Пример #1
0
        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);
        }
Пример #2
0
    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);
        }
    }
Пример #3
0
    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;
    }
Пример #5
0
        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);
        }
Пример #6
0
        /// <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)));
 }
Пример #8
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();
        }
Пример #9
0
        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);
        }
Пример #12
0
        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);
        }