| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- #if !UNITY_2019_3_OR_NEWER
- #define CINEMACHINE_PHYSICS
- #define CINEMACHINE_PHYSICS_2D
- #endif
- using Cinemachine.Utility;
- using UnityEngine;
- namespace Cinemachine
- {
- #if !(CINEMACHINE_PHYSICS || CINEMACHINE_PHYSICS_2D)
- // Workaround for Unity scripting bug
- [AddComponentMenu("")] // Hide in menu
- public class CinemachineCollisionImpulseSource : CinemachineImpulseSource {}
- #else
- /// <summary>
- /// Generate an Impulse Event this object's Collider collides with something
- /// or its trigger zone is entered.
- ///
- /// This component should be attached to a GameObject with a Collider or a Collider2D.
- /// Objects colliding with this (or entering its trigger zone if it's a trigger) will be
- /// filtered according to the layer and tag settings defined here, and if they
- /// pass the filter, they will cause an impulse event to be generated.
- /// </summary>
- [DocumentationSorting(DocumentationSortingAttribute.Level.UserRef)]
- [SaveDuringPlay]
- [HelpURL(Documentation.BaseURL + "manual/CinemachineCollisionImpulseSource.html")]
- public class CinemachineCollisionImpulseSource : CinemachineImpulseSource
- {
- /// <summary>Only collisions with objects on these layers will generate Impulse events.</summary>
- [Header("Trigger Object Filter")]
- [Tooltip("Only collisions with objects on these layers will generate Impulse events")]
- public LayerMask m_LayerMask = 1;
- /// <summary>No Impulse evemts will be generated for collisions with objects having these tags</summary>
- [TagField]
- [Tooltip("No Impulse evemts will be generated for collisions with objects having these tags")]
- public string m_IgnoreTag = string.Empty;
- /// <summary>If checked, signal direction will be affected by the direction of impact</summary>
- [Header("How To Generate The Impulse")]
- [Tooltip("If checked, signal direction will be affected by the direction of impact")]
- public bool m_UseImpactDirection = false;
- /// <summary>If checked, signal amplitude will be multiplied by the mass of the impacting object</summary>
- [Tooltip("If checked, signal amplitude will be multiplied by the mass of the impacting object")]
- public bool m_ScaleImpactWithMass = false;
- /// <summary>If checked, signal amplitude will be multiplied by the speed of the impacting object</summary>
- [Tooltip("If checked, signal amplitude will be multiplied by the speed of the impacting object")]
- public bool m_ScaleImpactWithSpeed = false;
- #if CINEMACHINE_PHYSICS
- Rigidbody mRigidBody;
- #endif
- #if CINEMACHINE_PHYSICS_2D
- Rigidbody2D mRigidBody2D;
- #endif
- private void Start()
- {
- #if CINEMACHINE_PHYSICS
- mRigidBody = GetComponent<Rigidbody>();
- #endif
- #if CINEMACHINE_PHYSICS_2D
- mRigidBody2D = GetComponent<Rigidbody2D>();
- #endif
- }
- private void OnEnable() {} // For the Enabled checkbox
- #if CINEMACHINE_PHYSICS
- private void OnCollisionEnter(Collision c)
- {
- GenerateImpactEvent(c.collider, c.relativeVelocity);
- }
- private void OnTriggerEnter(Collider c)
- {
- GenerateImpactEvent(c, Vector3.zero);
- }
- private float GetMassAndVelocity(Collider other, ref Vector3 vel)
- {
- bool getVelocity = vel == Vector3.zero;
- float mass = 1;
- if (m_ScaleImpactWithMass || m_ScaleImpactWithSpeed || m_UseImpactDirection)
- {
- if (mRigidBody != null)
- {
- if (m_ScaleImpactWithMass)
- mass *= mRigidBody.mass;
- if (getVelocity)
- vel = -mRigidBody.velocity;
- }
- var rb = other != null ? other.attachedRigidbody : null;
- if (rb != null)
- {
- if (m_ScaleImpactWithMass)
- mass *= rb.mass;
- if (getVelocity)
- vel += rb.velocity;
- }
- }
- return mass;
- }
- private void GenerateImpactEvent(Collider other, Vector3 vel)
- {
- // Check the filters
- if (!enabled)
- return;
- if (other != null)
- {
- int layer = other.gameObject.layer;
- if (((1 << layer) & m_LayerMask) == 0)
- return;
- if (m_IgnoreTag.Length != 0 && other.CompareTag(m_IgnoreTag))
- return;
- }
- // Calculate the signal direction and magnitude
- float mass = GetMassAndVelocity(other, ref vel);
- if (m_ScaleImpactWithSpeed)
- mass *= vel.magnitude;
- Vector3 dir = Vector3.down;
- if (m_UseImpactDirection && !vel.AlmostZero())
- dir = -vel.normalized;
- // Fire it off!
- GenerateImpulse(dir * mass);
- }
- #endif
- #if CINEMACHINE_PHYSICS_2D
- private void OnCollisionEnter2D(Collision2D c)
- {
- GenerateImpactEvent2D(c.collider, c.relativeVelocity);
- }
- private void OnTriggerEnter2D(Collider2D c)
- {
- GenerateImpactEvent2D(c, Vector3.zero);
- }
- private float GetMassAndVelocity2D(Collider2D other2d, ref Vector3 vel)
- {
- bool getVelocity = vel == Vector3.zero;
- float mass = 1;
- if (m_ScaleImpactWithMass || m_ScaleImpactWithSpeed || m_UseImpactDirection)
- {
- if (mRigidBody2D != null)
- {
- if (m_ScaleImpactWithMass)
- mass *= mRigidBody2D.mass;
- if (getVelocity)
- vel = -mRigidBody2D.velocity;
- }
- var rb2d = other2d != null ? other2d.attachedRigidbody : null;
- if (rb2d != null)
- {
- if (m_ScaleImpactWithMass)
- mass *= rb2d.mass;
- if (getVelocity)
- {
- Vector3 v = rb2d.velocity;
- vel += v;
- }
- }
- }
- return mass;
- }
- private void GenerateImpactEvent2D(Collider2D other2d, Vector3 vel)
- {
- // Check the filters
- if (!enabled)
- return;
- if (other2d != null)
- {
- int layer = other2d.gameObject.layer;
- if (((1 << layer) & m_LayerMask) == 0)
- return;
- if (m_IgnoreTag.Length != 0 && other2d.CompareTag(m_IgnoreTag))
- return;
- }
- // Calculate the signal direction and magnitude
- float mass = GetMassAndVelocity2D(other2d, ref vel);
- if (m_ScaleImpactWithSpeed)
- mass *= vel.magnitude;
- Vector3 dir = Vector3.down;
- if (m_UseImpactDirection && !vel.AlmostZero())
- dir = -vel.normalized;
- // Fire it off!
- GenerateImpulse(dir * mass);
- }
- #endif
- }
- #endif
- }
|