using UnityEngine; using System.Collections; using System.Collections.Generic; namespace RootMotion.Dynamics { /// /// All the required information when a muscle collides with something. /// public struct MuscleCollision { /// /// The index of the colliding muscle in the PuppetMaster.muscles array. /// public int muscleIndex; /// /// The collision from OnCollisionEnter/Stay/Exit. /// public Collision collision; public bool isStay; public MuscleCollision(int muscleIndex, Collision collision, bool isStay = false) { this.muscleIndex = muscleIndex; this.collision = collision; this.isStay = isStay; } } /// /// Hitting muscles via code, usually by raycasting. /// public struct MuscleHit { /// /// The index of the colliding muscle in the PuppetMaster.muscles array. /// public int muscleIndex; /// /// How much should the muscle be unpinned by the hit? /// public float unPin; /// /// The force to add to the muscle's Rigidbody. /// public Vector3 force; /// /// The world space hit point. /// public Vector3 position; public MuscleHit(int muscleIndex, float unPin, Vector3 force, Vector3 position) { this.muscleIndex = muscleIndex; this.unPin = unPin; this.force = force; this.position = position; } } /// /// Filters and broadcasts collisions with the Muscles to the Puppet Behaviours. /// [AddComponentMenu("Scripts/RootMotion.Dynamics/PuppetMaster/Muscle Collision Broadcaster")] public class MuscleCollisionBroadcaster : MonoBehaviour { /// /// The PuppetMaster that this muscle belongs to. /// [HideInInspector] public PuppetMaster puppetMaster; /// /// The index of this muscle in the PuppetMaster.muscles array. /// [HideInInspector] public int muscleIndex; private const string onMuscleHit = "OnMuscleHit"; private const string onMuscleCollision = "OnMuscleCollision"; private const string onMuscleCollisionExit = "OnMuscleCollisionExit"; private MuscleCollisionBroadcaster otherBroadcaster; public void Hit(float unPin, Vector3 force, Vector3 position) { if (!enabled) return; foreach (BehaviourBase behaviour in puppetMaster.behaviours) { behaviour.OnMuscleHit(new MuscleHit(muscleIndex, unPin, force, position)); } } // Prevents processing internal collisions. private bool IsSelf(Collider c) { //return c.transform.root == transform.root; // Might be faster, but make sure characters are not stacked to the same root! return c.transform.IsChildOf(puppetMaster.transform); // Use this if you need all your puppets to be parented to a single container gameobject. } void OnCollisionEnter(Collision collision) { if (!enabled) return; if (puppetMaster == null) return; if (IsSelf(collision.collider)) return; if (puppetMaster.muscles[muscleIndex].state.isDisconnected) return; foreach (BehaviourBase behaviour in puppetMaster.behaviours) { behaviour.OnMuscleCollision(new MuscleCollision(muscleIndex, collision)); } } void OnCollisionStay(Collision collision) { if (!enabled) return; if (puppetMaster == null) return; if (PuppetMasterSettings.instance != null && !PuppetMasterSettings.instance.collisionStayMessages) return; if (IsSelf(collision.collider)) return; if (puppetMaster.muscles[muscleIndex].state.isDisconnected) return; foreach (BehaviourBase behaviour in puppetMaster.behaviours) { behaviour.OnMuscleCollision(new MuscleCollision(muscleIndex, collision, true)); } } void OnCollisionExit(Collision collision) { if (!enabled) return; if (puppetMaster == null) return; if (PuppetMasterSettings.instance != null && !PuppetMasterSettings.instance.collisionExitMessages) return; if (IsSelf(collision.collider)) return; if (puppetMaster.muscles[muscleIndex].state.isDisconnected) return; foreach (BehaviourBase behaviour in puppetMaster.behaviours) { behaviour.OnMuscleCollisionExit(new MuscleCollision(muscleIndex, collision)); } } } }