private void OnDisconnectMuscleRecursive(int index, MuscleDisconnectMode disconnectMode = MuscleDisconnectMode.Sever, bool deactivate = false) { // Reset flags if (!muscles[index].joint.gameObject.activeInHierarchy || deactivate) { muscles[index].state.resetFlag = true; } for (int i = 0; i < muscles[index].childIndexes.Length; i++) { int childIndex = muscles[index].childIndexes[i]; if (!muscles[childIndex].joint.gameObject.activeInHierarchy || deactivate) { muscles[childIndex].state.resetFlag = true; } } // Disconnect individual muscles DisconnectMuscle(muscles[index], true, deactivate); for (int i = 0; i < muscles[index].childIndexes.Length; i++) { int childIndex = muscles[index].childIndexes[i]; bool alreadyDone = disconnectMode == MuscleDisconnectMode.Sever && muscles[childIndex].state.isDisconnected; if (disconnectMode == MuscleDisconnectMode.Explode && muscles[childIndex].joint.xMotion != ConfigurableJointMotion.Free) { alreadyDone = false; } if (!alreadyDone) { DisconnectMuscle(muscles[childIndex], disconnectMode == MuscleDisconnectMode.Explode, deactivate); } } // Disconnect the last muscle too if all others removed if (!muscles[0].state.isDisconnected) { bool lastMuscle = true; for (int i = 1; i < muscles.Length; i++) { if (!muscles[i].state.isDisconnected) { lastMuscle = false; break; } if (lastMuscle) { DisconnectMuscleRecursive(0, MuscleDisconnectMode.Sever); } } } }
/// <summary> /// Disconnects muscle from index. In Sever mode, the muscle and it's children will be disconnected in one piece (cutting limb off). In Explode mode the muscle and all it's children will be cut off. If Deactivate is true, the disconnected muscle GameObjects will be deactivated. /// </summary> public void DisconnectMuscleRecursive(int index, MuscleDisconnectMode disconnectMode = MuscleDisconnectMode.Sever, bool deactivate = false) { if (index < 0 || index >= muscles.Length) { Debug.LogError("PuppetMaster.DisconnectMuscleRecursive() called with out of range index: " + index, transform); return; } disconnectMuscleFlags[index] = true; muscleDisconnectModes[index] = disconnectMode; disconnectDeactivateFlags[index] = deactivate; }
// Update is called once per frame void Update() { // Switching modes if (Input.GetKeyDown(KeyCode.M)) { if (disconnectMuscleMode == MuscleDisconnectMode.Sever) { disconnectMuscleMode = MuscleDisconnectMode.Explode; } else { disconnectMuscleMode = MuscleDisconnectMode.Sever; } } // Pick up prop if (Input.GetKeyDown(KeyCode.P)) { propMuscle.currentProp = prop; // If skeleton is dead, need to resurrect it, as attaching prop also reconnects all parent muscles if (puppet.puppetMaster.muscles[0].state.isDisconnected) { skeleton.OnRebuild(); } } // Drop prop if (Input.GetKeyDown(KeyCode.D)) { propMuscle.currentProp = null; } // Shooting if (Input.GetMouseButtonDown(0)) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // Raycast to find a ragdoll collider RaycastHit hit = new RaycastHit(); if (Physics.Raycast(ray, out hit, 100f, layers)) { var broadcaster = hit.collider.attachedRigidbody.GetComponent <MuscleCollisionBroadcaster>(); // If is a muscle... if (broadcaster != null) { broadcaster.Hit(unpin, ray.direction * force, hit.point); // Remove the muscle and its children broadcaster.puppetMaster.DisconnectMuscleRecursive(broadcaster.muscleIndex, disconnectMuscleMode); } else { // Add force hit.collider.attachedRigidbody.AddForceAtPosition(ray.direction * force, hit.point); } // Particle FX particles.transform.position = hit.point; particles.transform.rotation = Quaternion.LookRotation(-ray.direction); particles.Emit(5); } } // Reattach all the missing muscles if (Input.GetKeyDown(KeyCode.R)) { puppet.puppetMaster.ReconnectMuscleRecursive(0); skeleton.OnRebuild(); } }