Last active
August 30, 2019 08:25
-
-
Save immrsv/62601f18fbbb1c6adc3af5e841e973d8 to your computer and use it in GitHub Desktop.
Unity Animator as a scene controller
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.Events; | |
using Sirenix.OdinInspector; | |
// Add this to the object that holds the Animator | |
public class StateMachineEventReceiver : MonoBehaviour | |
{ | |
[System.Serializable] | |
public class MapItem { | |
public string StateName; | |
[FoldoutGroup("Events")] | |
public UnityEvent OnStateEnter; | |
[FoldoutGroup("Events")] | |
public UnityEvent OnStateUpdate; | |
[FoldoutGroup("Events")] | |
public UnityEvent OnStateExit; | |
} | |
public Animator Filter; | |
public List<MapItem> Map; | |
private void OnEnable() { | |
StateMachineEventSource.Enter += StateMachineEventSource_OnStateEnter; | |
StateMachineEventSource.Update += StateMachineEventSource_OnStateUpdate; | |
StateMachineEventSource.Exit += StateMachineEventSource_OnStateExit; | |
} | |
private void OnDisable() { | |
StateMachineEventSource.Enter -= StateMachineEventSource_OnStateEnter; | |
StateMachineEventSource.Update -= StateMachineEventSource_OnStateUpdate; | |
StateMachineEventSource.Exit -= StateMachineEventSource_OnStateExit; | |
} | |
private void StateMachineEventSource_OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { | |
if (Filter != null && animator != Filter) return; | |
foreach (var item in Map) { | |
if (stateInfo.IsName(item.StateName)) { | |
item.OnStateEnter.Invoke(); | |
break; | |
} | |
} | |
} | |
private void StateMachineEventSource_OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { | |
if (Filter != null && animator != Filter) return; | |
foreach (var item in Map) { | |
if (stateInfo.IsName(item.StateName)) { | |
item.OnStateUpdate.Invoke(); | |
break; | |
} | |
} | |
} | |
private void StateMachineEventSource_OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { | |
if (Filter != null && animator != Filter) return; | |
foreach (var item in Map) { | |
if (stateInfo.IsName(item.StateName)) { | |
item.OnStateExit.Invoke(); | |
break; | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
[System.Serializable] | |
public delegate void StateMachineStateEvent(Animator animator, AnimatorStateInfo stateInfo, int layerIndex); | |
// Add this to the 'root' of the Animator Controller (click on the empty space in the Animator window) | |
public class StateMachineEventSource : StateMachineBehaviour | |
{ | |
public static event StateMachineStateEvent Enter; | |
public static event StateMachineStateEvent Update; | |
public static event StateMachineStateEvent Exit; | |
// OnStateEnter is called when a transition starts and the state machine starts to evaluate this state | |
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { | |
Enter?.Invoke(animator, stateInfo, layerIndex); | |
} | |
// OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks | |
override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { | |
Update?.Invoke(animator, stateInfo, layerIndex); | |
} | |
// OnStateExit is called when a transition ends and the state machine finishes evaluating this state | |
override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { | |
Exit?.Invoke(animator, stateInfo, layerIndex); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Odin is only used to display the list of events for Receiver in the Inspector nicely, it's not required.