// Sets colliders of a muscle to puppet or unpinned mode
        public void SetColliders(Muscle m, bool unpinned)
        {
            var props = GetProps(m.props.group);

            if (unpinned)
            {
                foreach (Collider c in m.colliders)
                {
                    c.material = props.unpinnedMaterial != null ? props.unpinnedMaterial : defaults.unpinnedMaterial;

                    // Enable colliders
                    if (props.disableColliders)
                    {
                        c.enabled = true;
                    }
                }
            }
            else
            {
                foreach (Collider c in m.colliders)
                {
                    c.material = props.puppetMaterial != null ? props.puppetMaterial : defaults.puppetMaterial;

                    // Disable colliders
                    if (props.disableColliders)
                    {
                        Vector3 inertiaTensor = m.rigidbody.inertiaTensor;
                        c.enabled = false;
                        m.rigidbody.inertiaTensor = inertiaTensor;
                    }
                }
            }
        }
예제 #2
0
        // Sets colliders of a muscle to puppet or unpinned mode
        private void SetColliders(Muscle m, bool unpinned)
        {
            var props = GetProps(m.props.group);

            if (unpinned)
            {
                foreach (Collider c in m.colliders)
                {
                    c.material = props.unpinnedMaterial != null? props.unpinnedMaterial: defaults.unpinnedMaterial;

                    // Enable colliders
                    c.enabled = true;
                }
            }
            else
            {
                foreach (Collider c in m.colliders)
                {
                    c.material = props.puppetMaterial != null? props.puppetMaterial: defaults.puppetMaterial;

                    // Enable colliders
                    if (props.disableColliders)
                    {
                        c.enabled = false;
                    }
                }
            }
        }
예제 #3
0
 public virtual void OnMuscleRemoved(Muscle m)
 {
     if (OnHierarchyChanged != null)
     {
         OnHierarchyChanged();
     }
 }
예제 #4
0
 public HandBehaviours(ActorBehavioursBase <ACType, ABB> abb, PropHandler ph)
 {
     propHandler = ph;
     this.abb    = (ABB)abb;
     this.ac     = abb.ac;
     muscleGroup = ph.attachedMuscleGroup;
     handMuscle  = muscleGroup.muscles[muscleGroup.muscles.Length - 1];
 }
예제 #5
0
 // 将 直接把现有的 muscle 通过调整 添加到 muscles 中
 public void AddMuscle(Muscle muscle, bool forceLayers = true)
 {
     muscle.transform.gameObject.SetActive(true);
     muscle.Initiate(muscles);
     System.Array.Resize(ref muscles, muscles.Length + 1);
     muscles[muscles.Length - 1]   = muscle;
     muscle.rigidbody.centerOfMass = Vector3.zero;
 }
예제 #6
0
            public Footstep(IKEffector effector, Transform thigh, Muscle pelvisMuscle, bool isLeft)
            {
                this.effector     = effector;
                this.thigh        = thigh;
                this.pelvisMuscle = pelvisMuscle;
                this.isLeft       = isLeft;

                Reset();
            }
예제 #7
0
        public override void OnMuscleReconnected(Muscle m)
        {
            base.OnMuscleReconnected(m);

            m.state.pinWeightMlp     = 0f;
            m.state.muscleWeightMlp  = 1;
            m.state.muscleDamperMlp  = 1;
            m.state.maxForceMlp      = 1;
            m.state.mappingWeightMlp = 1f;
        }
예제 #8
0
 // Ignores or unignores collisions with all the colliders of this and another Muscle
 public void IgnoreCollisions(Muscle m, bool ignore)
 {
     foreach (Collider c in colliders)
     {
         foreach (Collider c2 in m.colliders)
         {
             if (c != null && c2 != null && c.enabled && c2.enabled && c.gameObject.activeInHierarchy && c2.gameObject.activeInHierarchy)
             {
                 Physics.IgnoreCollision(c, c2, ignore);
             }
         }
     }
 }
예제 #9
0
        // Called by PropMuscle when this prop is dropped
        public void Drop(PuppetMaster puppetMaster, int propMuscleIndex)
        {
            if (!puppetMaster.muscles[propMuscleIndex].joint.gameObject.activeInHierarchy)
            {
                transform.position = puppetMaster.muscles[propMuscleIndex].target.position;
                transform.rotation = puppetMaster.muscles[propMuscleIndex].target.rotation;
            }

            ReattachRigidbody();

            if (!puppetMaster.muscles[propMuscleIndex].joint.gameObject.activeInHierarchy || puppetMaster.muscles[propMuscleIndex].rigidbody.isKinematic)
            {
                r.velocity        = puppetMaster.muscles[propMuscleIndex].mappedVelocity;
                r.angularVelocity = puppetMaster.muscles[propMuscleIndex].mappedAngularVelocity;
            }

            transform.parent = defaultParent;

            meshRoot.parent        = transform;
            meshRoot.localPosition = Vector3.zero;
            meshRoot.localRotation = Quaternion.identity;

            for (int i = 0; i < colliders.Length; i++)
            {
                colliders[i].sharedMaterial = droppedMaterials[i];
            }

            puppetMaster.ResetInternalCollisions(puppetMaster.muscles[propMuscleIndex], false);
            puppetMaster.muscles[propMuscleIndex].colliders = emptyColliders;

            if (forceLayers)
            {
                foreach (Collider c in colliders)
                {
                    if (!c.isTrigger)
                    {
                        c.gameObject.layer = defaultLayer;
                    }
                }
            }

            isPickedUp = false;
            propMuscle = null;

            OnDrop(puppetMaster, propMuscleIndex);
        }
예제 #10
0
        public override void OnMuscleReconnected(Muscle m)
        {
            base.OnMuscleReconnected(m);

            if (m == puppetMaster.muscles[0])
            {
                SetState(State.Puppet);
            }

            float f = state == State.Puppet ? 1f : 0f;

            m.state.pinWeightMlp     = f;
            m.state.muscleWeightMlp  = f;
            m.state.muscleDamperMlp  = f;
            m.state.maxForceMlp      = 1;
            m.state.mappingWeightMlp = 1f;

            SetColliders(m, state == State.Unpinned);
        }
예제 #11
0
        // Called by PropMuscle when this prop is picked up
        public void PickUp(PuppetMaster puppetMaster, int propMuscleIndex)
        {
            RemoveRigidbody();

            transform.parent   = puppetMaster.muscles[propMuscleIndex].transform;
            transform.position = puppetMaster.muscles[propMuscleIndex].transform.position;
            transform.rotation = puppetMaster.muscles[propMuscleIndex].transform.rotation;

            meshRoot.parent        = puppetMaster.muscles[propMuscleIndex].target;
            meshRoot.localPosition = Vector3.zero;
            meshRoot.localRotation = Quaternion.identity;

            puppetMaster.muscles[propMuscleIndex].props = muscleProps;

            if (pickedUpMaterial != null)
            {
                foreach (Collider c in colliders)
                {
                    c.sharedMaterial = pickedUpMaterial;
                }
            }

            if (forceLayers)
            {
                foreach (Collider c in colliders)
                {
                    if (!c.isTrigger)
                    {
                        c.gameObject.layer = puppetMaster.muscles[propMuscleIndex].joint.gameObject.layer;
                    }
                }
            }

            puppetMaster.muscles[propMuscleIndex].colliders = colliders;
            puppetMaster.UpdateInternalCollisions(puppetMaster.muscles[propMuscleIndex]);

            isPickedUp = true;
            propMuscle = puppetMaster.muscles[propMuscleIndex];

            OnPickUp(puppetMaster, propMuscleIndex);
        }
예제 #12
0
            public Leg(IKSolverFullBodyBiped solver, PuppetMaster puppetMaster, FullBodyBipedEffector effectorType)
            {
                this.solver = solver;
                effector    = solver.GetEffector(effectorType);
                chain       = solver.GetChain(effectorType);

                stepFrom = effector.bone.position;
                stepTo   = effector.bone.position;
                position = effector.bone.position;

                offset = effectorType == FullBodyBipedEffector.LeftFoot? Vector3.left: Vector3.right;

                stepTimer  = 0f;
                stepLength = 0f;

                muscle      = puppetMaster.GetMuscle(effector.bone);
                thighMuscle = puppetMaster.GetMuscle(chain.nodes[0].transform);

                mass          = muscle.rigidbody.mass;
                inertiaTensor = muscle.rigidbody.inertiaTensor;
            }
예제 #13
0
        // 将对应的muscle 中 muscles 中移除 并 标记active 为false;
        public void RemoveMuscle(Muscle muscle)
        {
            Muscle[] newMuscles = new Muscle[muscles.Length - (muscle.childIndexes.Length + 1)];
            int      index      = GetMuscleIndex(muscle.joint);
            int      added      = 0;

            for (int i = 0; i < muscles.Length; i++)
            {
                if (i != index && !muscles[index].childFlags[i])
                {
                    newMuscles[added] = muscles[i];
                    added++;
                }
                else
                {
                    muscles[i].transform.gameObject.SetActive(false);
                }
            }
            muscles = newMuscles;

            //UpdateHierarchies();
        }
예제 #14
0
        // Builds muscles
        private void SetUpMuscles(Transform setUpTo)
        {
            // Auto-detect targets
            ConfigurableJoint[] joints = transform.GetComponentsInChildren <ConfigurableJoint>();

            if (joints.Length == 0)
            {
                Debug.LogWarning("No ConfigurableJoints found, can not build PuppetMaster. Please create ConfigurableJoints to connect the ragdoll bones together.", transform);
                return;
            }

            var animator = targetRoot.GetComponentInChildren <Animator>();

            Transform[] children = setUpTo.GetComponentsInChildren <Transform>();

            muscles = new Muscle[joints.Length];
            int hipIndex = -1;

            for (int i = 0; i < joints.Length; i++)
            {
                muscles[i]       = new Muscle();
                muscles[i].joint = joints[i];
                muscles[i].name  = joints[i].name;
                muscles[i].props = new Muscle.Props(1f, 1f, 1f, 1f, muscles[i].joint.connectedBody == null);
                if (muscles[i].joint.connectedBody == null && hipIndex == -1)
                {
                    hipIndex = i;
                }

                foreach (Transform c in children)
                {
                    if (c.name == joints[i].name)
                    {
                        muscles[i].target = c;
                        if (animator != null)
                        {
                            muscles[i].props.group = FindGroup(animator, muscles[i].target);

                            if (muscles[i].props.group == Muscle.Group.Hips || muscles[i].props.group == Muscle.Group.Leg || muscles[i].props.group == Muscle.Group.Foot)
                            {
                                muscles[i].props.mapPosition = true;
                            }
                        }
                        break;
                    }
                }
            }

            // The hip muscle is not first in hierarchy
            if (hipIndex != 0)
            {
                var firstMuscle = muscles[0];
                var hipMuscle   = muscles[hipIndex];
                muscles[hipIndex] = firstMuscle;
                muscles[0]        = hipMuscle;
            }

            bool allSameGroup = true;

            foreach (Muscle m in muscles)
            {
                if (m.target == null)
                {
                    Debug.LogWarning("No target Transform found for PuppetMaster muscle " + m.joint.name + ". Please assign manually.", transform);
                }

                if (m.props.group != muscles[0].props.group)
                {
                    allSameGroup = false;
                }
            }

            if (allSameGroup)
            {
                Debug.LogWarning("Muscle groups need to be assigned in the PuppetMaster!", transform);
            }
        }
예제 #15
0
        /// <summary>
        /// NB! Make sure to call this from FixedUpdate!
        /// Creates a new muscle for the specified "joint" and targets it to the "target". The joint will be connected to the specified "connectTo" Muscle.
        /// Note that the joint will be binded to it's current position and rotation relative to the "connectTo", so make sure the added object is positioned correctly when calling this.
        /// This method allocates memory, avoid using it each frame.
        /// </summary>
        public void AddMuscle(ConfigurableJoint joint, Transform target, Rigidbody connectTo, Transform targetParent, Muscle.Props muscleProps = null, bool forceTreeHierarchy = false, bool forceLayers = true)
        {
            if (!CheckIfInitiated())
            {
                return;
            }

            if (!initiated)
            {
                Debug.LogWarning("PuppetMaster has not been initiated.", transform);
                return;
            }

            if (ContainsJoint(joint))
            {
                Debug.LogWarning("Joint " + joint.name + " is already used by a Muscle", transform);
                return;
            }

            if (target == null)
            {
                Debug.LogWarning("AddMuscle was called with a null 'target' reference.", transform);
                return;
            }

            if (connectTo == joint.GetComponent <Rigidbody>())
            {
                Debug.LogWarning("ConnectTo is the joint's own Rigidbody, can not add muscle.", transform);
                return;
            }

            if (!isActive)
            {
                Debug.LogWarning("Adding muscles to inactive PuppetMasters is not currently supported.", transform);
                return;
            }

            if (muscleProps == null)
            {
                muscleProps = new Muscle.Props();
            }

            Muscle muscle = new Muscle();

            muscle.props  = muscleProps;
            muscle.joint  = joint;
            muscle.target = target;
            muscle.joint.transform.parent = (hierarchyIsFlat || connectTo == null) && !forceTreeHierarchy? transform: connectTo.transform;

            if (forceLayers)
            {
                joint.gameObject.layer  = gameObject.layer;                //@todo what if collider is on a child gameobject?
                target.gameObject.layer = targetRoot.gameObject.layer;
            }

            if (connectTo != null)
            {
                muscle.target.parent = targetParent;

                Vector3    relativePosition = GetMuscle(connectTo).transform.InverseTransformPoint(muscle.target.position);
                Quaternion relativeRotation = Quaternion.Inverse(GetMuscle(connectTo).transform.rotation) * muscle.target.rotation;

                joint.transform.position = connectTo.transform.TransformPoint(relativePosition);
                joint.transform.rotation = connectTo.transform.rotation * relativeRotation;

                joint.connectedBody = connectTo;
            }

            muscle.Initiate(muscles);

            if (connectTo != null)
            {
                muscle.rigidbody.velocity        = connectTo.velocity;
                muscle.rigidbody.angularVelocity = connectTo.angularVelocity;
            }

            // Ignore internal collisions
            if (!internalCollisions)
            {
                for (int i = 0; i < muscles.Length; i++)
                {
                    muscle.IgnoreCollisions(muscles[i], true);
                }
            }

            Array.Resize(ref muscles, muscles.Length + 1);
            muscles[muscles.Length - 1] = muscle;

            // Update angular limit ignoring
            muscle.IgnoreAngularLimits(!angularLimits);

            if (behaviours.Length > 0)
            {
                muscle.broadcaster = muscle.joint.gameObject.AddComponent <MuscleCollisionBroadcaster>();
                muscle.broadcaster.puppetMaster = this;
                muscle.broadcaster.muscleIndex  = muscles.Length - 1;
            }

            muscle.jointBreakBroadcaster = muscle.joint.gameObject.AddComponent <JointBreakBroadcaster>();
            muscle.jointBreakBroadcaster.puppetMaster = this;
            muscle.jointBreakBroadcaster.muscleIndex  = muscles.Length - 1;

            UpdateHierarchies();
            CheckMassVariation(100f, true);

            foreach (BehaviourBase b in behaviours)
            {
                b.OnMuscleAdded(muscle);
            }
        }
예제 #16
0
        /// <summary>
        /// Removes the muscle with the specified joint and all muscles connected to it from PuppetMaster management. This will not destroy the body part/prop, but just release it from following the target.
        /// If you call RemoveMuscleRecursive on an upper arm muscle, the entire arm will be disconnected from the rest of the body.
        /// </summary>
        /// <param name="joint">The joint of the muscle (and the muscles connected to it) to remove.</param>
        /// <param name="attachTarget">If set to <c>true</c> , the target Transform of the first muscle will be parented to the disconnected limb.</param>
        /// <param name="blockTargetAnimation">If set to <c>true</c>, will add AnimationBlocker.cs to the removed target bones. That will override animation that would otherwise still be writing on those bones.</param>
        /// <param name="removeMode">Remove mode. Sever cuts the body part by disconnecting the first joint. Explode explodes the body part disconnecting all joints. Numb removes the muscles from PuppetMaster management, keeps the joints connected and disables spring and damper forces.</param>
        public void RemoveMuscleRecursive(ConfigurableJoint joint, bool attachTarget, bool blockTargetAnimation = false, MuscleRemoveMode removeMode = MuscleRemoveMode.Sever)
        {
            if (!CheckIfInitiated())
            {
                return;
            }

            if (joint == null)
            {
                Debug.LogWarning("RemoveMuscleRecursive was called with a null 'joint' reference.", transform);
                return;
            }

            if (!ContainsJoint(joint))
            {
                Debug.LogWarning("No Muscle with the specified joint was found, can not remove muscle.", transform);
                return;
            }

            int index = GetMuscleIndex(joint);

            Muscle[] newMuscles = new Muscle[muscles.Length - (muscles[index].childIndexes.Length + 1)];

            int added = 0;

            for (int i = 0; i < muscles.Length; i++)
            {
                if (i != index && !muscles[index].childFlags[i])
                {
                    newMuscles[added] = muscles[i];
                    added++;
                }
                else
                {
                    if (muscles[i].broadcaster != null)
                    {
                        muscles[i].broadcaster.enabled = false;
                        Destroy(muscles[i].broadcaster);
                    }
                    if (muscles[i].jointBreakBroadcaster != null)
                    {
                        muscles[i].jointBreakBroadcaster.enabled = false;
                        Destroy(muscles[i].jointBreakBroadcaster);
                    }
                }
            }

            switch (removeMode)
            {
            case MuscleRemoveMode.Sever:
                DisconnectJoint(muscles[index].joint);

                for (int i = 0; i < muscles[index].childIndexes.Length; i++)
                {
                    KillJoint(muscles[muscles[index].childIndexes[i]].joint);
                }
                break;

            case MuscleRemoveMode.Explode:
                DisconnectJoint(muscles[index].joint);

                for (int i = 0; i < muscles[index].childIndexes.Length; i++)
                {
                    DisconnectJoint(muscles[muscles[index].childIndexes[i]].joint);
                }
                break;

            case MuscleRemoveMode.Numb:
                KillJoint(muscles[index].joint);

                for (int i = 0; i < muscles[index].childIndexes.Length; i++)
                {
                    KillJoint(muscles[muscles[index].childIndexes[i]].joint);
                }
                break;
            }

            muscles[index].transform.parent = null;

            for (int i = 0; i < muscles[index].childIndexes.Length; i++)
            {
                if (removeMode == MuscleRemoveMode.Explode || muscles[muscles[index].childIndexes[i]].transform.parent == transform)
                {
                    muscles[muscles[index].childIndexes[i]].transform.parent = null;
                }
            }


            foreach (BehaviourBase b in behaviours)
            {
                b.OnMuscleRemoved(muscles[index]);

                for (int i = 0; i < muscles[index].childIndexes.Length; i++)
                {
                    var c = muscles[muscles[index].childIndexes[i]];
                    b.OnMuscleRemoved(c);
                }
            }

            if (attachTarget)
            {
                muscles[index].target.parent   = muscles[index].transform;
                muscles[index].target.position = muscles[index].transform.position;
                muscles[index].target.rotation = muscles[index].transform.rotation * muscles[index].targetRotationRelative;

                for (int i = 0; i < muscles[index].childIndexes.Length; i++)
                {
                    var c = muscles[muscles[index].childIndexes[i]];
                    c.target.parent   = c.transform;
                    c.target.position = c.transform.position;
                    c.target.rotation = c.transform.rotation;
                }
            }

            if (blockTargetAnimation)
            {
                muscles[index].target.gameObject.AddComponent <AnimationBlocker>();

                for (int i = 0; i < muscles[index].childIndexes.Length; i++)
                {
                    var c = muscles[muscles[index].childIndexes[i]];
                    c.target.gameObject.AddComponent <AnimationBlocker>();
                }
            }

            if (OnMuscleRemoved != null)
            {
                OnMuscleRemoved(muscles[index]);
            }
            for (int i = 0; i < muscles[index].childIndexes.Length; i++)
            {
                var c = muscles[muscles[index].childIndexes[i]];
                if (OnMuscleRemoved != null)
                {
                    OnMuscleRemoved(c);
                }
            }

            // Enable collisions between the new muscles and the removed colliders
            if (!internalCollisionsEnabled)
            {
                foreach (Muscle newMuscle in newMuscles)
                {
                    foreach (Collider newMuscleCollider in newMuscle.colliders)
                    {
                        foreach (Collider removedMuscleCollider in muscles[index].colliders)
                        {
                            Physics.IgnoreCollision(newMuscleCollider, removedMuscleCollider, false);
                        }

                        for (int childMuscleIndex = 0; childMuscleIndex < muscles[index].childIndexes.Length; childMuscleIndex++)
                        {
                            foreach (Collider childMuscleCollider in muscles[childMuscleIndex].colliders)
                            {
                                Physics.IgnoreCollision(newMuscleCollider, childMuscleCollider, false);
                            }
                        }
                    }
                }
            }

            muscles = newMuscles;

            UpdateHierarchies();
        }
예제 #17
0
        private void ReconnectMuscle(Muscle m)
        {
            m.state.isDisconnected = false;

            if (activeState != State.Frozen && !m.isPropMuscle)
            {
                m.target.position = m.targetAnimatedPosition;
                m.target.rotation = m.targetAnimatedWorldRotation;
            }

            if (m != muscles[0])
            {
                m.joint.xMotion = ConfigurableJointMotion.Locked;
                m.joint.yMotion = ConfigurableJointMotion.Locked;
                m.joint.zMotion = ConfigurableJointMotion.Locked;

                if (!hierarchyIsFlat && m.joint.connectedBody != null)
                {
                    m.transform.parent = m.joint.connectedBody.transform;
                }
            }

            bool disable = false;

            if (m.joint.connectedBody != null && !m.joint.connectedBody.gameObject.activeInHierarchy)
            {
                disable = true;
            }
            if (m.joint.connectedBody == null)
            {
                if (activeMode == Mode.Disabled || activeState == State.Frozen)
                {
                    disable = true;
                }
            }

            if (disable)
            {
                m.joint.gameObject.SetActive(false);
            }
            else
            {
                if (!m.joint.gameObject.activeInHierarchy || m.state.resetFlag)
                {
                    m.Reset();
                    m.joint.gameObject.SetActive(true);
                }
                else
                {
                    if (activeState != State.Frozen)
                    {
                        m.MoveToTarget();
                    }
                }
            }

            if (activeMode == Mode.Kinematic)
            {
                m.SetKinematic(true);
            }

            if (activeState == State.Dead)
            {
                m.ResetTargetLocalPosition();
                m.SetMuscleRotation(muscleWeight * stateSettings.deadMuscleWeight, muscleSpring, muscleDamper + stateSettings.deadMuscleDamper);
            }

            m.state.resetFlag = false;
            m.ClearVelocities();

            m.state.pinWeightMlp     = 1;
            m.state.muscleWeightMlp  = 1;
            m.state.muscleDamperMlp  = 1;
            m.state.maxForceMlp      = 1;
            m.state.mappingWeightMlp = 1f;

            UpdateInternalCollisions(m);
            m.IgnoreAngularLimits(!angularLimits);

            foreach (BehaviourBase b in behaviours)
            {
                b.OnMuscleReconnected(m);
            }
            if (OnMuscleReconnected != null)
            {
                OnMuscleReconnected(m);
            }
        }
예제 #18
0
        /// <summary>
        /// Removes the muscle with the specified joint and all muscles connected to it from PuppetMaster management. This will not destroy the body part/prop, but just release it from following the target.
        /// If you call RemoveMuscleRecursive on an upper arm muscle, the entire arm will be disconnected from the rest of the body.
        /// If attachTarget is true, the target Transform of the first muscle will be parented to the disconnected limb.
        /// This method allocates some memory, avoid using it each frame.
        /// </summary>
        public void RemoveMuscleRecursive(ConfigurableJoint joint, bool attachTarget)
        {
            if (!CheckIfInitiated())
            {
                return;
            }

            if (joint == null)
            {
                Debug.LogWarning("RemoveMuscleRecursive was called with a null 'joint' reference.", transform);
                return;
            }

            if (!ContainsJoint(joint))
            {
                Debug.LogWarning("No Muscle with the specified joint was found, can not remove muscle.", transform);
                return;
            }

            int index = GetMuscleIndex(joint);

            Muscle[] newMuscles = new Muscle[muscles.Length - (muscles[index].childIndexes.Length + 1)];

            int added = 0;

            for (int i = 0; i < muscles.Length; i++)
            {
                if (i != index && !muscles[index].childFlags[i])
                {
                    newMuscles[added] = muscles[i];
                    added++;
                }
                else
                {
                    if (muscles[i].broadcaster != null)
                    {
                        Destroy(muscles[i].broadcaster);
                    }
                }
            }

            muscles[index].joint.connectedBody = null;

            muscles[index].joint.targetRotation = Quaternion.identity;
            JointDrive j = new JointDrive();

            j.positionSpring = 0f;
                        #if UNITY_5_2
            j.mode = JointDriveMode.None;
                        #endif
            muscles[index].joint.slerpDrive     = j;
            muscles[index].joint.xMotion        = ConfigurableJointMotion.Free;
            muscles[index].joint.yMotion        = ConfigurableJointMotion.Free;
            muscles[index].joint.zMotion        = ConfigurableJointMotion.Free;
            muscles[index].joint.angularXMotion = ConfigurableJointMotion.Free;
            muscles[index].joint.angularYMotion = ConfigurableJointMotion.Free;
            muscles[index].joint.angularZMotion = ConfigurableJointMotion.Free;

            muscles[index].transform.parent = null;

            if (attachTarget)
            {
                muscles[index].target.parent   = muscles[index].transform;
                muscles[index].target.position = muscles[index].transform.position;
                muscles[index].target.rotation = muscles[index].transform.rotation * muscles[index].targetRotationRelative;
            }

            muscles = newMuscles;

            UpdateHierarchies();
        }
예제 #19
0
        private void DisconnectMuscle(Muscle m, bool sever, bool deactivate)
        {
            m.state.pinWeightMlp     = 0f;
            m.state.muscleWeightMlp  = 0f;
            m.state.muscleDamperAdd  = 0f;
            m.state.muscleDamperMlp  = 0f;
            m.state.mappingWeightMlp = 0f;
            m.state.maxForceMlp      = 0f;
            m.state.immunity         = 0f;
            m.state.impulseMlp       = 1f;

            if (sever)
            {
                m.joint.xMotion = ConfigurableJointMotion.Free;
                m.joint.yMotion = ConfigurableJointMotion.Free;
                m.joint.zMotion = ConfigurableJointMotion.Free;

                m.IgnoreAngularLimits(true);

                if (!hierarchyIsFlat)
                {
                    m.joint.transform.parent = transform;
                }
            }
            else
            {
                m.IgnoreAngularLimits(false);
            }

            bool applyMappedVelocity = !m.joint.gameObject.activeInHierarchy || m.rigidbody.isKinematic;

            if (activeState == State.Frozen)
            {
                applyMappedVelocity = false;
            }

            // In case disconnecting in disabled mode
            if (!m.joint.gameObject.activeInHierarchy && !deactivate)
            {
                m.MoveToTarget();
                m.joint.gameObject.SetActive(true);
            }

            m.SetKinematic(false);
            JointDrive slerpDrive = new JointDrive();

            slerpDrive.positionSpring = 0f;
            slerpDrive.maximumForce   = 0f;
            slerpDrive.positionDamper = 0f;
            m.joint.slerpDrive        = slerpDrive;

            // Enable internal collisions with the disconnected muscle
            if (!deactivate)
            {
                for (int i = 0; i < muscles.Length; i++)
                {
                    if (muscles[i] != m && !muscles[i].state.isDisconnected)
                    {
                        foreach (Collider c1 in m.colliders)
                        {
                            foreach (Collider c2 in muscles[i].colliders)
                            {
                                if (c1.enabled && c2.enabled)
                                {
                                    Physics.IgnoreCollision(c1, c2, false);
                                }
                            }
                        }
                    }
                }

                if (applyMappedVelocity)
                {
                    m.rigidbody.velocity        = m.mappedVelocity;
                    m.rigidbody.angularVelocity = m.mappedAngularVelocity;
                }
            }
            else
            {
                m.joint.gameObject.SetActive(false);
            }

            if (m.isPropMuscle)
            {
                var propMuscle = m.joint.GetComponent <PropMuscle>();
                if (propMuscle.activeProp != null)
                {
                    propMuscle.currentProp = null;
                }
            }

            m.state.isDisconnected = true;

            foreach (BehaviourBase b in behaviours)
            {
                b.OnMuscleDisconnected(m);
            }
            if (OnMuscleDisconnected != null)
            {
                OnMuscleDisconnected(m);
            }
        }
예제 #20
0
        public override void OnMuscleRemoved(Muscle m)
        {
            base.OnMuscleRemoved(m);

            SetColliders(m, true);
        }
예제 #21
0
        // 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;
        }
예제 #22
0
        public override void OnMuscleAdded(Muscle m)
        {
            base.OnMuscleAdded(m);

            SetColliders(m, state == State.Unpinned);
        }
예제 #23
0
 public virtual void OnMuscleAdded(Muscle m)
 {
 }
예제 #24
0
        public override void OnMuscleDisconnected(Muscle m)
        {
            base.OnMuscleDisconnected(m);

            SetColliders(m, true);
        }
예제 #25
0
 public virtual void OnMuscleRemoved(Muscle m)
 {
 }
예제 #26
0
 public virtual void OnMuscleReconnected(Muscle m)
 {
 }