Skip to content

Instantly share code, notes, and snippets.

@drZool
Last active May 6, 2019 11:54
Show Gist options
  • Select an option

  • Save drZool/64370d1cbac03c178edf610879603ad0 to your computer and use it in GitHub Desktop.

Select an option

Save drZool/64370d1cbac03c178edf610879603ad0 to your computer and use it in GitHub Desktop.
Simple transition system. Depends on LerpHelper https://gist.github.com/drZool/2938bc198ebccee0931d98798bd86cfa and uses Profiler but that can be removed
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(View))]
public class AnimatorViewTrigger : MonoBehaviour
{
public AnimationEvent[] events;
View view;
public bool debug;
public bool OneActiveTriggerOnly;
void Awake()
{
view = GetComponent<View>();
view.OnShow += OnShow;
view.OnHide += OnHide;
view.OnBeginHide += OnBeginHide;
}
string currentTrigger;
void OnEnable()
{
foreach (var e in events)
{
if (e.on == On.Enable)
{
if (debug) Debug.Log("Trigger view." + e.on + " > " + e.to + " " + e.animator, e.animator.gameObject);
if (OneActiveTriggerOnly)
{
if (!string.IsNullOrEmpty(currentTrigger))
e.animator.ResetTrigger(currentTrigger);
currentTrigger = e.to;
}
e.Trigger();
}
}
}
void OnShow()
{
foreach (var e in events)
{
if (e.on == On.Show)
{
if (debug) Debug.Log("Trigger view." + e.on + " > " + e.to + " " + e.animator, e.animator.gameObject);
if (OneActiveTriggerOnly)
{
if (!string.IsNullOrEmpty(currentTrigger))
e.animator.ResetTrigger(currentTrigger);
currentTrigger = e.to;
}
e.Trigger();
}
}
}
void OnHide()
{
foreach (var e in events)
{
if (e.on == On.Hide)
{
if (debug) Debug.Log("Trigger view." + e.on + " > " + e.to + " " + e.animator, e.animator.gameObject);
if (OneActiveTriggerOnly)
{
if (!string.IsNullOrEmpty(currentTrigger))
e.animator.ResetTrigger(currentTrigger);
currentTrigger = e.to;
}
e.Trigger();
}
}
}
void OnBeginHide()
{
foreach (var e in events)
{
if (e.on == On.BeginHide)
{
if (debug) Debug.Log("Trigger view." + e.on + " > " + e.to + " " + e.animator, e.animator.gameObject);
if (OneActiveTriggerOnly)
{
if (!string.IsNullOrEmpty(currentTrigger))
e.animator.ResetTrigger(currentTrigger);
currentTrigger = e.to;
}
e.Trigger();
}
}
}
}
[System.Serializable]
public class AnimationEvent
{
public Animator animator;
public On on;
[Header("SetTrigger")]
public string to;
public void Trigger()
{
animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
if (animator.gameObject.activeInHierarchy)
{
animator.SetTrigger(to);
animator.Update(0); //HACK(hello) force animator to update
}
}
}
using UnityEngine;
[System.Serializable]
public class PositionAndScale
{
public string Name = "Name";
public Vector3 Position = Vector3.zero;
public float Scale = 1;
public float Delay = 0;
public float Duration = 0;
public Vector3 Scale3 {
get {
return Vector3.one * Scale;
}
}
[Range (0, 1)]
public float Alpha = 1;
public bool Save;
public bool Load;
public PositionAndScale ()
{
}
public PositionAndScale (Transform transform)
{
if (transform is RectTransform) {
Position = (transform as RectTransform).anchoredPosition;
} else {
Position = transform.localPosition;
}
Scale = transform.localScale.x;
var group = transform.GetComponent<CanvasGroup> ();
if (group != null) {
Alpha = group.alpha;
} else {
Alpha = 1;
}
}
public static PositionAndScale Lerp (PositionAndScale a, PositionAndScale b, float t)
{
var p = new PositionAndScale ();
if (a == null || b == null) {
return p;
}
p.Position = Vector3.Lerp (a.Position, b.Position, t);
p.Scale = Mathf.Lerp (a.Scale, b.Scale, t);
p.Alpha = Mathf.Lerp (a.Alpha, b.Alpha, t);
return p;
}
public static PositionAndScale QuadInOutLerp (PositionAndScale a, PositionAndScale b, float t)
{
return Lerp (a, b, QuadraticEaseInOut (t));
}
static public float QuadraticEaseInOut (float p)
{
if (p < 0.5f) {
return 2 * p * p;
} else {
return (-2 * p * p) + (4 * p) - 1;
}
}
}
using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;
[ExecuteInEditMode]
public class Transition : MonoBehaviour
{
public enum State
{
Enter,
Show,
Leave,
None,
}
public enum Easing
{
Linear,
InOutQuad
}
public event Action OnTransitionDone;
public Easing easing = Easing.Linear;
public List<PositionAndScale> states;
public bool UseAlpha = false;
public bool blocksViewChange = true;
public bool debug;
LerpHelper <PositionAndScale> lerp;
public bool isLerping{ get; private set; }
Action OnDoneCustomCallback;
CanvasGroup _canvasGroup;
CanvasGroup canvasGroup {
get {
if (_canvasGroup == null) {
_canvasGroup = GetComponent<CanvasGroup> ();
if (_canvasGroup == null) {
_canvasGroup = gameObject.AddComponent<CanvasGroup> ();
}
_canvasGroup.blocksRaycasts = true;
_canvasGroup.interactable = true;
}
return _canvasGroup;
}
}
public void TransitionToState (string stateName, float duration, Action OnDone = null)
{
gameObject.SetActive (true);
//this.stringOfStates = stringOfStates;
var state = GetState (stateName);
if (state == null) {
Debug.LogWarning ("Can't find statename " + stateName);
return;
}
if (debug)
Debug.Log (name + " TranstitionToState " + stateName + " x " + state.Position.x + " is " + GetPosition ().x);
TransitionToState (state, duration, OnDone);
}
public PositionAndScale GetState (string stateName)
{
foreach (var state in states) {
if (state.Name == stateName) {
return state;
}
}
return null;
}
public void TransitionToState (PositionAndScale state, float duration, Action OnDone = null)
{
gameObject.SetActive (true);
if (state.Duration > 0)
duration = state.Duration;
lerp = new LerpHelper<PositionAndScale> (new PositionAndScale (transform), state, duration, time + state.Delay);
if (debug)
Debug.Log (name + " TransitionToState " + state.Name + " time " + time + " norm: " + lerp.GetNormalizedTime (time), gameObject);
isLerping = true;
if (OnDone != null)
OnDoneCustomCallback = OnDone;
Profiler.AsyncBegin (this.name, state.Name, GetInstanceID ());
}
static float time {
get {
#if UNITY_EDITOR
if (!Application.isPlaying) {
return (float)UnityEditor.EditorApplication.timeSinceStartup;
}
#endif
return Time.time;
}
}
public void LateUpdate ()
{
if (isLerping) {
PositionAndScale value;
switch (easing) {
case Easing.InOutQuad:
value = lerp.GetValue (PositionAndScale.QuadInOutLerp, time);
break;
default:
value = lerp.GetValue (PositionAndScale.Lerp, time);
break;
}
if (!float.IsNaN (value.Scale3.x))
transform.localScale = value.Scale3;
if (!float.IsNaN (value.Position.x))
SetPosition (value.Position);
if (UseAlpha) {
if (float.IsNaN (value.Alpha)) {
canvasGroup.alpha = lerp.from.Alpha; //Set to value
if (debug)
Debug.Log ("NAN alpha. Using to: " + lerp.to.Alpha + " " + name, gameObject);
} else {
canvasGroup.alpha = value.Alpha;
}
if (debug)
Debug.Log ("New alpha " + canvasGroup.alpha + " " + name, gameObject);
}
isLerping = !lerp.IsComplete (time);
if (!isLerping) {
if (OnTransitionDone != null)
OnTransitionDone.Invoke ();
if (OnDoneCustomCallback != null) {
OnDoneCustomCallback.Invoke ();
OnDoneCustomCallback = null;
}
}
}
#if UNITY_EDITOR
if (!Application.isPlaying && states != null && !isLerping) {
foreach (var state in states) {
if (state.Save) {
UnityEditor.Undo.RecordObject (gameObject, "Save transition state");
state.Save = false;
state.Scale = transform.localScale.x;
state.Position = GetPosition ();
if (UseAlpha)
state.Alpha = canvasGroup.alpha;
}
if (state.Load) {
state.Load = false;
UnityEditor.Undo.RecordObject (gameObject, "Load transition state");
transform.localScale = Vector3.one * state.Scale;
SetPosition (state.Position);
if (UseAlpha)
canvasGroup.alpha = state.Alpha;
}
}
}
#endif
}
void SetPosition (Vector3 position)
{
if (transform is RectTransform) {
(transform as RectTransform).anchoredPosition = (Vector2)position;
} else {
transform.localPosition = position;
}
}
Vector3 GetPosition ()
{
if (transform is RectTransform) {
return (Vector3)(transform as RectTransform).anchoredPosition;
} else {
return transform.localPosition;
}
}
public void TransitionFromTo (Transition.State from, Transition.State to, float duration)
{
var fromState = GetState (from.ToString ());
if (fromState != null) {
if (debug) {
if (UseAlpha) {
Debug.Log (name + " TransitionFromTo " + from + " -> " + to + " x " + fromState.Position.x + " is " + GetPosition ().x + " alpha is " + canvasGroup.alpha, gameObject);
} else {
Debug.Log (name + " TransitionFromTo " + from + " -> " + to + " x " + fromState.Position.x + " is " + GetPosition ().x, gameObject);
}
}
transform.localScale = fromState.Scale3;
SetPosition (fromState.Position);
if (UseAlpha)
canvasGroup.alpha = fromState.Alpha;
} else {
Debug.LogWarning ("Could not find state " + from, gameObject);
}
TransitionToState (to.ToString (), duration);
}
public void TransitionInstant (Transition.State toState)
{
TransitionInstant (toState.ToString ());
}
public void TransitionInstant (string toState)
{
isLerping = false;
var state = GetState (toState);
if (debug) {
if (UseAlpha) {
Debug.Log (name + " TransitionInstant " + toState + " x " + state.Position.x + " is " + GetPosition ().x + " alpha " + state.Alpha + " is " + canvasGroup.alpha, gameObject);
} else {
Debug.Log (name + " TransitionInstant " + toState + " x " + state.Position.x + " is " + GetPosition ().x, gameObject);
}
}
if (state != null) {
transform.localScale = Vector3.one * state.Scale;
SetPosition (state.Position);
if (UseAlpha) {
canvasGroup.alpha = state.Alpha;
if (debug)
Debug.Log ("Instance alpha " + canvasGroup.alpha + " " + name, gameObject);
}
} else {
Debug.LogWarning ("Could not find state " + state, this);
}
if (debug) {
if (UseAlpha) {
Debug.Log (name + " After TransitionInstant " + toState + " x " + state.Position.x + " is " + GetPosition ().x + " alpha " + state.Alpha + " is " + canvasGroup.alpha, gameObject);
} else {
Debug.Log (name + " After TransitionInstant " + toState + " x " + state.Position.x + " is " + GetPosition ().x, gameObject);
}
}
}
}
using UnityEngine;
using System.Collections;
[RequireComponent (typeof(View))]
public class TransitionViewTrigger : MonoBehaviour
{
public TransitionEvent[] events;
View view;
void Awake ()
{
view = GetComponent<View> ();
view.OnShow += OnShow;
view.OnHide += OnHide;
view.OnBeginHide += OnBeginHide;
}
void OnEnable ()
{
foreach (var e in events) {
if (e.on == On.Enable) {
//Debug.Log ("Trigger " + e.on + " " + e.to + " " + e.IsInstant);
e.Trigger ();
}
}
}
void OnShow ()
{
foreach (var e in events) {
if (e.on == On.Show) {
//Debug.Log ("Trigger " + e.on + " " + e.to + " " + e.IsInstant);
e.Trigger ();
}
}
}
void OnHide ()
{
foreach (var e in events) {
if (e.on == On.Hide) {
//Debug.Log ("Trigger " + e.on + " " + e.to + " " + e.IsInstant);
e.Trigger ();
}
}
}
void OnBeginHide ()
{
foreach (var e in events) {
if (e.on == On.BeginHide) {
//Debug.Log ("Trigger " + e.on + " " + e.to + " " + e.IsInstant);
e.Trigger ();
}
}
}
}
[System.Serializable]
public class TransitionEvent
{
public On on;
public Transition.State to;
public bool IsInstant;
public Transition transition;
public float duration = 1;
[Header ("Optional")]
public Transition.State from;
public void Trigger ()
{
if (IsInstant) {
transition.TransitionInstant (to);
} else {
if (from != Transition.State.None) {
transition.TransitionFromTo (from, to, duration);
} else {
transition.TransitionToState (to.ToString (), duration);
}
}
}
}
[System.Serializable]
public enum On
{
Enable,
Show,
Hide,
BeginHide
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment