/// <summary> /// Adds convenience methods to determine the current Animator state as boolean methods to the class code /// element (e.g. IsIdle ()). NOTE that this method relies on classes from namespace UnityEditorInternal /// which can be subject to changes in future releases. /// </summary> public static void ProcessAllAnimatorStates (Animator animator, ProcessAnimatorState callback) { AnimatorController controller = GetInternalAnimatorController (animator); int layerCount = controller.layerCount; for (int layer = 0; layer < layerCount; layer++) { string layerName = controller.GetLayer (layer).name; UnityEditorInternal.StateMachine sm = controller.GetLayer (layer).stateMachine; for (int i = 0; i < sm.stateCount; i++) { UnityEditorInternal.State state = sm.GetState (i); Motion motion = state.GetMotion (); float duration = (motion != null ? motion.averageDuration : 0f); string motionName = (motion != null ? motion.name : ""); StateInfo info = new StateInfo (state.uniqueNameHash, layer, layerName, state.uniqueName, state.tag, state.speed, state.iKOnFeet, state.mirror, motionName, duration); callback (info); } } }
public override void Perform(LayerStatus [] statuses, Dictionary <int, StateInfo> stateInfos) { LayerStatus status = statuses [layer]; if (status.State.Current == stateId) { // seems awkward but null check first costs almost no performance, but a dictionary lookup does if (OnActive != null || OnEnter != null || OnStay != null) { StateInfo currentInfo = GetStateInfo(status.State.Current, stateInfos); if (currentInfo != null) { if (status.State.HasChanged) { if (OnEnter != null) { // fire once after a state change OnEnter(currentInfo, status); } } else if (OnStay != null) { // OnStay starts firing the 2nd time we are in this state OnStay(currentInfo, status); } if (OnActive != null) { // fire always OnActive(currentInfo, status); } } } } else if (status.State.Previous == stateId && status.State.HasChanged) { StateInfo previousInfo = GetStateInfo(status.State.Previous, stateInfos); if (OnExit != null) { OnExit(previousInfo, status); } } }
public SpecificStateHandler State(int nameHash) { if (StateInfos.ContainsKey(nameHash)) { StateInfo info = StateInfos [nameHash]; // reuse handler if possible to maximise performance in FixedUdpate; // drawback: we have to create a handler first to get the hash ID SpecificStateHandler handler = new SpecificStateHandler(info.Layer, nameHash); int id = handler.GetHashCode(); if (!StateHandlers.ContainsKey(id)) { StateHandlers [id] = handler; } else { } return((SpecificStateHandler)StateHandlers [id]); } else { Debug.LogWarning("There seem to be no animator state with nameHash [" + nameHash + "]. Maybe you need to update the corresonding AnimatorAccess component."); } return(null); }
/// <summary> /// Callback from InternalAPIAccess to process a single Animator state. /// </summary> /// <param name="layer">Layer index.</param> /// <param name="layerName">Layer name.</param> /// <param name="item">State name.</param> public void ProcessAnimatorState (StateInfo info) { string layerPrefix = (info.Layer > 0 || config.ForceLayerPrefix ? null : info.LayerName); string name = CodeGenerationUtils.GenerateStateName (config.AnimatorStatePrefix, info.Name, layerPrefix); name = name.FirstCharToUpper (); string fieldName = CodeGenerationUtils.GenerateStateName (config.AnimatorStateHashPrefix, info.Name, layerPrefix); fieldName = fieldName.FirstCharToLower (); // field declaration GenericFieldCodeElement field = new GenericFieldCodeElement (typeof(int), fieldName, "" + info.Id); field.ReadOnly = true; field.Summary.Add ("Hash of Animator state " + info.Name); classCodeElement.Fields.Add (field); string methodName = "Is" + name; // IsXXX method () MethodCodeElement<bool> method = new MethodCodeElement<bool> (methodName); method.Origin = "state " + info.Name; method.Code.Add ("return " + fieldName + " == animator.GetCurrentAnimatorStateInfo (" + info.Layer + ").nameHash" + ";"); method.Summary.Add ("true if the current Animator state of layer " + info.Layer + " is \"" + info.Name + "\"."); classCodeElement.Methods.Add (method); // overloaded IsXXX (int nameHash) MethodCodeElement<bool> methodWithLayerParameter = new MethodCodeElement<bool> (methodName); methodWithLayerParameter.Origin = "state " + info.Name; methodWithLayerParameter.AddParameter (typeof(int), "nameHash"); methodWithLayerParameter.Code.Add ("return nameHash == " + fieldName + ";"); methodWithLayerParameter.Summary.Add ("true if the given (state) nameHash equals Animator.StringToHash (\"" + info.Name + "\")."); classCodeElement.Methods.Add (methodWithLayerParameter); // state dictionary is filled in overriden method InitialiseEventManager object [] parameters = new object[] {info.Id, info.Layer, info.LayerName, info.Name, info.Tag, info.Speed, info.FootIK, info.Mirror, info.Motion.Name, info.Motion.Duration }; string parameterList = CodeElementUtils.GetCallParameterString (parameters); EventManagerInitialiser.Code.Add (StateInfoDict + ".Add (" + info.Id + ", new StateInfo (" + parameterList + "));"); }