Skip to content

Instantly share code, notes, and snippets.

@nonathaj
Last active September 8, 2023 22:30
Show Gist options
  • Save nonathaj/08c2cb38f6c53417c963 to your computer and use it in GitHub Desktop.
Save nonathaj/08c2cb38f6c53417c963 to your computer and use it in GitHub Desktop.
Unity Event System for Designers
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
/*
Event class for catching Unity Message Events that are sent to the GameObject's attached components.
Events that are captured here are sent from the GameObjectHelper class
*/
[AddComponentMenu("Event/Catch Event")]
public class CatchEvent : MonoBehaviour
{
[SerializeField]
string message;
public string Message { get { return message; } set { message = value; } }
[SerializeField]
UnityEvent onMessageReceived;
public UnityEvent OnMessageReceived { get { return onMessageReceived; } }
public void CatchMessage(string message)
{
if (message == Message)
OnMessageReceived.Invoke();
}
}
using UnityEngine;
using System.Collections;
using UnityEngine.Events;
/*
Count Event component
This event is used to trigger an event when a count reaches a certain number.
*/
[AddComponentMenu("Event/Counter Event")]
public class CountEvent : MonoBehaviour
{
[SerializeField, Tooltip("What is the starting count, and the current count during gameplay.")]
int count = 0;
public int Count {
get { return count; }
set {
count = value;
#if UNITY_EDITOR
if (!Application.isPlaying)
return;
#endif
OnCountChanged.Invoke(count);
if (count == EndCount)
{
OnCountEnd.Invoke(count);
if (ResetOnEnd)
count = 0;
}
}
}
[SerializeField, Tooltip("At what count do we fire this event?")]
int endCount = 0;
public int EndCount { get { return endCount; } set { endCount = value; } }
[SerializeField, Tooltip("Does the counter reset to 0 after firing an event?")]
bool resetOnEnd = false;
public bool ResetOnEnd { get { return resetOnEnd; } set { resetOnEnd = value; } }
[System.Serializable] public class IntEvent : UnityEvent<int> { }
[SerializeField, Tooltip("Called when the count changes")]
IntEvent onCountChanged;
public IntEvent OnCountChanged { get { return onCountChanged; } }
[SerializeField, Tooltip("Called when the count reaches the end count")]
IntEvent onCountEnd;
public IntEvent OnCountEnd { get { return onCountEnd; } }
public void Increment() { Count++; }
public void Decrement() { Count--; }
}
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
/*
Event that is used to add a delay between its trigger, and an event firing.
There are optional other trigger functions, including:
TriggerImmmediate - Fires the event with no delay.
TriggerImmediateAlways - Fires the event with no delay, event if the script is disabled.
*/
[AddComponentMenu("Event/Delay Event")]
public class DelayEvent : MonoBehaviour
{
[SerializeField, Tooltip("Should this event be triggered once before the first frame of this object?")]
bool triggerOnStart = false;
public bool TriggerOnStart { get { return triggerOnStart; } set { triggerOnStart = value; } }
[SerializeField, Tooltip("Number of seconds after Trigger is called that the DelayedEvent is called")]
float delaySeconds;
public float DelaySeconds { get { return delaySeconds; } set { delaySeconds = value; } }
[SerializeField, Tooltip("Called Delay Seconds after Trigger is called.")]
UnityEvent delayedEvent;
public UnityEvent DelayedEvent { get { return delayedEvent; } }
public void Trigger()
{
#if UNITY_EDITOR
if (!Application.isPlaying)
return;
#endif
if (!enabled || !gameObject.activeInHierarchy)
return;
this.InvokeAfter(delegate () { DelayedEvent.Invoke(); }, DelaySeconds);
}
public void TriggerImmediate()
{
#if UNITY_EDITOR
if (!Application.isPlaying)
return;
#endif
if (!enabled || !gameObject.activeInHierarchy)
return;
DelayedEvent.Invoke();
}
public void TriggerImmediateAlways()
{
#if UNITY_EDITOR
if (!Application.isPlaying)
return;
#endif
DelayedEvent.Invoke();
}
void Start()
{
if (TriggerOnStart)
Trigger();
}
}
using UnityEngine;
using System.Collections;
/*
A class that exposes helper functions for manipulating gameobjects, and their transforms. It also exposes many static Unity functions for editing in the other events.
*/
[AddComponentMenu("Event/Game Object Helper")]
public class GameObjectHelper : MonoBehaviour
{
///
/// GameObject options
///
public void DestroyGameObject() { Object.Destroy(gameObject); }
new public void Destroy(Object obj) { Object.Destroy(obj); }
public void DestroyRootGameObject(Object o)
{
GameObject go = MonoExtensions.GetGameObject(o);
if (go != null)
Destroy(go.transform.root.gameObject);
}
public void DestroyGameObject(Object o)
{
GameObject go = MonoExtensions.GetGameObject(o);
if(go != null)
Destroy(go);
}
///
/// Transform Options
///
public void SetPostion(Transform t) { transform.position = t.position; }
public void SetRotation(Transform t) { transform.rotation = t.rotation; }
public void SetLocalScale(Transform scale) { transform.localScale = transform.localScale; }
public void RotateLocalX(float degrees) { RotateLocal(new Vector3(degrees, 0f, 0f)); }
public void RotateLocalY(float degrees) { RotateLocal(new Vector3(0f, degrees, 0f)); }
public void RotateLocalZ(float degrees) { RotateLocal(new Vector3(0f, 0f, degrees)); }
public void RotateLocal(Vector3 degrees) { transform.Rotate(degrees, Space.Self); }
public void RotateWorldX(float degrees) { RotateWorld(new Vector3(degrees, 0f, 0f)); }
public void RotateWorldY(float degrees) { RotateWorld(new Vector3(0f, degrees, 0f)); }
public void RotateWorldZ(float degrees) { RotateWorld(new Vector3(0f, 0f, degrees)); }
public void RotateWorld(Vector3 degrees) { transform.Rotate(degrees, Space.World); }
public void MoveLocalX(float move) { MoveLocal(new Vector3(move, 0f, 0f)); }
public void MoveLocalY(float move) { MoveLocal(new Vector3(0f, move, 0f)); }
public void MoveLocalZ(float move) { MoveLocal(new Vector3(0f, 0f, move)); }
public void MoveLocal(Vector3 move) { transform.Translate(move, Space.Self); }
public void MoveWorldX(float move) { MoveWorld(new Vector3(move, 0f, 0f)); }
public void MoveWorldY(float move) { MoveWorld(new Vector3(0f, move, 0f)); }
public void MoveWorldZ(float move) { MoveWorld(new Vector3(0f, 0f, move)); }
public void MoveWorld(Vector3 move) { transform.Translate(move, Space.World); }
public void SetRotationLocalX(float rotation) { SetRotationLocal(new Vector3(rotation, 0f, 0f)); }
public void SetRotationLocalY(float rotation) { SetRotationLocal(new Vector3(0f, rotation, 0f)); }
public void SetRotationLocalZ(float rotation) { SetRotationLocal(new Vector3(0f, 0f, rotation)); }
public void SetRotationLocal(Vector3 euler) { transform.localEulerAngles = euler; }
public void SetRotationLocal(Quaternion rot) { transform.localRotation = rot; }
public void SetRotationWorldX(float rotation) { SetRotationWorld(new Vector3(rotation, 0f, 0f)); }
public void SetRotationWorldY(float rotation) { SetRotationWorld(new Vector3(0f, rotation, 0f)); }
public void SetRotationWorldZ(float rotation) { SetRotationWorld(new Vector3(0f, 0f, rotation)); }
public void SetRotationWorld(Vector3 euler) { transform.eulerAngles = euler; }
public void SetRotationWorld(Quaternion rot) { transform.rotation = rot; }
public void SetPositionLocalX(float position) { SetPositionLocal(new Vector3(position, 0f, 0f)); }
public void SetPositionLocalY(float position) { SetPositionLocal(new Vector3(0f, position, 0f)); }
public void SetPositionLocalZ(float position) { SetPositionLocal(new Vector3(0f, 0f, position)); }
public void SetPositionLocal(Vector3 pos) { transform.localPosition = pos; }
public void SetPositionWorldX(float position) { transform.position = new Vector3(position, 0f, 0f); }
public void SetPositionWorldY(float position) { transform.position = new Vector3(0f, position, 0f); }
public void SetPositionWorldZ(float position) { transform.position = new Vector3(0f, 0f, position); }
public void SetPositionWorld(Vector3 pos) { transform.position = pos; }
public void SetParentWorldPosStays(Transform newParent) { transform.SetParent(newParent, true); }
public void SetParentLocalPosStays(Transform newParent) { transform.SetParent(newParent, false); }
public void LookAtAndKeepUp(Transform toLookAt) { transform.LookAt(toLookAt, transform.up); }
public void DetachChildren() { transform.DetachChildren(); }
///
/// Event messages for CatchEvent
///
public void SendEventHere(string message) { SendMessage("CatchMessage", message, SendMessageOptions.DontRequireReceiver); }
public void SendEventHereAndParents(string message) { SendMessageUpwards("CatchMessage", message, SendMessageOptions.DontRequireReceiver); }
public void SendEventHereAndChildren(string message) { BroadcastMessage("CatchMessage", message, SendMessageOptions.DontRequireReceiver); }
public void GlobalEventInvoke(string eventName) { GlobalEventManager.Instance.Invoke(eventName); }
public void GlobalEventRemoveAllListeners(string eventName) { GlobalEventManager.Instance.RemoveAllListeners(eventName); }
///
/// Generating objects from Resources folder.
///
public void CreateFromResources(string resourcesDirectory)
{
GameObject prefab = Resources.Load<GameObject>(resourcesDirectory);
if(prefab != null)
Instantiate<GameObject>(prefab);
}
public void CreateChildFromResources(string resourcesDirectory)
{
GameObject prefab = Resources.Load<GameObject>(resourcesDirectory);
GameObject go = prefab != null ? Instantiate<GameObject>(prefab) : null;
if(go != null)
go.transform.SetParent(transform);
}
///
/// Debug Options
///
public void DebugBreak() { Debug.Break(); }
public void DebugLog(string log) { Debug.Log(log); }
public void DebugLogWarning(string warning) { Debug.LogWarning(warning); }
public void DebugLogError(string error) { Debug.LogError(error); }
///
/// Cursor Options
///
public void CursorVisible(bool visible) { Cursor.visible = visible; }
public void CursorModeConfined() { Cursor.lockState = CursorLockMode.Confined; }
public void CursorModeLocked() { Cursor.lockState = CursorLockMode.Locked; }
public void CursorModeNormal() { Cursor.lockState = CursorLockMode.None; }
public void SetTimeScale(float newTimescale) { Time.timeScale = newTimescale; }
///
/// Application Options
///
public void ApplicationOpenURL(string url) { Application.OpenURL(url); }
public void ApplicationQuit() { Application.Quit(); }
public void ApplicationLoadLevel(string levelName) { Application.LoadLevel(levelName); }
public void ApplicationLoadLevel(int levelId) { Application.LoadLevel(levelId); }
}
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
/*
Event class for generating prefabs from events.
*/
[AddComponentMenu("Event/Prefab Generator")]
public class Generator : MonoBehaviour
{
[SerializeField]
GameObject prefab;
[System.Serializable] public class GenerateEvent : UnityEvent<GameObject> { }
[SerializeField, Tooltip("Called when this generator creates an object")]
GenerateEvent onGenerate;
public GenerateEvent OnGenerate { get { return onGenerate; } }
//This is here so designers can disable the generator with the checkbox in the inspector
void Start() { }
public void Generate()
{
#if UNITY_EDITOR
if (!Application.isPlaying)
return;
#endif
if (!enabled)
return;
TryGenerate();
}
public void GenerateAlways()
{
#if UNITY_EDITOR
if (!Application.isPlaying)
return;
#endif
TryGenerate();
}
private void TryGenerate()
{
if (prefab == null)
{
Debug.LogWarning("Prefab is NOT set in Generator on " + name);
return;
}
OnGenerate.Invoke((GameObject)Instantiate(prefab, transform.position, transform.rotation));
}
}
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
/*
Listener for our global events, that are fired from the GlobalEventManager
*/
[AddComponentMenu("Event/Global Message Listener Event")]
public class GlobalEvent : MonoBehaviour
{
[SerializeField, Tooltip("What Global Event are we listening for?")]
string eventName;
public string EventName {
get { return eventName; }
set {
UnRegister();
eventName = value;
Register();
}
}
[SerializeField, Tooltip("Called when the Global event is triggered, and this script is enabled.")]
UnityEvent onGlobalEvent;
public UnityEvent OnGlobalEvent { get { return onGlobalEvent; } }
void Awake()
{
Register();
}
void OnDestroy()
{
UnRegister();
}
public void Register()
{
GlobalEventManager.Instance.AddListener(EventName, Trigger);
}
public void UnRegister()
{
if(GlobalEventManager.InstanceExists)
GlobalEventManager.Instance.RemoveListener(EventName, Trigger);
}
void Trigger()
{
if(enabled)
OnGlobalEvent.Invoke();
}
}
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
using System.Collections.Generic;
/*
Global Event messaging system for sending messages throughout the game.
Should probably expand this to accept parameters too.
*/
[UnitySingleton(UnitySingletonAttribute.Type.CreateOnNewGameObject, false)]
public class GlobalEventManager : UnitySingleton<GlobalEventManager>
{
Dictionary<string, UnityEvent> events = new Dictionary<string, UnityEvent>();
UnityEvent GetEvent(string eventName)
{
if (!events.ContainsKey(eventName))
events.Add(eventName, new UnityEvent());
return events[eventName];
}
public void AddListener(string eventName, UnityAction action)
{
GetEvent(eventName).AddListener(action);
}
public void RemoveListener(string eventName, UnityAction action)
{
GetEvent(eventName).RemoveListener(action);
if (GetEvent(eventName).GetPersistentEventCount() == 0)
events.Remove(eventName);
}
public void RemoveAllListeners(string eventName)
{
GetEvent(eventName).RemoveAllListeners();
events.Remove(eventName);
}
public void Invoke(string eventName)
{
GetEvent(eventName).Invoke();
}
}
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
/*
Event that happens regularly over some defined interval
*/
[AddComponentMenu("Event/Event Interval")]
public class IntervalEvent : MonoBehaviour
{
public enum UpdateType
{
Update,
FixedUpdate,
LateUpdate,
Seconds
}
[SerializeField, Tooltip("What kind of update loop should this interval run on?")]
UpdateType updateEvery = UpdateType.Seconds;
public UpdateType UpdateEvery { get { return updateEvery; } set { updateEvery = value; } }
private bool UpdateEverySeconds() { return UpdateEvery == UpdateType.Seconds; }
[SerializeField, Tooltip("Number of seconds between calling this event for the Seconds Update Type")]
float intervalSeconds = 1f;
[SerializeField, Tooltip("Called before the first frame and every Interval Seconds after")]
UnityEvent onIntervalEvent;
public UnityEvent OnIntervalEvent { get { return onIntervalEvent; } }
public bool Running { get; private set; }
void Awake()
{
Running = false;
}
void OnEnable()
{
if (!Running)
StartCoroutine("IntervalCoroutine");
}
void OnDisable()
{
if (Running)
{
StopCoroutine("IntervalCoroutine");
Running = false;
}
}
void Update()
{
if (UpdateEvery == UpdateType.Update)
OnIntervalEvent.Invoke();
}
void FixedUpdate()
{
if (UpdateEvery == UpdateType.FixedUpdate)
OnIntervalEvent.Invoke();
}
void LateUpdate()
{
if (UpdateEvery == UpdateType.LateUpdate)
OnIntervalEvent.Invoke();
}
IEnumerator IntervalCoroutine()
{
Running = true;
while (true)
{
while(UpdateEvery == UpdateType.Seconds)
{
OnIntervalEvent.Invoke();
yield return new WaitForSeconds(intervalSeconds);
}
yield return null; //stops the infinite loop from locking up the interval event
}
}
}
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
/*
Event that exposes specific MonoBehaviour messages to the editor.
*/
[AddComponentMenu("Event/Event MonoBehaviour")]
public class MonoBehaviourEvent : MonoBehaviour
{
[SerializeField, Tooltip("This function is always called before any Start functions and also just after a prefab is instantiated. (If a GameObject is inactive during start up Awake is not called until it is made active, or a function in any script attached to it is called.)")]
UnityEvent onAwake;
public UnityEvent OnAwake { get { return onAwake; } }
[SerializeField, Tooltip("Start is called before the first frame update only if the script instance is enabled.")]
UnityEvent onStart;
public UnityEvent OnStart { get { return onStart; } }
[SerializeField, Tooltip("(only called if the Object is active): This function is called just after the object is enabled. This happens when a MonoBehaviour instance is created, such as when a level is loaded or a GameObject with the script component is instantiated.")]
UnityEvent onEnable;
public UnityEvent OnEnableEvent { get { return onEnable; } }
[SerializeField, Tooltip("This function is called when the behaviour becomes disabled or inactive.")]
UnityEvent onDisable;
public UnityEvent OnDisableEvent { get { return onDisable; } }
[SerializeField, Tooltip("This function is called after all frame updates for the last frame of the object’s existence (the object might be destroyed in response to Object.Destroy or at the closure of a scene).")]
UnityEvent onDestroy;
public UnityEvent OnDestroyEvent { get { return onDestroy; } }
void Awake()
{
OnAwake.Invoke();
}
void Start()
{
OnStart.Invoke();
}
void OnEnable()
{
OnEnableEvent.Invoke();
}
void OnDisable()
{
OnDisableEvent.Invoke();
}
void OnDestroy()
{
OnDestroyEvent.Invoke();
}
}
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
using System.Collections.Generic;
using System;
public static class MonoExtensions
{
///Calls an action on the next frame
public static void InvokeNextFrame(this MonoBehaviour mb, UnityAction action)
{
mb.InvokeAfter(action, null);
}
///Calls an action at the end of the frame
public static void InvokeEndOfFrame(this MonoBehaviour mb, UnityAction action)
{
mb.InvokeAfter(action, new WaitForEndOfFrame());
}
///Calls an action at the next FixedUpdate
public static void InvokeFixedUpdate(this MonoBehaviour mb, UnityAction action)
{
mb.InvokeAfter(action, new WaitForFixedUpdate());
}
///Calls an action after a seconds within the given range of (fromSeconds, toSeconds)
public static void InvokeAfterRandom(this MonoBehaviour mb, UnityAction action, float fromSeconds, float toSeconds)
{
mb.InvokeAfter(action, UnityEngine.Random.Range(fromSeconds, toSeconds));
}
//Calls an action after a given amount of seconds
public static void InvokeAfter(this MonoBehaviour mb, UnityAction action, float seconds)
{
mb.InvokeAfter(action, new WaitForSeconds(seconds));
}
//Calls an action after a yield instruction has completed
public static void InvokeAfter(this MonoBehaviour mb, UnityAction action, YieldInstruction yieldInstruction)
{
mb.StartCoroutine(WaitBefore(yieldInstruction, action));
}
//Coroutine that waits for the yield instruction to complete, then calls an action
public static IEnumerator WaitBefore(YieldInstruction ins, UnityAction action)
{
yield return ins;
action.Invoke();
}
//Repeats an action every frame starting on the next frame
public static void InvokeFrameRepeat(this MonoBehaviour mb, UnityAction action, uint numTimes)
{
mb.StartCoroutine(RepeatCount(null, action, numTimes));
}
//Repeats an action forever with a number of seconds between each call
public static void InvokeRepeatForeverSeconds(this MonoBehaviour mb, UnityAction action, float secondsBetween)
{
mb.StartCoroutine(RepeatForever(new WaitForSeconds(secondsBetween), action));
}
public static IEnumerator RepeatCount(YieldInstruction ins, UnityAction action, uint numTimes)
{
for(uint x = 0; x < numTimes; x++)
{
yield return ins;
action.Invoke();
}
}
public static void InvokeFrameRepeatForever(this MonoBehaviour mb, UnityAction action)
{
mb.StartCoroutine(RepeatForever(null, action));
}
public static IEnumerator RepeatForever(YieldInstruction ins, UnityAction action)
{
while(true)
{
yield return ins;
action.Invoke();
}
}
public static void InvokeWhenTrue<T>(this MonoBehaviour mb, T source, System.Func<T, bool> boolSelector, UnityAction action)
{
mb.StartCoroutine(WaitForValue(null, source, boolSelector, true, null, action));
}
public static void InvokeWhenFalse<T>(this MonoBehaviour mb, T source, System.Func<T, bool> boolSelector, UnityAction action)
{
mb.StartCoroutine(WaitForValue(null, source, boolSelector, false, null, action));
}
public static IEnumerator WaitForValue<T, K>(YieldInstruction waitTicker, T source, System.Func<T, K> selector, K desiredVal, UnityAction tick, UnityAction finished) where K : System.IComparable
{
while(selector(source).CompareTo(desiredVal) != 0)
{
yield return waitTicker;
if (tick != null)
tick.Invoke();
}
if (finished != null)
finished.Invoke();
}
//Extension for monobehaviour and all other components that allow you to get/add a component to/from it's gameobject
public static T GetOrAddComponent<T>(this Component c) where T : Component
{
T item = c.GetComponent<T>();
if(item == null)
item = c.gameObject.AddComponent<T>();
return item;
}
public static T GetOrAddComponent<T>(this GameObject g) where T : Component
{
return g.transform.GetOrAddComponent<T>();
}
public static IEnumerable<T> GetComponentFromBranches<T>(this GameObject g) where T : Component
{
return g.transform.GetComponentFromBranches<T>();
}
/// <summary>
/// Returns an enumerable list of components from the first found on each branch of the transform tree.
/// Includes the object the component was called from
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="c"></param>
/// <returns></returns>
public static IEnumerable<T> GetComponentFromBranches<T>(this Component c) where T : Component
{
List<T> list = new List<T>();
c.transform.GetComponentsOnBranch<T>(ref list);
return list;
}
/// <summary>
/// Returns an enumerable list of components from the first found on each branch of the transform tree.
/// Does NOT include the object the component was called from
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="c"></param>
/// <returns></returns>
public static IEnumerable<T> GetComponentFromChildBranches<T>(this Component c) where T : Component
{
List<T> list = new List<T>();
foreach (Transform child in c.transform)
GetComponentsOnBranch<T>(child, ref list);
return list;
}
private static void GetComponentsOnBranch<T>(this Transform t, ref List<T> list) where T : Component
{
T item = t.GetComponent<T>();
if (item != null)
{
list.Add(item);
return;
}
foreach (Transform child in t)
GetComponentsOnBranch<T>(child, ref list);
}
public static T GetInterface<T>(this Component comp) where T : class
{
if (!typeof(T).IsInterface)
{
Debug.LogError(typeof(T).ToString() + ": is not an actual interface!");
return null;
}
return comp.GetComponent(typeof(T)) as T;
}
public static T GetInterface<T>(this GameObject inObj) where T : class
{
if (!typeof(T).IsInterface)
{
Debug.LogError(typeof(T).ToString() + ": is not an actual interface!");
return null;
}
return inObj.transform.GetInterface<T>();
}
public static IEnumerable<T> GetInterfaces<T>(this GameObject inObj) where T : class
{
if (!typeof(T).IsInterface)
{
Debug.LogError(typeof(T).ToString() + ": is not an actual interface!");
return null;
}
return inObj.GetComponents(typeof(T)) as T[];
}
public static T[] GetInterfacesInChildren<T>(this Component c) where T : class
{
if (!typeof(T).IsInterface)
{
Debug.LogError(typeof(T).Name + " is not an interface.");
return null;
}
Component[] comps = c.GetComponentsInChildren(typeof(T));
T[] arr = new T[comps.Length];
for (int x = 0; x < comps.Length; x++)
arr[x] = comps[x] as T;
return arr;
}
public static T GetComponentFromTreeBase<T>(this Component c) where T : Component
{
return c.transform.root.GetComponentInChildren<T>();
}
public static void Enable(bool enabled, params Behaviour[] comps)
{
Array.ForEach(comps, c => {
if(c != null)
c.enabled = enabled;
});
}
public static void SetActive(bool enabled, params GameObject[] gos)
{
Array.ForEach(gos, go => {
if(go != null)
go.SetActive(enabled);
});
}
public static void SetPosition(this GameObject go, Vector3 pos)
{
go.transform.position = pos;
}
}
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
/*
Playable Event component.
This event has 2 states, play and stop.
Recommended use would be turning things on and off with the two different states (e.g. turn on a light while this event is playing).
This event must be manually stopped by default, however can be configured to automatically stop after a given amount of seconds (if the SecondsToAutoStop is > 0).
If the gameobject this script is attached to is disabled before stop is called using the auto-stop, it will NOT be auto-stopped. (This is due to the nature of how coroutines are connected to gameobjects)
*/
[AddComponentMenu("Event/Playable Event")]
public class PlayableEvent : MonoBehaviour
{
[SerializeField, Tooltip("How many seconds until this playable automatically stops? 0 will never auto stop.")]
float secondsToAutoStop = 0f;
public float SecondsToAutoStop { get { return secondsToAutoStop; } set { secondsToAutoStop = value; } }
[SerializeField, Tooltip("Called when this playable begins playing?")]
UnityEvent onPlay;
public UnityEvent OnPlay { get { return onPlay; } }
[SerializeField, Tooltip("Called when this playable stops playing?")]
UnityEvent onStop;
public UnityEvent OnStop { get { return onStop; } }
public bool Playing { get; private set; } //is this event in the playing state? False is in the stopped state.
public void Play()
{
#if UNITY_EDITOR
if (!Application.isPlaying)
return;
#endif
Playing = true;
OnPlay.Invoke();
if (secondsToAutoStop > 0)
this.InvokeAfter(Stop, secondsToAutoStop);
}
public void Stop()
{
#if UNITY_EDITOR
if (!Application.isPlaying)
return;
#endif
Playing = false;
OnStop.Invoke();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment