| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- #if !UNITY_2019_3_OR_NEWER
- #define CINEMACHINE_PHYSICS
- #define CINEMACHINE_PHYSICS_2D
- #endif
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.Events;
- using UnityEngine.Playables;
- namespace Cinemachine
- {
- #if !(CINEMACHINE_PHYSICS || CINEMACHINE_PHYSICS_2D)
- // Workaround for Unity scripting bug
- [AddComponentMenu("")] // Hide in menu
- public class CinemachineTriggerAction : MonoBehaviour {}
- #else
- /// <summary>
- /// A multi-purpose script which causes an action to occur when
- /// a trigger collider is entered and exited.
- /// </summary>
- [DocumentationSorting(DocumentationSortingAttribute.Level.UserRef)]
- [SaveDuringPlay]
- [HelpURL(Documentation.BaseURL + "api/Cinemachine.CinemachineTriggerAction.html")]
- public class CinemachineTriggerAction : MonoBehaviour
- {
- /// <summary>Only triggers generated by objects on these layers will be considered.</summary>
- [Header("Trigger Object Filter")]
- [Tooltip("Only triggers generated by objects on these layers will be considered")]
- public LayerMask m_LayerMask = 1;
- /// <summary>If set, only triggers generated by objects with this tag will be considered</summary>
- [TagField]
- [Tooltip("If set, only triggers generated by objects with this tag will be considered")]
- public string m_WithTag = string.Empty;
- /// <summary>Triggers generated by objects with this tag will be ignored</summary>
- [TagField]
- [Tooltip("Triggers generated by objects with this tag will be ignored")]
- public string m_WithoutTag = string.Empty;
- /// <summary>Skip this many trigger entries before taking action</summary>
- [NoSaveDuringPlay]
- [Tooltip("Skip this many trigger entries before taking action")]
- public int m_SkipFirst = 0;
- /// <summary>Repeat the action for all subsequent trigger entries</summary>
- [Tooltip("Repeat the action for all subsequent trigger entries")]
- public bool m_Repeating = true;
- /// <summary>Defines what action to take on trigger enter/exit</summary>
- [Serializable]
- public struct ActionSettings
- {
- /// <summary>What action to take</summary>
- public enum Mode
- {
- /// <summary>Use the event only</summary>
- Custom,
- /// <summary>Boost priority of virtual camera target</summary>
- PriorityBoost,
- /// <summary>Activate the target GameObject</summary>
- Activate,
- /// <summary>Decativate target GameObject</summary>
- Deactivate,
- /// <summary>Enable a component</summary>
- Enable,
- /// <summary>Disable a component</summary>
- Disable,
- /// <summary>Start animation on target</summary>
- Play,
- /// <summary>Stop animation on target</summary>
- Stop
- }
- /// <summary>Serializable parameterless game event</summary>
- [Serializable] public class TriggerEvent : UnityEvent {}
- /// <summary>What action to take</summary>
- [Tooltip("What action to take")]
- public Mode m_Action;
- /// <summary>The target object on which to operate. If null, then the current behaviour/GameObject will be used</summary>
- [Tooltip("The target object on which to operate. If null, then the current behaviour/GameObject will be used")]
- public UnityEngine.Object m_Target;
- /// <summary>If PriorityBoost, this amount will be added to the virtual camera's priority</summary>
- [Tooltip("If PriorityBoost, this amount will be added to the virtual camera's priority")]
- public int m_BoostAmount;
- /// <summary>If playing a timeline, start at this time</summary>
- [Tooltip("If playing a timeline, start at this time")]
- public float m_StartTime;
- /// <summary>How to interpret the start time</summary>
- public enum TimeMode { FromStart, FromEnd, BeforeNow, AfterNow };
- /// <summary>How to interpret the start time</summary>
- [Tooltip("How to interpret the start time")]
- public TimeMode m_Mode;
- /// <summary>This event will be invoked</summary>
- [Tooltip("This event will be invoked")]
- public TriggerEvent m_Event;
- /// <summary>Constructor</summary>
- public ActionSettings(Mode action)
- {
- m_Action = action;
- m_Target = null;
- m_BoostAmount = 0;
- m_StartTime = 0;
- m_Mode = TimeMode.FromStart;
- m_Event = new TriggerEvent();
- }
- /// <summary>Invoke the action. Depending on the mode, different action will
- /// be performed. The embedded event will always be invoked, in addition to the
- /// action specified by the Mode.</summary>
- public void Invoke()
- {
- UnityEngine.Object currentTarget = m_Target;
- if (currentTarget != null)
- {
- GameObject targetGameObject = currentTarget as GameObject;
- Behaviour targetBehaviour = currentTarget as Behaviour;
- if (targetBehaviour != null)
- targetGameObject = targetBehaviour.gameObject;
- switch (m_Action)
- {
- case Mode.Custom:
- break;
- case Mode.PriorityBoost:
- {
- CinemachineVirtualCameraBase vcam
- = targetGameObject.GetComponent<CinemachineVirtualCameraBase>();
- if (vcam != null)
- {
- vcam.Priority += m_BoostAmount;
- vcam.MoveToTopOfPrioritySubqueue();
- }
- break;
- }
- case Mode.Activate:
- if (targetGameObject != null)
- {
- targetGameObject.SetActive(true);
- CinemachineVirtualCameraBase vcam
- = targetGameObject.GetComponent<CinemachineVirtualCameraBase>();
- if (vcam != null)
- vcam.MoveToTopOfPrioritySubqueue();
- }
- break;
- case Mode.Deactivate:
- if (targetGameObject != null)
- targetGameObject.SetActive(false);
- break;
- case Mode.Enable:
- {
- if (targetBehaviour != null)
- targetBehaviour.enabled = true;
- break;
- }
- case Mode.Disable:
- {
- if (targetBehaviour != null)
- targetBehaviour.enabled = false;
- break;
- }
- case Mode.Play:
- {
- PlayableDirector playable
- = targetGameObject.GetComponent<PlayableDirector>();
- if (playable != null)
- {
- double startTime = 0;
- double duration = playable.duration;
- double current = playable.time;
- switch (m_Mode)
- {
- default:
- case TimeMode.FromStart:
- startTime += m_StartTime;
- break;
- case TimeMode.FromEnd:
- startTime = duration - m_StartTime;
- break;
- case TimeMode.BeforeNow:
- startTime = current - m_StartTime;
- break;
- case TimeMode.AfterNow:
- startTime = current + m_StartTime;
- break;
- }
- playable.time = startTime;
- playable.Play();
- }
- else
- {
- Animation ani = targetGameObject.GetComponent<Animation>();
- if (ani != null)
- ani.Play();
- }
- break;
- }
- case Mode.Stop:
- {
- PlayableDirector playable
- = targetGameObject.GetComponent<PlayableDirector>();
- if (playable != null)
- playable.Stop();
- else
- {
- Animation ani = targetGameObject.GetComponent<Animation>();
- if (ani != null)
- ani.Stop();
- }
- break;
- }
- }
- }
- m_Event.Invoke();
- }
- }
- /// <summary>What action to take when an eligible object enters the collider or trigger zone</summary>
- public ActionSettings m_OnObjectEnter = new ActionSettings(ActionSettings.Mode.Custom);
- /// <summary>What action to take when an eligible object exits the collider or trigger zone</summary>
- public ActionSettings m_OnObjectExit = new ActionSettings(ActionSettings.Mode.Custom);
- HashSet<GameObject> m_ActiveTriggerObjects = new HashSet<GameObject>();
- private bool Filter(GameObject other)
- {
- if (!enabled)
- return false;
- if (((1 << other.layer) & m_LayerMask) == 0)
- return false;
- if (m_WithTag.Length != 0 && !other.CompareTag(m_WithTag))
- return false;
- if (m_WithoutTag.Length != 0 && other.CompareTag(m_WithoutTag))
- return false;
- return true;
- }
- void InternalDoTriggerEnter(GameObject other)
- {
- if (!Filter(other))
- return;
- --m_SkipFirst;
- if (m_SkipFirst > -1)
- return;
- if (!m_Repeating && m_SkipFirst != -1)
- return;
- m_ActiveTriggerObjects.Add(other);
- m_OnObjectEnter.Invoke();
- }
- void InternalDoTriggerExit(GameObject other)
- {
- if (!m_ActiveTriggerObjects.Contains(other))
- return;
- m_ActiveTriggerObjects.Remove(other);
- if (enabled)
- m_OnObjectExit.Invoke();
- }
- #if CINEMACHINE_PHYSICS
- void OnTriggerEnter(Collider other) { InternalDoTriggerEnter(other.gameObject); }
- void OnTriggerExit(Collider other) { InternalDoTriggerExit(other.gameObject); }
- void OnCollisionEnter(Collision other) { InternalDoTriggerEnter(other.gameObject); }
- void OnCollisionExit(Collision other) { InternalDoTriggerExit(other.gameObject); }
- #endif
- #if CINEMACHINE_PHYSICS_2D
- void OnTriggerEnter2D(Collider2D other) { InternalDoTriggerEnter(other.gameObject); }
- void OnTriggerExit2D(Collider2D other) { InternalDoTriggerExit(other.gameObject); }
- void OnCollisionEnter2D(Collision2D other) { InternalDoTriggerEnter(other.gameObject); }
- void OnCollisionExit2D(Collision2D other) { InternalDoTriggerExit(other.gameObject); }
- #endif
- void OnEnable() {} // For the Enabled checkbox
- }
- #endif
- }
|