254 lines
8.7 KiB
C#
254 lines
8.7 KiB
C#
using UnityEngine;
|
|
using System.Collections;
|
|
using UnityEngine.Events;
|
|
using System.Collections.Generic;
|
|
|
|
namespace MoreMountains.Tools
|
|
{
|
|
/// <summary>
|
|
/// Add this component to an object and it'll be auto destroyed X seconds after its Start()
|
|
/// </summary>
|
|
[AddComponentMenu("More Mountains/Tools/Activation/MMTimedActivation")]
|
|
public class MMTimedActivation : MonoBehaviour
|
|
{
|
|
/// the possible activation modes
|
|
public enum TimedStatusChange { Enable, Disable, Destroy }
|
|
/// the possible trigger modes
|
|
public enum ActivationModes { Awake, Start, OnEnable, OnTriggerEnter, OnTriggerExit, OnTriggerEnter2D, OnTriggerExit2D, Script }
|
|
/// the possible ways to check if the collider matches
|
|
public enum TriggerModes { None, Tag, Layer }
|
|
/// the possible delay modes
|
|
public enum DelayModes { Time, Frames }
|
|
|
|
[Header("Trigger Mode")]
|
|
/// the moment you want the countdown to state change to start
|
|
public ActivationModes ActivationMode = ActivationModes.Start;
|
|
/// the target layer for activation if using OnTriggerEnter or OnTriggerExit
|
|
[MMEnumCondition("ActivationMode", (int)ActivationModes.OnTriggerEnter, (int)ActivationModes.OnTriggerExit)]
|
|
public TriggerModes TriggerMode;
|
|
/// the layer the target collider should be on
|
|
[MMEnumCondition("TriggerMode", (int)TriggerModes.Layer)]
|
|
public LayerMask TargetTriggerLayer;
|
|
/// the tag the target collider should have
|
|
[MMEnumCondition("TriggerMode", (int)TriggerModes.Tag)]
|
|
public string TargetTriggerTag;
|
|
|
|
|
|
|
|
[Header("Delay")]
|
|
/// the chosen delay mode, whether to wait in seconds or frames
|
|
public DelayModes DelayMode = DelayModes.Time;
|
|
/// The time (in seconds) before we destroy the object
|
|
[MMEnumCondition("DelayMode", (int)DelayModes.Time)]
|
|
public float TimeBeforeStateChange = 2;
|
|
/// the amount of frames to wait for when in Frames DelayMode
|
|
[MMEnumCondition("DelayMode", (int)DelayModes.Frames)]
|
|
public int FrameCount = 1;
|
|
|
|
[Header("Timed Activation")]
|
|
/// the possible targets you want the state to change
|
|
public List<GameObject> TargetGameObjects;
|
|
/// the possible targets you want the state to change
|
|
public List<MonoBehaviour> TargetBehaviours;
|
|
/// the destruction mode for this object : destroy or disable
|
|
public TimedStatusChange TimeDestructionMode = TimedStatusChange.Disable;
|
|
|
|
[Header("Actions")]
|
|
/// Unity events to trigger after the delay
|
|
public UnityEvent TimedActions;
|
|
|
|
/// <summary>
|
|
/// On awake, initialize our delay and trigger our change state countdown if needed
|
|
/// </summary>
|
|
protected virtual void Awake()
|
|
{
|
|
if (ActivationMode == ActivationModes.Awake)
|
|
{
|
|
StartChangeState();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Call this method to start the countdown to activation
|
|
/// </summary>
|
|
public virtual void TriggerSequence()
|
|
{
|
|
StartChangeState();
|
|
}
|
|
|
|
/// <summary>
|
|
/// On start, trigger our change state countdown if needed
|
|
/// </summary>
|
|
protected virtual void Start()
|
|
{
|
|
if (ActivationMode == ActivationModes.Start)
|
|
{
|
|
StartChangeState();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// On enable, trigger our change state countdown if needed
|
|
/// </summary>
|
|
protected virtual void OnEnable()
|
|
{
|
|
if (ActivationMode == ActivationModes.Start)
|
|
{
|
|
StartChangeState();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// On trigger enter, we start our countdown if needed
|
|
/// </summary>
|
|
/// <param name="collider"></param>
|
|
protected virtual void OnTriggerEnter(Collider collider)
|
|
{
|
|
if ((ActivationMode == ActivationModes.OnTriggerEnter) && (CorrectTagOrLayer(collider.gameObject)))
|
|
{
|
|
StartChangeState();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// On trigger exit, we start our countdown if needed
|
|
/// </summary>
|
|
/// <param name="collider"></param>
|
|
protected virtual void OnTriggerExit(Collider collider)
|
|
{
|
|
if ((ActivationMode == ActivationModes.OnTriggerEnter) && (CorrectTagOrLayer(collider.gameObject)))
|
|
{
|
|
StartChangeState();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// On trigger enter 2D, we start our countdown if needed
|
|
/// </summary>
|
|
/// <param name="collider"></param>
|
|
protected virtual void OnTriggerEnter2d(Collider2D collider)
|
|
{
|
|
if ((ActivationMode == ActivationModes.OnTriggerEnter) && (CorrectTagOrLayer(collider.gameObject)))
|
|
{
|
|
StartChangeState();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// On trigger exit 2D, we start our countdown if needed
|
|
/// </summary>
|
|
/// <param name="collider"></param>
|
|
protected virtual void OnTriggerExit2d(Collider2D collider)
|
|
{
|
|
if ((ActivationMode == ActivationModes.OnTriggerEnter) && (CorrectTagOrLayer(collider.gameObject)))
|
|
{
|
|
StartChangeState();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if the target matches our settings, false otherwise
|
|
/// </summary>
|
|
/// <param name="target"></param>
|
|
/// <returns></returns>
|
|
protected virtual bool CorrectTagOrLayer(GameObject target)
|
|
{
|
|
switch (TriggerMode)
|
|
{
|
|
case TriggerModes.None:
|
|
return true;
|
|
case TriggerModes.Layer:
|
|
if (((1 << target.layer) & TargetTriggerLayer) != 0)
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
case TriggerModes.Tag:
|
|
return (target.CompareTag(TargetTriggerTag));
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// On start change state, starts the timed activation
|
|
/// </summary>
|
|
protected virtual void StartChangeState()
|
|
{
|
|
StartCoroutine(TimedActivationSequence());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Waits and triggers state change and events
|
|
/// </summary>
|
|
protected virtual IEnumerator TimedActivationSequence()
|
|
{
|
|
if (DelayMode == DelayModes.Time)
|
|
{
|
|
yield return MMCoroutine.WaitFor(TimeBeforeStateChange);
|
|
}
|
|
else
|
|
{
|
|
yield return StartCoroutine(MMCoroutine.WaitForFrames(FrameCount));
|
|
}
|
|
StateChange();
|
|
Activate();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Triggers actions if needed
|
|
/// </summary>
|
|
protected virtual void Activate()
|
|
{
|
|
if (TimedActions != null)
|
|
{
|
|
TimedActions.Invoke();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Changes the object's status or destroys it
|
|
/// </summary>
|
|
protected virtual void StateChange()
|
|
{
|
|
foreach(GameObject targetGameObject in TargetGameObjects)
|
|
{
|
|
switch (TimeDestructionMode)
|
|
{
|
|
case TimedStatusChange.Destroy:
|
|
Destroy(targetGameObject);
|
|
break;
|
|
|
|
case TimedStatusChange.Disable:
|
|
targetGameObject.SetActive(false);
|
|
break;
|
|
|
|
case TimedStatusChange.Enable:
|
|
targetGameObject.SetActive(true);
|
|
break;
|
|
}
|
|
}
|
|
|
|
foreach (MonoBehaviour targetBehaviour in TargetBehaviours)
|
|
{
|
|
switch (TimeDestructionMode)
|
|
{
|
|
case TimedStatusChange.Destroy:
|
|
Destroy(targetBehaviour);
|
|
break;
|
|
|
|
case TimedStatusChange.Disable:
|
|
targetBehaviour.enabled = false;
|
|
break;
|
|
|
|
case TimedStatusChange.Enable:
|
|
targetBehaviour.enabled = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|