using JetBrains.Annotations; using UnityEditor; using UnityEngine; using UnityEngine.Events; namespace ABI.CCK.Components { public class StateMachineCallbackSender : StateMachineBehaviour { #region UnityEvents [PublicAPI] public static readonly UnityEvent OnInitialized = new(); [PublicAPI] public static readonly UnityEvent OnExecuteEnterTask = new(); [PublicAPI] public static readonly UnityEvent OnExecuteExitTask = new(); #endregion public bool localOnly = true; private bool _initialized; #region Unity Events public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { if (!_initialized) Initialize(animator); OnExecuteEnterTask.Invoke(animator, this); } public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { if (!_initialized) Initialize(animator); OnExecuteExitTask.Invoke(animator, this); } #endregion Unity Events #region Private Methods private void Initialize(Animator animator) { _initialized = true; OnInitialized.Invoke(animator, this); } #endregion Private Methods #if UNITY_EDITOR [CustomEditor(typeof(StateMachineCallbackSender))] public class StateMachineCallbackSenderEditor : Editor { private StateMachineCallbackSender _sender; private bool _showLocalOnlyHelp; private SerializedProperty _localOnly; private void OnEnable() { _sender = (StateMachineCallbackSender)target; if (_sender == null) return; _localOnly = serializedObject.FindProperty("localOnly"); } public override void OnInspectorGUI() { if (_sender == null) return; serializedObject.Update(); using (new EditorGUILayout.VerticalScope(new GUIStyle() { padding = new RectOffset(10, 10, 10, 10) })) { DrawLocalOnlyToggle(); EditorGUILayout.HelpBox( "This behaviour will send the following state machine callbacks to any listening receviers: OnStateMachineEnter, OnStateMachineExit", MessageType.Info); } serializedObject.ApplyModifiedProperties(); } private void DrawLocalOnlyToggle() { using (new EditorGUILayout.HorizontalScope()) { EditorGUILayout.PropertyField(_localOnly); if (GUILayout.Button("?", GUILayout.Width(25))) _showLocalOnlyHelp = !_showLocalOnlyHelp; GUILayout.Space(5); } if (_showLocalOnlyHelp) { EditorGUILayout.HelpBox("When 'Local Only' is enabled, the animator driver is executed locally and not for remote users.", MessageType.Info); EditorGUILayout.Space(5); EditorGUILayout.HelpBox("Avatars: Only the wearer.\nSpawnables: Only the prop's owner.\nWorlds: This option is ignored.", MessageType.Info); } EditorGUILayout.Space(); } } #endif } }