protected override void OnActivate()
        {
            // When this becomes the active behaviour. There can only be one active behaviour.
            // Switching behaviours is done by the behaviours themselves, using PuppetEvents.
            // Each behaviour should know when it is no longer required and which behaviours to switch to in each case.
            isFinished  = false;
            balanceLost = false;
            finishTimer = 0f;
            weight      = 0f;
            timer       = 0f;
            forceFinish = false;

            foreach (Muscle m in puppetMaster.muscles)
            {
                m.state.pinWeightMlp    = 0f;
                m.state.muscleWeightMlp = 1f;

                if (m.props.group == Muscle.Group.Foot)
                {
                    PressureSensor pressureSensor = m.transform.GetComponent <PressureSensor>();
                    if (pressureSensor == null)
                    {
                        pressureSensor = m.transform.gameObject.AddComponent <PressureSensor>();
                    }
                    pressureSensor.layers = groundLayers;
                }
                else if (m.props.group == Muscle.Group.Spine || m.props.group == Muscle.Group.Head)
                {
                    m.state.muscleWeightMlp = spineMuscleWeightMlp;
                }
            }

            onActivate.Trigger(puppetMaster);
        }
        protected override void OnDeactivate()
        {
            // Called when this behaviour is exited. OnActivate is the place for resetting variables to defaults though.
            isFinished  = false;
            balanceLost = false;
            finishTimer = 0f;
            timer       = 0f;
            forceFinish = false;

            foreach (Muscle m in puppetMaster.muscles)
            {
                m.state.muscleWeightMlp  = 1f;
                m.state.mappingWeightMlp = 1f;

                if (m.props.group == Muscle.Group.Foot)
                {
                    m.state.muscleDamperMlp = 1f;
                    m.state.muscleDamperAdd = 0f;
                    m.state.maxForceMlp     = 1f;

                    PressureSensor pressureSensor = m.transform.GetComponent <PressureSensor>();
                    if (pressureSensor != null)
                    {
                        Destroy(pressureSensor);
                    }
                }
            }

            foreach (SubBehaviourBalancer balancer in balancers)
            {
                balancer.joint.targetAngularVelocity = Vector3.zero;
            }
        }
Example #3
0
        public void Initiate(BehaviourBase behaviour, Settings settings, Rigidbody Ibody, Rigidbody[] rigidbodies, ConfigurableJoint joint, Transform[] copPoints, PressureSensor pressureSensor)
        {
            this.behaviour      = behaviour;
            this.settings       = settings;
            this.Ibody          = Ibody;
            this.rigidbodies    = rigidbodies;
            this.joint          = joint;
            this.copPoints      = copPoints;
            this.pressureSensor = pressureSensor;

            toJointSpace = PhysXTools.ToJointSpace(joint);

            behaviour.OnPreFixedUpdate += Solve;
        }
        // Initiate something. This is called only once by the PuppetMaster in Start().
        protected override void OnInitiate()
        {
            ik = puppetMaster.targetRoot.GetComponentInChildren <FullBodyBipedIK>();
            if (ik == null)
            {
                Debug.LogError("No FullBodyBipedIK component found on the target hierarchy, can not initiate BehaviourBipedStagger.", transform);
                enabled = false;
                return;
            }
            if (ik.solver.iterations > 0)
            {
                Debug.LogWarning("BehaviourBipedStagger works best and fastest with FullBodyBipedIK solver iterations set to 0.", transform);
            }

            ik.solver.OnPreUpdate += Solve;

            // Balancers
            Transform[] copPoints = new Transform[0];
            foreach (Muscle m in puppetMaster.muscles)
            {
                if (m.props.group == Muscle.Group.Foot)
                {
                    System.Array.Resize(ref copPoints, copPoints.Length + 1);
                    copPoints[copPoints.Length - 1] = m.transform;
                }
            }

            if (copPoints.Length == 0)
            {
                Debug.LogError("No 'Foot' muscles found, please assign a Group for each muscle in PuppetMaster.", transform);
                enabled = false;
                return;
            }

            rigidbodies = new Rigidbody[puppetMaster.muscles.Length];
            for (int i = 0; i < rigidbodies.Length; i++)
            {
                rigidbodies[i] = puppetMaster.muscles[i].rigidbody;
            }

            // TODO Check for rigidbody mass
            // TODO Make sure Angular Limits is enabled

            foreach (Muscle m in puppetMaster.muscles)
            {
                if (m.props.group == Muscle.Group.Foot)
                {
                    System.Array.Resize(ref balancers, balancers.Length + 1);
                    balancers[balancers.Length - 1] = new SubBehaviourBalancer();

                    balancers[balancers.Length - 1].Initiate(this as BehaviourBase, balancerSettings, m.joint.connectedBody, rigidbodies, m.joint, copPoints, m.joint.GetComponent <PressureSensor>());

                    PressureSensor pressureSensor = m.transform.gameObject.AddComponent <PressureSensor>();
                    pressureSensor.layers = groundLayers;
                }
            }

            // Muscle axes
            pelvisMuscle  = puppetMaster.muscles[0];
            pelvisForward = Quaternion.Inverse(pelvisMuscle.target.rotation) * transform.forward;

            // Footsteps
            footsteps = new Footstep[2] {
                new Footstep(ik.solver.leftFootEffector, ik.references.leftThigh, pelvisMuscle, true),
                new Footstep(ik.solver.rightFootEffector, ik.references.rightThigh, pelvisMuscle, false)
            };

            // IK settings
            ik.solver.leftLegMapping.maintainRotationWeight  = 0f;
            ik.solver.rightLegMapping.maintainRotationWeight = 0f;
        }