/// /// SURGE FRAMEWORK /// Author: Bob Berkebile /// Email: bobb@pixelplacement.com /// /// Simple system for turning anything into a button. /// /// using UnityEngine; using UnityEngine.UI; using UnityEngine.Events; using UnityEngine.EventSystems; using System; using Pixelplacement.TweenSystem; #if UNITY_2017_2_OR_NEWER using UnityEngine.XR; #else using UnityEngine.VR; #endif namespace Pixelplacement { [RequireComponent(typeof(Collider))] [RequireComponent(typeof(Rigidbody))] [ExecuteInEditMode] public sealed class ColliderButton : MonoBehaviour { //Public Events: public ColliderButtonEvent OnSelected; public ColliderButtonEvent OnDeselected; public ColliderButtonEvent OnClick; public ColliderButtonEvent OnPressed; public ColliderButtonEvent OnReleased; public static event Action OnSelectedGlobal; public static event Action OnDeselectedGlobal; public static event Action OnClickGlobal; public static event Action OnPressedGlobal; public static event Action OnReleasedGlobal; //Public Enums: public enum EaseType { EaseOut, EaseOutBack }; //Public Properties: public bool IsSelected { get; private set; } //Public Variables: public KeyCode[] keyInput; public bool _unityEventsFolded; public bool _scaleResponseFolded; public bool _colorResponseFolded; public bool applyColor; public bool applyScale; public LayerMask collisionLayerMask = -1; public Renderer colorRendererTarget; public Image colorImageTarget; public Color selectedColor = Color.gray; public Color pressedColor = Color.green; public Color disabledColor = new Color(.5f, .5f, .5f, .5f); public float colorDuration = .1f; public Transform scaleTarget; public Vector3 normalScale; public Vector3 selectedScale; public Vector3 pressedScale; public float scaleDuration = .1f; public EaseType scaleEaseType; public bool resizeGUIBoxCollider = true; public bool centerGUIBoxCollider = true; public Vector2 guiBoxColliderPadding; public bool interactable = true; //Private Variables: bool _clicking; int _selectedCount; bool _colliderSelected; bool _pressed; bool _released; bool _vrRunning; RectTransform _rectTransform; EventTrigger _eventTrigger; EventTrigger.Entry _pressedEventTrigger; EventTrigger.Entry _releasedEventTrigger; EventTrigger.Entry _enterEventTrigger; EventTrigger.Entry _exitEventTrigger; int _colliderCount; BoxCollider _boxCollider; TweenBase _colorTweenImage = null; TweenBase _colorTweenMaterial; TweenBase _scaleTween; Color _normalColorRenderer; Color _normalColorImage; bool _interactableStatus = true; //Init: private void Reset() { //var sets: applyColor = true; keyInput = new KeyCode[] { KeyCode.Mouse0 }; //hook up image to help users: Image image = GetComponent(); if (image != null) { colorImageTarget = image; } //hook up renderer to help users: Renderer renderer = GetComponent(); if (renderer != null && renderer.sharedMaterial.HasProperty("_Color")) { colorRendererTarget = renderer; } } private void Awake() { if (Application.isPlaying) { //color setups: if (colorRendererTarget != null) { if (colorRendererTarget.material.HasProperty("_Color")) { _normalColorRenderer = colorRendererTarget.material.color; } } if (colorImageTarget != null) { _normalColorImage = colorImageTarget.color; } } //scale setup: scaleTarget = transform; normalScale = transform.localScale; //set initial size on gui collider: _rectTransform = GetComponent(); _boxCollider = GetComponent(); if (_rectTransform != null && _boxCollider != null) ResizeGUIBoxCollider(_boxCollider); //set up rigidbody: GetComponent().isKinematic = true; //refs: _rectTransform = GetComponent(); _boxCollider = GetComponent(); if (!Application.isPlaying) return; //rect and event triggers: _rectTransform = GetComponent(); if (_rectTransform != null) { _eventTrigger = gameObject.AddComponent(); _pressedEventTrigger = new EventTrigger.Entry(); _pressedEventTrigger.eventID = EventTriggerType.PointerDown; _releasedEventTrigger = new EventTrigger.Entry(); _releasedEventTrigger.eventID = EventTriggerType.PointerUp; _enterEventTrigger = new EventTrigger.Entry(); _enterEventTrigger.eventID = EventTriggerType.PointerEnter; _exitEventTrigger = new EventTrigger.Entry(); _exitEventTrigger.eventID = EventTriggerType.PointerExit; } //events: if (_rectTransform != null) { //event registrations: _pressedEventTrigger.callback.AddListener((data) => { OnPointerDownDelegate((PointerEventData)data); }); _eventTrigger.triggers.Add(_pressedEventTrigger); _releasedEventTrigger.callback.AddListener((data) => { OnPointerUpDelegate((PointerEventData)data); }); _eventTrigger.triggers.Add(_releasedEventTrigger); _enterEventTrigger.callback.AddListener((data) => { OnPointerEnterDelegate((PointerEventData)data); }); _eventTrigger.triggers.Add(_enterEventTrigger); _exitEventTrigger.callback.AddListener((data) => { OnPointerExitDelegate((PointerEventData)data); }); _eventTrigger.triggers.Add(_exitEventTrigger); } } //Flow: private void OnEnable() { if (!Application.isPlaying) return; ColorReset(); } private void OnDisable() { if (!Application.isPlaying) return; //resets: _pressed = false; _released = false; _clicking = false; _colliderSelected = false; _selectedCount = 0; _colliderCount = 0; ColorReset(); ScaleReset(); } //Loops: private void Update() { //disabled? if (_interactableStatus != interactable) { if (interactable) { ColorNormal(); } else { ColorDisabled(); } //handle a Unity GUI button in case it is also attached: Button button = GetComponent