private AnimatorStateMachine GetOrCreateStateMachine(AnimatorStateMachine stateMachine, string stateMachineName, int angle) { AnimatorStateMachine subStateMachine = FindStateMachine(stateMachine, stateMachineName); if (subStateMachine == null) { subStateMachine = stateMachine.AddStateMachine(stateMachineName, new Vector3(450 + Mathf.Cos(angle * Mathf.Deg2Rad) * 200, Mathf.Sin(angle * Mathf.Deg2Rad) * 150)); } return(subStateMachine); }
static void AddSuMechie(AnimatorStateMachine machine, int index1, string path, AnimatorControllerLayer layer, string sunStateMachine) { ////创建子状态机 //for (int k = 1; k < index1; k++) //{ // AnimatorStateMachine sub2Machine = machine.AddStateMachine("sub2Machine", new Vector3(100, 300, 0)); //} AnimatorStateMachine sub2Machine = machine.AddStateMachine(sunStateMachine, new Vector3(100, 300, 0)); // 根据动画文件读取它的AnimationClip对象 var datas = AssetDatabase.LoadAllAssetsAtPath(path); if (datas.Length == 0) { Debug.Log(string.Format("Can't find clip in {0}", path)); return; } foreach (var data in datas) { int index = 0; if (!(data is AnimationClip)) { continue; } var newClip = data as AnimationClip; if (newClip.name.StartsWith("__")) { continue; } // 取出动画名字,添加到state里面 AnimatorState state = sub2Machine.AddState(newClip.name, new Vector3(500, sub2Machine.states.Length * 60, 0)); stateList.Add(state); if (state.name == "walk") { sub2Machine.defaultState = state; } Debug.Log(string.Format("<color=red>{0}</color>", state)); index++; state.motion = newClip; // 把State添加在Layer里面 sub2Machine.AddAnyStateTransition(state); } }
private void UpdateAnimatorController() { // The new controller that will be created based on Manager animations AnimatorController newController = new AnimatorController(); newController.AddLayer("DefaultLayer"); // Add a parameter that will determine the animation states AnimatorControllerParameter animatorParameter = new AnimatorControllerParameter(); animatorParameter.type = AnimatorControllerParameterType.Int; animatorParameter.name = "TextAnimation"; animatorParameter.defaultInt = 999; newController.AddParameter(animatorParameter); // Add state machine AnimatorStateMachine rootStateMachine = newController.layers[0].stateMachine; AnimatorStateMachine stateMachine = rootStateMachine.AddStateMachine("TextAnimationStateMachine"); // Create a default state to prevent animation auto playing index 0 AnimatorState waitingState = stateMachine.AddState("Waiting"); //foreach (AnimationClip clip in DamageNumberManager.instance.animations) for (int i = 0; i < DamageNumberManager.instance.animations.Length; i++) { AnimationClip clip = DamageNumberManager.instance.animations[i]; // Add new state based on the AnimationClip AnimatorState state = stateMachine.AddState(clip.name); state.motion = clip; // Create transition from "Waiting" to the new state AnimatorStateTransition transition = waitingState.AddTransition(state, false); transition.AddCondition(AnimatorConditionMode.Equals, i, "TextAnimation"); } // Override the existing Animator Controller AnimatorOverrideController overrideController = new AnimatorOverrideController(); overrideController.runtimeAnimatorController = newController; GetComponent <Animator>().runtimeAnimatorController = overrideController; }
/// <summary> /// Show how to add a child machine /// </summary> /// <param name="fbxPath"></param> private void CreateCrouchWalk(string fbxPath) { AnimatorStateMachine walkMachine = crouchLayerMachine.AddStateMachine("Walk", new Vector3(0f, 100f)); walkMachine.entryPosition = Vector3.zero; walkMachine.anyStatePosition = new Vector3(0f, -200f); walkMachine.exitPosition = new Vector3(0f, -400f); AnimationClip walkClip = AnimatorFactoryUtil.LoadAnimClip(fbxPath, "HumanoidCrouchWalk"); AnimationClip walkLeftClip = AnimatorFactoryUtil.LoadAnimClip(fbxPath, "HumanoidCrouchWalkLeft"); AnimationClip walkRightClip = AnimatorFactoryUtil.LoadAnimClip(fbxPath, "HumanoidCrouchWalkRight"); stateWalk = walkMachine.AddState("Walk", new Vector3(200f, 0f)); stateWalk.motion = walkClip; stateWalkLeft = walkMachine.AddState("WalkLeft", new Vector3(200f, -200f)); stateWalkLeft.motion = walkLeftClip; stateWalkRight = walkMachine.AddState("WalkRight", new Vector3(200f, -400f)); stateWalkRight.motion = walkRightClip; }
public static AnimatorStateMachine AddStateMachineToStateMachine(AnimatorStateMachine parent, string name) { bool exists = false; AnimatorStateMachine createdMachine = null; foreach (ChildAnimatorStateMachine stateMachine in parent.stateMachines) { if (stateMachine.stateMachine.name == name) { exists = true; createdMachine = stateMachine.stateMachine; break; } } if (!exists) { createdMachine = parent.AddStateMachine( name, FindNextPosition(parent.stateMachines)); } return(createdMachine); }
/// <summary> /// Sets all fields and properties that have been deserialized. /// </summary> /// <param name="obj">The GameObject that will be used to initialize this component.</param> /// <param name="info">The fields that were deserialized already.</param> /// <param name="context">A context container that stores a <see cref="XmlDeserializer.DeserializeContext"/> object within.</param> /// <param name="selector">Always null.</param> /// <returns>The component that was deserialized.</returns> public override object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) { //just deserialize as normal in-place object ReplaceState(obj, info, "stateMachines", "states"); AnimatorStateMachine fsm = obj as AnimatorStateMachine; var subFsms = info.GetValue("stateMachines", typeof(ChildAnimatorStateMachine[])) as ChildAnimatorStateMachine[]; var subStates = info.GetValue("states", typeof(ChildAnimatorState[])) as ChildAnimatorState[]; //NOTE: this will no handle nested states properly! foreach (var subFsm in subFsms) { //Debug.Log("Adding sub FSM " + subFsm.stateMachine.name); fsm.AddStateMachine(subFsm.stateMachine, subFsm.position); } foreach (var state in subStates) { //Debug.Log("Adding State " + state.state); fsm.AddState(state.state, state.position); } return(obj); }
private AnimatorStateMachine AddSubMachine(AnimatorStateMachine machine, SubAnimatorMachineItem subMachineItems, int times) { return(machine.AddStateMachine(subMachineItems.SubMachineName, new Vector3(300 * (times / 5), -(100 * (times % 5) + 100), 0))); }
private void Export() { List <AnimationClip> clips = new List <AnimationClip>(); foreach (Direction direction in billboard.directions) { AnimationClip clip = new AnimationClip(); clip.name = billboard.name + "_" + direction.angleStart + "_" + direction.angleEnd; clip.wrapMode = billboard.loop ? WrapMode.Loop : WrapMode.Default; AnimationClipSettings settings = new AnimationClipSettings(); settings.loopTime = billboard.loop; AnimationUtility.SetAnimationClipSettings(clip, settings); clip.ClearCurves(); if (direction.sprites.Count != 0) { //Set Keyframes EditorCurveBinding curveBinding = new EditorCurveBinding(); curveBinding.type = typeof(SpriteRenderer); curveBinding.path = ""; curveBinding.propertyName = "m_Sprite"; ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[direction.sprites.Count]; for (int i = 0; i < direction.sprites.Count; i++) { Sprite sprite = direction.sprites[i]; keyFrames[i] = new ObjectReferenceKeyframe(); keyFrames[i].time = i * billboard.waitTime; keyFrames[i].value = sprite; } AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames); //Set FlipX AnimationCurve curve = direction.invertSprites ? AnimationCurve.Constant(0, (direction.sprites.Count) * billboard.waitTime, 1) : AnimationCurve.Constant(0, direction.sprites.Count * billboard.waitTime, 0); clip.SetCurve("", typeof(SpriteRenderer), "m_FlipX", curve); } clips.Add(clip); } string path = EditorUtility.SaveFilePanelInProject("Export Animations", "animations", "", "Export Animations"); if (path == "") { return; } foreach (AnimationClip clip in clips) { string clipPath = path + clip.name + ".anim"; AssetDatabase.CreateAsset(clip, clipPath); } AssetDatabase.SaveAssets(); AnimatorController controller = null; AnimatorStateMachine rootStateMachine = null; switch (animator) { case null: controller = AnimatorController.CreateAnimatorControllerAtPath(path + ".controller"); controller.AddParameter("angle", AnimatorControllerParameterType.Float); break; default: controller = animator; break; } rootStateMachine = controller.layers[0].stateMachine; AnimatorStateMachine stateMachine = rootStateMachine.AddStateMachine(billboard.name, Vector3.zero); AnimatorState baseState = stateMachine.AddState("Base", new Vector3(0, 600)); for (int x = 0; x < billboard.directions.Count; x++) { Direction direction = billboard.directions[x]; string name = billboard.name + "_" + direction.angleStart + "_" + direction.angleEnd; AnimationClip clip = AssetDatabase.LoadAssetAtPath <AnimationClip>(path + name + ".anim"); float radians = (((float)x / (billboard.directions.Count)) * 360f) * Mathf.Deg2Rad; var cos = Mathf.Cos(radians); var sin = Mathf.Sin(radians); Vector3 pos = new Vector3(0, 600); pos += new Vector3(cos, sin) * 300; AnimatorState state = stateMachine.AddState(name, pos); state.motion = clip; var transition = AddTransition(state, baseState); transition.AddCondition(AnimatorConditionMode.Greater, direction.angleEnd, "angle"); transition = AddTransition(state, baseState); transition.AddCondition(AnimatorConditionMode.Less, direction.angleStart, "angle"); transition = AddTransition(baseState, state); transition.AddCondition(AnimatorConditionMode.Greater, direction.angleStart, "angle"); transition.AddCondition(AnimatorConditionMode.Less, direction.angleEnd, "angle"); } AssetDatabase.SaveAssets(); }
private void CreateMechAnimatorController() { AnimatorController animatorController = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath("Assets/AnimatorController.controller"); AnimatorControllerParameter groundedParameter = new AnimatorControllerParameter(); groundedParameter.name = "Grounded"; groundedParameter.type = AnimatorControllerParameterType.Bool; animatorController.AddParameter(groundedParameter); AnimatorControllerParameter forwardParameter = new AnimatorControllerParameter(); forwardParameter.name = "Forward"; forwardParameter.type = AnimatorControllerParameterType.Float; animatorController.AddParameter(forwardParameter); AnimatorControllerParameter turnParameter = new AnimatorControllerParameter(); turnParameter.name = "Turn"; turnParameter.type = AnimatorControllerParameterType.Float; animatorController.AddParameter(turnParameter); AnimatorControllerParameter jumpParameter = new AnimatorControllerParameter(); jumpParameter.name = "Jump"; jumpParameter.type = AnimatorControllerParameterType.Trigger; animatorController.AddParameter(jumpParameter); AnimatorControllerParameter landedParameter = new AnimatorControllerParameter(); landedParameter.name = "Landed"; landedParameter.type = AnimatorControllerParameterType.Trigger; animatorController.AddParameter(landedParameter); AnimatorControllerParameter landDamageAmountParameter = new AnimatorControllerParameter(); landDamageAmountParameter.name = "LandDamageAmount"; landDamageAmountParameter.type = AnimatorControllerParameterType.Float; animatorController.AddParameter(landDamageAmountParameter); AnimatorStateMachine stateMachine = animatorController.layers[0].stateMachine; AnimatorStateMachine locomotionStateMachine = stateMachine.AddStateMachine("Locomotion", new Vector3(350, 100, 0)); stateMachine.AddEntryTransition(locomotionStateMachine); // Grounded state - as it's first, it will have an entry transition by default AnimatorState groundedState = CreateGroundedState(animatorController, locomotionStateMachine); // Landing state AnimatorState landingState = CreateLandingState(animatorController, locomotionStateMachine); // Airborne state AnimatorState airborneState = CreateAirborneState(animatorController, locomotionStateMachine); // Transitions AnimatorStateTransition groundedToAirborneTransition = groundedState.AddTransition(airborneState); groundedToAirborneTransition.hasExitTime = false; groundedToAirborneTransition.hasFixedDuration = true; groundedToAirborneTransition.duration = 0.25f; groundedToAirborneTransition.AddCondition(AnimatorConditionMode.IfNot, 0, "Grounded"); AnimatorStateTransition airborneToLandingTransition = airborneState.AddTransition(landingState); airborneToLandingTransition.hasExitTime = false; airborneToLandingTransition.hasFixedDuration = true; airborneToLandingTransition.duration = 0.1f; airborneToLandingTransition.AddCondition(AnimatorConditionMode.If, 0, "Grounded"); AnimatorStateTransition landingToGroundedTransition = landingState.AddTransition(groundedState); landingToGroundedTransition.hasExitTime = true; landingToGroundedTransition.exitTime = 0.5f; landingToGroundedTransition.hasFixedDuration = true; landingToGroundedTransition.duration = 0.25f; AssetDatabase.SaveAssets(); }
protected bool UpdateStatemachine(BaseState state, AnimatorStateMachine parentState = null, int layerIndex = 0) { bool status = true; AnimatorStateMachine statemachine = null; ChildAnimatorStateMachine[] _animatorSubstates = animatorController.layers[layerIndex].stateMachine.stateMachines; // --- Update State --- if (parentState != null) { // -- Add States into Parent State -- if (!AnimatorstatemachineExists(state.Name, parentState.stateMachines, out statemachine)) { statemachine = parentState.AddStateMachine(state.Name); } } else { // -- Add States into Global State -- if (!AnimatorstatemachineExists(state.Name, _animatorSubstates, out statemachine)) { statemachine = this.animatorController.layers[layerIndex].stateMachine.AddStateMachine(state.Name); } } // --- Add State Parameter --- string stateParameterName = state.Name; AnimatorControllerParameter stateParameter = null; if (!ParameterExists(stateParameterName, this.animatorController.parameters, out stateParameter)) { this.animatorController.AddParameter(stateParameterName, AnimatorControllerParameterType.Bool); ParameterExists(stateParameterName, this.animatorController.parameters, out stateParameter); // Link Paramter to "stateParameter" ObjectReference } if (statemachine != null) { // --- Create BlendTree --- if (state.blendTree) { BaseState.BlendTree1DInfo blendTree1D = state.GetBlendTree(); string blendTreeName = string.Format("{0}_{1}_BlendTree", state.Name, blendTree1D.parameter); //// -- Update BlendTree Parameter -- string blendParameterName = blendTree1D.parameter; AnimatorControllerParameter blendParameter = null; if (!ParameterExists(blendParameterName, this.animatorController.parameters, out blendParameter)) { this.animatorController.AddParameter(blendParameterName, AnimatorControllerParameterType.Float); } // --- Add BlendTree --- AnimatorState blendTreeState; BlendTree blendTree = null; if (!AnimatorstateExists(blendTreeName, statemachine.states, out blendTreeState)) { Debug.Log("CreateBlendTreeInController"); //blendTreeState = this.animatorController.CreateBlendTreeInController(blendTreeName, out blendTree); blendTreeState = CreateBlendTreeInController(statemachine, blendTreeName, out blendTree); } else if (blendTreeState.motion == null) { Debug.Log("RecreateBlendTreeInController"); blendTreeState = RecreateBlendTreeInController(statemachine, blendTreeState, blendTreeName, out blendTree, 0); } if (blendTreeState.motion is BlendTree) { blendTree = blendTreeState.motion as BlendTree; } if (blendTree != null && blendTree1D.blocks != null) { blendTree.name = blendTreeName; blendTree.blendParameter = blendParameterName; blendTree.useAutomaticThresholds = false; AnimatorState subBlendTreeState; BlendTree subBlendTree = null; AnimationClip animationClip = null; for (int i = 0; i < blendTree1D.blocks.Count; i++) { if (blendTree1D.blocks.Count > 1) { // 1D BlendTree with SubBlendTrees that have motionClips as children //Debug.LogFormat("Multi-BlendTree: {0}/{1}", blendTree1D.blocks.Keys[i], blendTree1D.blocks.Keys.Count); string subBlendTreeName = string.Format("{0}_BlendTree", blendTree1D.blocks.Keys[i]); //// -- Update BlendTree Parameter -- string subBlendParameterName = string.Format("{0}_Blend_{1}", state.Name, blendTree1D.blocks.Keys[i]); AnimatorControllerParameter subBlendParameter = null; if (!ParameterExists(subBlendParameterName, this.animatorController.parameters, out subBlendParameter)) { this.animatorController.AddParameter(subBlendParameterName, AnimatorControllerParameterType.Float); } // -- Create Sub-BlendTree -- if (i >= blendTree.children.Length) { subBlendTree = CreateBlendTree(subBlendTreeName); blendTree.AddChild(subBlendTree); } else if (blendTree.children[i].motion == null) { subBlendTree = CreateBlendTree(subBlendTreeName); blendTree.children[i].motion = subBlendTree; } subBlendTree = blendTree.children[i].motion as BlendTree; subBlendTree.name = subBlendTreeName; subBlendTree.blendParameter = subBlendParameterName; subBlendTree.useAutomaticThresholds = false; // -- Update Clips -- for (int y = 0; y < blendTree1D.blocks.Values[i].Length; y++) { //Debug.LogFormat("- {0}: {1}", blendTree1D.blocks.Values[i][y].label, subBlendTree.children[y].motion); animationClip = blendTree1D.blocks.Values[i][y].clip; if (y < subBlendTree.children.Length) { subBlendTree.children[y].motion = animationClip; // Update } else { subBlendTree.AddChild(animationClip); // Add } } // Rewrite the Threshold ChildMotion[] subChildren = subBlendTree.children; for (int z = 0; z < subBlendTree.children.Length; z++) { subChildren[z].threshold = z; } subBlendTree.children = subChildren; } else { // 1D BlendTree with Motion Clips and One Parameter for (int x = 0; x < blendTree1D.blocks.Values[0].Length; x++) { animationClip = blendTree1D.blocks.Values[0][x].clip; if (x < blendTree.children.Length) { blendTree.children[x].motion = animationClip; // Update } else { blendTree.AddChild(animationClip); // Add } } } } // Rewrite the Threshold ChildMotion[] children = blendTree.children; for (int z = 0; z < blendTree.children.Length; z++) { children[z].threshold = z; } blendTree.children = children; } //// --- Anystate Transitions --- string triggerParameterName = blendTreeName; AnimatorControllerParameter transitionParameter = null; if (!ParameterExists(triggerParameterName, this.animatorController.parameters, out transitionParameter)) { this.animatorController.AddParameter(triggerParameterName, AnimatorControllerParameterType.Trigger); } AnimatorStateTransition transition = null; if (!StateTransitionExists(triggerParameterName, this.animatorController.layers[layerIndex].stateMachine.anyStateTransitions, out transition)) { transition = this.animatorController.layers[layerIndex].stateMachine.AddAnyStateTransition(blendTreeState); transition.AddCondition(AnimatorConditionMode.If, 0f, triggerParameterName); transition.AddCondition(AnimatorConditionMode.If, 0f, stateParameterName); transition.destinationStateMachine = statemachine; } } // --- Update Animations in State --- List <AnimationObject> animations = state.GetAnimations(); for (int i = 0; i < animations.Count; i++) { // -- Setup AnimatorState -- AnimationObject animation = animations[i]; AnimatorState animatorState = null; if (string.IsNullOrEmpty(animation.label)) { continue; } if (!AnimatorstateExists(animation.label, statemachine.states, out animatorState)) { animatorState = statemachine.AddState(animation.label); } // -- Update AnimationState -- animatorState.motion = animation.clip; // Update MotionClip // -- Animation Events -- if (animation.clip != null && animation.clip.events != null && animation.clip.events.Length > 0) { //for(int x = 0; x < animation.clip.events.Length; x++) //{ // Debug.LogFormat("{0}: ({1}) {2}", animation.clip.name, // animation.clip.events[x].time, // animation.clip.events[x].functionName); //} //AnimationEvent animationEvent = new AnimationEvent(); //animationEvent. //animation.clip.AddEvent() } // -- Update Parameters -- string parameterName = animation.label; AnimatorControllerParameter parameter = null; if (!ParameterExists(parameterName, this.animatorController.parameters, out parameter)) { this.animatorController.AddParameter(parameterName, AnimatorControllerParameterType.Trigger); } // -- Update Transition -- AnimatorStateTransition transition = null; //// --- Anystate Transitions --- if (!StateTransitionExists(parameterName, this.animatorController.layers[layerIndex].stateMachine.anyStateTransitions, out transition)) { transition = this.animatorController.layers[layerIndex].stateMachine.AddAnyStateTransition(animatorState); transition.AddCondition(AnimatorConditionMode.If, 0f, parameterName); if (!(stateParameter.name.Contains("Reset") && layerIndex > 0)) { transition.AddCondition(AnimatorConditionMode.If, 0f, stateParameterName); } transition.destinationStateMachine = statemachine; } } // --- Add Transitions between States --- for (int i = 0; i < animations.Count; i++) { AnimationObject animation = animations[i]; AnimatorState animatorSenderState = null; AnimatorState animatorReceiverState = null; if (AnimatorstateExists(animation.label, statemachine.states, out animatorSenderState) && AnimatorstateExists(animation.destination, statemachine.states, out animatorReceiverState)) { AnimatorStateTransition transition = null; if (!TransitionExists(animatorSenderState, animatorReceiverState, out transition)) { //Debug.LogFormat("AnimatorController: Add Transition from '{0}' to {1}!", animatorSenderState.name, animatorReceiverState.name); transition = animatorSenderState.AddTransition(animatorReceiverState); transition.exitTime = 1f; transition.duration = 0f; transition.hasExitTime = true; } } } } return(status); }
public static AnimatorStateMachine CreateStateMachine(AnimatorStateMachine parentStateMachine, Vector3 position, BitActionSwitchGroup bitActionSwitchGroup, AnimatorState loadBitStartState, AnimatorState endState, int groupIndex) { var stateMachine = parentStateMachine.AddStateMachine("BitCalculator", position); stateMachine.anyStatePosition = Style.AnyStatePosition; stateMachine.entryPosition = Style.EntryPosition; stateMachine.exitPosition = Style.ExitPosition; stateMachine.parentStateMachinePosition = Style.ParentStateMachinePosition; var maxDigit = Convert.ToString(1 << (bitActionSwitchGroup.bitActionSwitchItems.Count - 1), 2).Length; var zeroState = stateMachine.AddStateDefaultParam("".PadLeft(maxDigit, '0'), Style.ZeroStatePosition); zeroState.motion = GlobalClips.ShortEmptyClip; var zeroDriver = zeroState.AddStateMachineBehaviour <VRCAvatarParameterDriver>(); zeroDriver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { name = bitActionSwitchGroup.variableName, value = 0.0f }); zeroDriver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { name = ActionSwitchParameters.ObjectNumParameterName, value = 0.0f }); zeroDriver.parameters.AddRange(bitActionSwitchGroup.bitActionSwitchItems.Select((value, index) => new VRC_AvatarParameterDriver.Parameter { name = ActionSwitchParameters.GetObjectFloatStatusParameterName(index + 1 + groupIndex * 9), value = 0.0f })); zeroState.AddTransitionDefaultParam(endState, AnimatorConditionMode.NotEqual, 0.0f, ActionSwitchParameters.ObjectNumParameterName); zeroState.AddTransitionDefaultParam(endState, new[] { new AnimatorCondition { mode = AnimatorConditionMode.IfNot, parameter = ActionSwitchParameters.VRCIsLocalParameterName, threshold = 0.0f }, new AnimatorCondition { mode = AnimatorConditionMode.NotEqual, parameter = bitActionSwitchGroup.variableName, threshold = 0 }, }); loadBitStartState.AddTransitionDefaultParam(zeroState, new[] { new AnimatorCondition { mode = AnimatorConditionMode.IfNot, parameter = ActionSwitchParameters.VRCIsLocalParameterName, threshold = 0.0f }, new AnimatorCondition { mode = AnimatorConditionMode.Equals, parameter = bitActionSwitchGroup.variableName, threshold = 0.0f }, }); var loadToZero = loadBitStartState.AddTransitionDefaultParam(zeroState, new[] { new AnimatorCondition { mode = AnimatorConditionMode.If, parameter = ActionSwitchParameters.VRCIsLocalParameterName, threshold = 0.0f }, new AnimatorCondition { mode = AnimatorConditionMode.Equals, parameter = ActionSwitchParameters.ObjectNumParameterName, threshold = 0.0f }, }); var conditions = loadToZero.conditions; ArrayUtility.AddRange(ref conditions, bitActionSwitchGroup.bitActionSwitchItems.Select((value, index) => new AnimatorCondition { mode = AnimatorConditionMode.IfNot, parameter = ActionSwitchParameters.GetObjectActiveStatusParameterName(index + 1), threshold = 0.0f }).ToArray()); loadToZero.conditions = conditions; var stateIndex = 1; for (var i = 0; i < bitActionSwitchGroup.bitActionSwitchItems.Count; i++) { for (var j = 0; j < 1 << i; j++) { var bitStatePosition = Style.ZeroStatePosition; bitStatePosition.x -= 250 * (i + 1); bitStatePosition.y += 100 * j; var stateName = Convert.ToString(stateIndex, 2).PadLeft(maxDigit, '0'); var progress = (float)i / bitActionSwitchGroup.bitActionSwitchItems.Count; var info = $"{i + 1} / {bitActionSwitchGroup.bitActionSwitchItems.Count}({progress * 100:F2}%) - {stateName}"; EditorUtility.DisplayProgressBar($"Create Group{groupIndex + 1} - Create States {bitActionSwitchGroup.bitActionSwitchItems[i].name}", info, progress); var bitState = stateMachine.AddStateDefaultParam(stateName, bitStatePosition); bitState.motion = GlobalClips.ShortEmptyClip; var bitDriver = bitState.AddStateMachineBehaviour <VRCAvatarParameterDriver>(); bitDriver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { name = bitActionSwitchGroup.variableName, value = stateIndex }); bitDriver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { name = ActionSwitchParameters.ObjectNumParameterName, value = 0.0f }); var binaryArray = stateIndex.ToBinaryArray(maxDigit); bitDriver.parameters.AddRange(Enumerable.Range(0, maxDigit).Select(x => new VRC_AvatarParameterDriver.Parameter { name = ActionSwitchParameters.GetObjectFloatStatusParameterName(x + 1 + groupIndex * 9), value = binaryArray[x] ? 1.0f : 0.0f })); // transition bitState.AddTransitionDefaultParam(endState, AnimatorConditionMode.NotEqual, 0.0f, ActionSwitchParameters.ObjectNumParameterName); bitState.AddTransitionDefaultParam(endState, new[] { new AnimatorCondition { mode = AnimatorConditionMode.IfNot, parameter = ActionSwitchParameters.VRCIsLocalParameterName, threshold = 0.0f }, new AnimatorCondition { mode = AnimatorConditionMode.NotEqual, parameter = bitActionSwitchGroup.variableName, threshold = stateIndex }, }); loadBitStartState.AddTransitionDefaultParam(bitState, new[] { new AnimatorCondition { mode = AnimatorConditionMode.IfNot, parameter = ActionSwitchParameters.VRCIsLocalParameterName, threshold = 0.0f }, new AnimatorCondition { mode = AnimatorConditionMode.Equals, parameter = bitActionSwitchGroup.variableName, threshold = stateIndex }, }); var loadToBit = loadBitStartState.AddTransitionDefaultParam(bitState, new[] { new AnimatorCondition { mode = AnimatorConditionMode.If, parameter = ActionSwitchParameters.VRCIsLocalParameterName, threshold = 0.0f }, new AnimatorCondition { mode = AnimatorConditionMode.Equals, parameter = ActionSwitchParameters.ObjectNumParameterName, threshold = 0.0f }, }); var animatorConditions = loadToBit.conditions; ArrayUtility.AddRange(ref animatorConditions, bitActionSwitchGroup.bitActionSwitchItems.Select((value, index) => new AnimatorCondition { mode = binaryArray[index] ? AnimatorConditionMode.If : AnimatorConditionMode.IfNot, parameter = ActionSwitchParameters.GetObjectActiveStatusParameterName(index + 1 + groupIndex * 9), threshold = 0.0f }).ToArray()); loadToBit.conditions = animatorConditions; stateIndex++; } } return(stateMachine); }
public static AnimatorStateMachine CloneDeep(this AnimatorStateMachine source) { var dest = new AnimatorStateMachine { defaultState = InstanceCaches <AnimatorState> .FindOrCreate(source.defaultState, w => w.CloneDeep()), anyStatePosition = source.anyStatePosition, entryPosition = source.entryPosition, exitPosition = source.exitPosition, parentStateMachinePosition = source.parentStateMachinePosition, hideFlags = source.hideFlags, name = source.name }; foreach (var sourceState in source.states) { dest.AddState(InstanceCaches <AnimatorState> .FindOrCreate(sourceState.state, w => w.CloneDeep()), sourceState.position); } foreach (var sourceTransition in source.anyStateTransitions) { AnimatorStateTransition transition = null; if (sourceTransition.destinationStateMachine != null) { transition = dest.AddAnyStateTransition(InstanceCaches <AnimatorStateMachine> .FindOrCreate(sourceTransition.destinationStateMachine, CloneDeep)); } if (sourceTransition.destinationState != null) { transition = dest.AddAnyStateTransition(InstanceCaches <AnimatorState> .FindOrCreate(sourceTransition.destinationState, w => w.CloneDeep())); } if (transition == null) { throw new ArgumentNullException(nameof(transition)); } sourceTransition.CloneTo(transition); // should always false if (InstanceCaches <AnimatorStateTransition> .Find(sourceTransition.GetInstanceID()) == null) { InstanceCaches <AnimatorStateTransition> .Register(sourceTransition.GetInstanceID(), transition); } } foreach (var sourceTransition in source.entryTransitions) { AnimatorTransition transition = null; if (sourceTransition.destinationStateMachine != null) { transition = dest.AddEntryTransition(InstanceCaches <AnimatorStateMachine> .FindOrCreate(sourceTransition.destinationStateMachine, CloneDeep)); } if (sourceTransition.destinationState != null) { transition = dest.AddEntryTransition(InstanceCaches <AnimatorState> .FindOrCreate(sourceTransition.destinationState, w => w.CloneDeep())); } if (transition == null) { throw new ArgumentNullException(nameof(transition)); } transition.CloneTo(sourceTransition); // should always false if (InstanceCaches <AnimatorTransition> .Find(sourceTransition.GetInstanceID()) == null) { InstanceCaches <AnimatorTransition> .Register(sourceTransition.GetInstanceID(), transition); } } foreach (var sourceBehaviour in source.behaviours) { var behaviour = dest.AddStateMachineBehaviour(sourceBehaviour.GetType()); sourceBehaviour.CloneDeepTo(behaviour); // store InstanceCaches <StateMachineBehaviour> .Register(behaviour.GetInstanceID(), behaviour); } foreach (var sourceStateMachine in source.stateMachines) { dest.AddStateMachine(InstanceCaches <AnimatorStateMachine> .FindOrCreate(sourceStateMachine.stateMachine, CloneDeep), sourceStateMachine.position); } return(dest); }
public static AnimatorStateMachine CreateStateMachine(AnimatorStateMachine parentStateMachine, Vector3 position, int index, BitActionSwitchGroup bitActionSwitchGroup, AnimatorStateMachine bitCalculatorStateMachine, int groupIndex) { var name = (index + 1 + groupIndex * 9).ToString(); var stateMachine = parentStateMachine.AddStateMachine($"Object {name} Switch", position); stateMachine.anyStatePosition = Style.AnyStatePosition; stateMachine.entryPosition = Style.EntryPosition; stateMachine.exitPosition = Style.ExitPosition; stateMachine.parentStateMachinePosition = Style.ParentStateMachinePosition; var topState = stateMachine.AddStateDefaultParam($"Object{name}", Style.ObjectTopStatePosition); stateMachine.defaultState = topState; var activeState = stateMachine.AddStateDefaultParam("Active", Style.ActiveStatePosition); activeState.motion = GlobalClips.ShortEmptyClip; var activeDriver = activeState.AddStateMachineBehaviour <VRCAvatarParameterDriver>(); activeDriver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { name = ActionSwitchParameters.GetObjectActiveStatusParameterName(index + 1 + groupIndex * 9), value = 1.0f }); var inactiveState = stateMachine.AddStateDefaultParam("Inactive", Style.InactiveStatePosition); inactiveState.motion = GlobalClips.ShortEmptyClip; var inactiveDriver = inactiveState.AddStateMachineBehaviour <VRCAvatarParameterDriver>(); inactiveDriver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { name = ActionSwitchParameters.GetObjectActiveStatusParameterName(index + 1 + groupIndex * 9), value = 0.0f }); var conditions = new List <AnimatorCondition>(); for (var i = 0; i < 1 << bitActionSwitchGroup.bitActionSwitchItems.Count; i++) { var targetDigit = ((1 << index) & i) == 0; if (targetDigit) // 0,2,4,6 { topState.AddTransitionDefaultParam(activeState, AnimatorConditionMode.Equals, i, bitActionSwitchGroup.variableName); conditions.Add(new AnimatorCondition { mode = AnimatorConditionMode.NotEqual, threshold = i, parameter = bitActionSwitchGroup.variableName }); // transition inactiveState.AddTransitionDefaultParam(bitCalculatorStateMachine.states[i].state, AnimatorConditionMode.Equals, (1 << index) ^ i, bitActionSwitchGroup.variableName); } else // 1,3,5,7 { activeState.AddTransitionDefaultParam(bitCalculatorStateMachine.states[i].state, AnimatorConditionMode.Equals, (1 << index) ^ i, bitActionSwitchGroup.variableName); } } topState.AddTransitionDefaultParam(inactiveState, conditions.ToArray()); return(stateMachine); }
/************************************************************************************************/ public AnimatorController CreateAnimatorController() { // The new controller that will be created based on Manager animations AnimatorController newController = new AnimatorController(); newController.name = DEFAULT_CONTROLLER_NAME; newController.AddLayer("DefaultLayer"); // Add a parameter that will determine the animation states AnimatorControllerParameter animatorParameter = new AnimatorControllerParameter(); animatorParameter.type = AnimatorControllerParameterType.Int; animatorParameter.name = "TextAnimation"; animatorParameter.defaultInt = 999; newController.AddParameter(animatorParameter); // Add state machine AnimatorStateMachine rootStateMachine = newController.layers[0].stateMachine; AnimatorStateMachine stateMachine = rootStateMachine.AddStateMachine("TextAnimationStateMachine"); // Create a default state to prevent animation auto playing index 0 AnimatorState waitingState = stateMachine.AddState("Waiting"); //foreach (AnimationClip clip in DamageNumberManager.instance.animations) for (int i = 0; i < myScript.animations.Length; i++) { AnimationClip clip = myScript.animations[i]; // Add new state based on the AnimationClip AnimatorState state = stateMachine.AddState(clip.name); state.motion = clip; // Create transition from "Waiting" to the new state AnimatorStateTransition transition = waitingState.AddTransition(state, false); transition.AddCondition(AnimatorConditionMode.Equals, i, "TextAnimation"); } //// Save OR update the new AnimatorController as an asset (.controller) // Search if there is already an AnimatorController (and get its path if so) string assetPath = null; if (myScript.animatorOverrideController != null) { assetPath = AssetDatabase.GetAssetPath(myScript.animatorOverrideController.runtimeAnimatorController); } Object existingController = AssetDatabase.LoadAssetAtPath <Object>(assetPath); if (existingController == null) { // Create the new AnimatorController in the specified default directory AssetDatabase.CreateAsset(newController, DEFAULT_CONTROLLER_PATH + DEFAULT_CONTROLLER_NAME + ".controller"); existingController = newController; Debug.LogError("AnimatorController not found. Creating new one in " + DEFAULT_CONTROLLER_PATH + " directory."); } else { // Update the existing AnimatorController copy with latest data EditorUtility.CopySerialized(newController, existingController); Debug.Log("Updated existing AnimatorController found at " + assetPath + "."); } // Make sure the returned controller refers to the generated 'asset', not the controller 'within this scope' AnimatorController updatedController_asset = (AnimatorController)existingController; AssetDatabase.SaveAssets(); return(updatedController_asset); }
static void CreateController() { // Creates the controller AnimatorController controller = AnimatorController.CreateAnimatorControllerAtPath("Assets/Animations/Motion.controller"); // Add Animation Clips AnimationClip clip = new AnimationClip(); clip.frameRate = 24; AssetDatabase.CreateAsset(clip, "Assets/Animations/Motion.anim"); AssetDatabase.SaveAssets(); // Add parameters controller.AddParameter("TransitionNow", AnimatorControllerParameterType.Trigger); controller.AddParameter("Reset", AnimatorControllerParameterType.Trigger); controller.AddParameter("GotoB1", AnimatorControllerParameterType.Trigger); controller.AddParameter("GotoC", AnimatorControllerParameterType.Trigger); // Add StateMachines AnimatorStateMachine rootStateMachine = controller.layers[0].stateMachine; AnimatorStateMachine stateMachineA = rootStateMachine.AddStateMachine("smA"); AnimatorStateMachine stateMachineB = rootStateMachine.AddStateMachine("smB"); AnimatorStateMachine stateMachineC = stateMachineB.AddStateMachine("smC"); // Add Clip // Add States AnimatorState stateA1 = stateMachineA.AddState("stateA1"); AnimatorState stateB1 = stateMachineB.AddState("stateB1"); AnimatorState stateB2 = stateMachineB.AddState("stateB2"); stateMachineC.AddState("stateC1"); AnimatorState stateC2 = stateMachineC.AddState("stateC2"); // don’t add an entry transition, should entry to state by default // Add clip stateA1.motion = clip; // Add Transitions AnimatorStateTransition exitTransition = stateA1.AddExitTransition(); exitTransition.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, "TransitionNow"); exitTransition.duration = 0; AnimatorStateTransition resetTransition = rootStateMachine.AddAnyStateTransition(stateA1); resetTransition.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, "Reset"); resetTransition.duration = 0; AnimatorTransition transitionB1 = stateMachineB.AddEntryTransition(stateB1); transitionB1.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, "GotoB1"); stateMachineB.AddEntryTransition(stateB2); stateMachineC.defaultState = stateC2; AnimatorStateTransition exitTransitionC2 = stateC2.AddExitTransition(); exitTransitionC2.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, "TransitionNow"); exitTransitionC2.duration = 0; AnimatorTransition stateMachineTransition = rootStateMachine.AddStateMachineTransition(stateMachineA, stateMachineC); stateMachineTransition.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, "GotoC"); rootStateMachine.AddStateMachineTransition(stateMachineA, stateMachineB); }