Last active
September 8, 2023 22:30
-
-
Save nonathaj/08c2cb38f6c53417c963 to your computer and use it in GitHub Desktop.
Unity Event System for Designers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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--; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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