示例#1
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);
            }
        }
示例#2
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);
            }
        }
示例#3
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);
            }
        }