private static AnimatorState CreateInitState(AnimatorStateMachine stateMachine,
                                                     IReadOnlyList <BitActionSwitchItem> actionSwitchItems, int groupIndex)
        {
            var state = stateMachine.AddStateDefaultParam("Init", Style.InitStatePosition);
            var avatarParameterDriver = state.AddStateMachineBehaviour <VRCAvatarParameterDriver>();

            avatarParameterDriver.parameters = new List <VRC_AvatarParameterDriver.Parameter>
            {
                new VRC_AvatarParameterDriver.Parameter
                {
                    name  = ActionSwitchParameters.InitializedParameterName,
                    value = 1.0f
                }
            };

            avatarParameterDriver.parameters.AddRange(actionSwitchItems.Select((value, index) =>
                                                                               new VRC_AvatarParameterDriver.Parameter
            {
                name  = ActionSwitchParameters.GetObjectFloatStatusParameterName(index + 1 + groupIndex * 9),
                value = 0.0f
            }));

            avatarParameterDriver.parameters.AddRange(actionSwitchItems.Select((value, index) =>
                                                                               new VRC_AvatarParameterDriver.Parameter
            {
                name  = ActionSwitchParameters.GetObjectActiveStatusParameterName(index + 1 + groupIndex * 9),
                value = 0.0f
            }));

            return(state);
        }
Example #2
0
        public void CreateBitActionSwitchAnimator(List <ActivationAnimationClipItem> animationClips, BitActionSwitchGroup bitActionSwitchGroup, int groupIndex)
        {
            this.AddAnimatorParameters(bitActionSwitchGroup, groupIndex);

            var mainLayer = this.animatorController.AddLayerDefault(ActionSwitchParameters.GetLayerName(groupIndex + 1));

            BitActionSwitchMainLayer.Create(mainLayer.stateMachine, bitActionSwitchGroup, groupIndex);

            for (var i = 0; i < bitActionSwitchGroup.bitActionSwitchItems.Count; i++)
            {
                var animateLayer = this.animatorController.AddLayerDefault(ActionSwitchParameters.GetObjectStatusLayerName(i + 1 + groupIndex * 9));
                BitActionSwitchAnimateLayer.Create(animateLayer.stateMachine, i, bitActionSwitchGroup, animationClips[i], groupIndex);
            }
        }
Example #3
0
        private void AddAnimatorParameters(BitActionSwitchGroup bitActionSwitchGroup, int groupIndex)
        {
            if (this.animatorController.parameters.All(x => x.name != ActionSwitchParameters.VRCSeatedParameterName))
            {
                this.animatorController.AddParameter(new AnimatorControllerParameter
                {
                    type        = AnimatorControllerParameterType.Bool,
                    name        = ActionSwitchParameters.VRCSeatedParameterName,
                    defaultBool = false
                });
            }

            if (this.animatorController.parameters.All(x => x.name != ActionSwitchParameters.VRCIsLocalParameterName))
            {
                this.animatorController.AddParameter(new AnimatorControllerParameter
                {
                    type        = AnimatorControllerParameterType.Bool,
                    name        = ActionSwitchParameters.VRCIsLocalParameterName,
                    defaultBool = false
                });
            }

            if (this.animatorController.parameters.All(x => x.name != bitActionSwitchGroup.variableName))
            {
                this.animatorController.AddParameter(new AnimatorControllerParameter
                {
                    type       = AnimatorControllerParameterType.Int,
                    name       = bitActionSwitchGroup.variableName,
                    defaultInt = 0
                });
            }

            if (this.animatorController.parameters.All(x => x.name != ActionSwitchParameters.ObjectNumParameterName))
            {
                this.animatorController.AddParameter(new AnimatorControllerParameter
                {
                    type       = AnimatorControllerParameterType.Int,
                    name       = ActionSwitchParameters.ObjectNumParameterName,
                    defaultInt = 0
                });
            }

            if (this.animatorController.parameters.All(x => x.name != ActionSwitchParameters.ThroughTransitionParameterName))
            {
                this.animatorController.AddParameter(new AnimatorControllerParameter
                {
                    type        = AnimatorControllerParameterType.Bool,
                    name        = ActionSwitchParameters.ThroughTransitionParameterName,
                    defaultBool = true
                });
            }

            if (this.animatorController.parameters.All(x => x.name != ActionSwitchParameters.InitializedParameterName))
            {
                this.animatorController.AddParameter(new AnimatorControllerParameter
                {
                    type        = AnimatorControllerParameterType.Bool,
                    name        = ActionSwitchParameters.InitializedParameterName,
                    defaultBool = false
                });
            }

            for (var i = 0; i < bitActionSwitchGroup.bitActionSwitchItems.Count; i++)
            {
                this.animatorController.AddParameter(new AnimatorControllerParameter
                {
                    type        = AnimatorControllerParameterType.Bool,
                    name        = ActionSwitchParameters.GetObjectActiveStatusParameterName(i + 1 + groupIndex * 9),
                    defaultBool = false
                });

                this.animatorController.AddParameter(new AnimatorControllerParameter
                {
                    type         = AnimatorControllerParameterType.Float,
                    name         = ActionSwitchParameters.GetObjectFloatStatusParameterName(i + 1 + groupIndex * 9),
                    defaultFloat = 0.0f
                });
            }
        }
        public static void Create(AnimatorStateMachine stateMachine, int index, BitActionSwitchGroup bitActionSwitchGroup,
                                  ActivationAnimationClipItem animationClip, int groupIndex)
        {
            stateMachine.entryPosition    = Style.EntryPosition;
            stateMachine.anyStatePosition = Style.AnyStatePosition;
            stateMachine.exitPosition     = Style.ExitPosition;

            var initState              = stateMachine.AddStateDefaultParam("Init", Style.InitStatePosition);
            var staticBitActiveState   = stateMachine.AddStateDefaultParam("Static Bit Active", Style.StaticBitActiveStatePosition);
            var staticBitInactiveState = stateMachine.AddStateDefaultParam("Static Bit Inactive", Style.StaticBitInactiveStatePosition);
            var bitActiveState         = stateMachine.AddStateDefaultParam("Bit Active", Style.BitActiveStatePosition);
            var bitInactiveState       = stateMachine.AddStateDefaultParam("Bit Inactive", Style.BitInactiveStatePosition);

            // set motion
            var bitActionSwitchItem = bitActionSwitchGroup.bitActionSwitchItems[index];

            if (bitActionSwitchItem.registerType == BitActionSwitchItem.RegisterType.GameObject)
            {
                staticBitActiveState.motion   = animationClip.NonDefaultClip;
                staticBitInactiveState.motion = animationClip.DefaultClip;

                bitActiveState.motion   = staticBitActiveState.motion;
                bitInactiveState.motion = staticBitInactiveState.motion;
            }
            else
            {
                staticBitActiveState.motion   = bitActionSwitchItem.staticNonDefaultClip;
                staticBitInactiveState.motion = bitActionSwitchItem.staticDefaultClip;

                bitActiveState.motion   = bitActionSwitchItem.defaultClip == null ? staticBitActiveState.motion : bitActionSwitchItem.nonDefaultClip;
                bitInactiveState.motion = bitActionSwitchItem.nonDefaultClip == null ? staticBitInactiveState.motion : bitActionSwitchItem.defaultClip;
            }

            // transition
            stateMachine.AddAnyTransitionDefaultParam(initState, AnimatorConditionMode.If, 0.0f, ActionSwitchParameters.InitializedParameterName);

            staticBitActiveState.AddTransitionDefaultParam(bitInactiveState, AnimatorConditionMode.Equals, index + 1 + groupIndex * 9,
                                                           ActionSwitchParameters.ObjectNumParameterName);

            staticBitInactiveState.AddTransitionDefaultParam(bitActiveState, AnimatorConditionMode.Equals, index + 1 + groupIndex * 9,
                                                             ActionSwitchParameters.ObjectNumParameterName);

            var activeToInactive = bitActiveState.AddTransitionDefaultParam(bitInactiveState, AnimatorConditionMode.Less, 0.5f,
                                                                            ActionSwitchParameters.GetObjectFloatStatusParameterName(index + 1 + groupIndex * 9));

            activeToInactive.hasExitTime = true;
            activeToInactive.exitTime    = 1.0f;

            var inactiveToActive = bitInactiveState.AddTransitionDefaultParam(bitActiveState, AnimatorConditionMode.Greater, 0.5f,
                                                                              ActionSwitchParameters.GetObjectFloatStatusParameterName(index + 1 + groupIndex * 9));

            inactiveToActive.hasExitTime = true;
            inactiveToActive.exitTime    = 1.0f;


            var conditions = new List <AnimatorCondition>();

            for (var i = 0; i < 1 << bitActionSwitchGroup.bitActionSwitchItems.Count; i++)
            {
                var targetDigit = ((1 << index) & i) != 0;
                if (!targetDigit)
                {
                    continue;              // 1,3,5,7
                }
                initState.AddTransitionDefaultParam(staticBitActiveState, AnimatorConditionMode.Equals, i,
                                                    bitActionSwitchGroup.variableName);
                conditions.Add(new AnimatorCondition
                {
                    mode      = AnimatorConditionMode.NotEqual,
                    threshold = i,
                    parameter = bitActionSwitchGroup.variableName
                });
            }

            initState.AddTransitionDefaultParam(staticBitInactiveState, conditions.ToArray());
        }
        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 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);
        }