// 将 直接把现有的 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; }
/// <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); } }