///
/// 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