Seven is the number.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

138 lines
3.4 KiB

using System;
using UnityEngine;
using UnityEngine.EventSystems;
public class AnimatedBiStateButton : MonoBehaviour,
IPointerDownHandler, IPointerUpHandler,
IPointerEnterHandler, IPointerExitHandler
{
public enum State
{
Up,
AnimateDown,
Down,
AnimateUp,
}
public float animationDuration = .1f;
public AnimationCurve animationCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);
public bool useEnterExitEvents = true;
public event Action willPress;
public event Action willRelease;
protected State state = State.Up;
/// <summary>
/// 0 = fully up
/// 1 = fully down
/// </summary>
protected float pressAmount = 0;
protected bool IsAnimating => state == State.AnimateDown || state == State.AnimateUp;
void Update()
{
PollPointerUp();
DoAnimation();
}
void DoAnimation()
{
if (!IsAnimating) return;
if (state == State.AnimateDown)
{
pressAmount += Time.deltaTime / animationDuration;
}
else if (state == State.AnimateUp)
{
pressAmount -= Time.deltaTime / animationDuration;
}
pressAmount = Mathf.Clamp01(pressAmount);
var animationProgress = pressAmount;
if (state == State.AnimateUp) animationProgress = 1 - animationProgress;
animationProgress = animationCurve.Evaluate(animationProgress);
if (state == State.AnimateUp) animationProgress = 1 - animationProgress;
Animate(animationProgress);
if (state == State.AnimateDown && pressAmount == 1)
{
state = State.Down;
}
if (state == State.AnimateUp && pressAmount == 0)
{
state = State.Up;
}
}
protected void Press()
{
if (state != State.Down && state != State.AnimateDown)
{
OnWillPress();
state = State.AnimateDown;
}
}
protected void Release()
{
if (state != State.Up && state != State.AnimateUp)
{
OnWillRelease();
state = State.AnimateUp;
}
}
/// <summary>
/// Pointer Up event does not fire on an object if it was not the one receive the Pointer Down event.
/// </summary>
void PollPointerUp()
{
if (useEnterExitEvents
&& (state == State.Down || state == State.AnimateDown)
&& !Input.GetMouseButton(0))
{
Release();
}
}
/// <summary>
/// NOP if not overrided
/// </summary>
/// <param name="visualPressAmount"><see cref="pressAmount"/> conformed to <see cref="animationCurve"/></param>
protected virtual void Animate(float visualPressAmount) { }
public void OnPointerDown(PointerEventData eventData)
{
Press();
}
public void OnPointerUp(PointerEventData eventData)
{
Release();
}
public void OnPointerEnter(PointerEventData eventData)
{
if (useEnterExitEvents && Input.GetMouseButton(0)) Press();
}
public void OnPointerExit(PointerEventData eventData)
{
if (useEnterExitEvents) Release();
}
protected virtual void OnWillPress()
{
willPress?.Invoke();
}
protected virtual void OnWillRelease()
{
willRelease?.Invoke();
}
}