Advertisement
mvaganov

Trigger.cs

Feb 15th, 2018
278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 15.92 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.SceneManagement;
  5.  
  6. // author: mvaganov@hotmail.com
  7. // license: Copyfree, public domain. This is free code! Great artists, steal this code!
  8. // latest version at: https://pastebin.com/raw/8cZ5yKSd
  9. // requires Timer at: https://pastebin.com/raw/h61nAC3E
  10. namespace NS {
  11.     public class Trigger : TriggerBase {
  12.         public float delayInSeconds = 0;
  13.         [Tooltip("* Transform: teleport triggering object to the Transform\n"+
  14.             "* SceneAsset: load the scene\n"+
  15.             "* AudioClip: play audio here\n"+
  16.             "* GameObject: SetActivate(true)\n"+
  17.             "* Material: set this Renderer's .material property, make a note of what the previous material was\n"+
  18.             "* <any other>: activate a \'DoActivateTrigger()\' method (if available)\n"+
  19.             "* IEnumerable: trigger each element in the list")]
  20.         public Object whatToTrigger;
  21.         [Tooltip("If false, *deactivate* whatToTrigger instead")]
  22.         public bool activate = true;
  23.  
  24.         void Start () { AddTriggers (gameObject, whatToTrigger, kind, triggerTag, activate, delayInSeconds); }
  25.  
  26.         public void DoActivateTrigger (){ DoActivateTrigger (gameObject, whatToTrigger, gameObject, activate, delayInSeconds); }
  27.     }
  28.     [RequireComponent(typeof(Collider))]
  29.     public class TriggerBase : MonoBehaviour {
  30.  
  31.         public enum TKind {
  32.             scriptedOnly,
  33.             onTriggerEnter, onTriggerExit, onTriggerStay,
  34.             onCollisionEnter, onCollisionExit, onCollisionStay,
  35.             onControllerColliderHit,
  36.             onStart, onDestroy, onEnable, onDisable, onApplicationPause, onApplicationUnpause, onApplicationQuit,
  37.             onMouseEnter, onMouseOver, onMouseExit,
  38.             onMouseDown, onMouseDrag, onMouseUp, onMouseUpAsButton,
  39.             onBecameInvisible, onBecameVisible,
  40.             // TODO add: onVREnter (can be hands or head), onVRExit, onVRPress (can be any hand control button), onVRRelease, onVRPointStart, onVRPointStop, onVRSwipe
  41.         }
  42.         [Tooltip("What triggers the object above")]
  43.         public TKind kind = TKind.onTriggerEnter;
  44.         [Tooltip("For colliders, if not empty, only trigger if the triggering collider is tagged with this value")]
  45.         public string triggerTag;
  46.  
  47.         public static void DoActivateTrigger(object triggeringObject, object whatToTrigger, GameObject triggeredGameObject, bool activate, float delayInSeconds) {
  48.             if (delayInSeconds <= 0) {
  49.                 DoActivateTrigger (triggeringObject, whatToTrigger, triggeredGameObject, activate);
  50.             } else {
  51.                 NS.Timer.setTimeout (() => {
  52.                     DoActivateTrigger (triggeringObject, whatToTrigger, triggeredGameObject, activate);
  53.                 }, (long)(delayInSeconds * 1000));
  54.             }
  55.         }
  56.         public static void DoActivateTrigger(object triggeringObject, object whatToTrigger, GameObject triggeredGameObject, bool activate) {
  57.             if (whatToTrigger == null) { Debug.LogError ("Don't know how to trigger null"); return; }
  58.             System.Type type = whatToTrigger.GetType ();
  59.             if (typeof(System.Action).IsAssignableFrom (type)) {
  60.                 System.Action a = whatToTrigger as System.Action;
  61.                 a.Invoke ();
  62.             } else if (typeof(UnityEngine.Events.UnityEvent).IsAssignableFrom (type)) {
  63.                 UnityEngine.Events.UnityEvent a = whatToTrigger as UnityEngine.Events.UnityEvent;
  64.                 a.Invoke ();
  65.             } else if (type == typeof(Transform)) {
  66.                 Transform t = whatToTrigger as Transform;
  67.                 Transform toMove = triggeringObject as Transform;
  68.                 if (toMove == null) {
  69.                     GameObject go = triggeringObject as GameObject;
  70.                     if (go != null) {
  71.                         toMove = go.transform;
  72.                     }
  73.                 }
  74.                 if (toMove != null) {
  75.                     toMove.position = t.position;
  76.                 }
  77.             } else if (type == typeof(UnityEditor.SceneAsset)) {
  78.                 UnityEditor.SceneAsset scene = whatToTrigger as UnityEditor.SceneAsset;
  79.                 LoadLevel (scene.name, activate);
  80.             } else if (type == typeof(AudioClip) || type == typeof(AudioSource)) {
  81.                 AudioSource asource = null;
  82.                 if (type == typeof(AudioSource)) {
  83.                     asource = whatToTrigger as AudioSource;
  84.                 }
  85.                 if (asource == null) {
  86.                     asource = triggeredGameObject.AddComponent<AudioSource> ();
  87.                 }
  88.                 if (type == typeof(AudioClip)) {
  89.                     asource.clip = whatToTrigger as AudioClip;
  90.                 }
  91.                 if (activate) {
  92.                     asource.Play ();
  93.                 } else {
  94.                     asource.Stop ();
  95.                 }
  96.             } else if (type == typeof(ParticleSystem)) {
  97.                 ParticleSystem ps = whatToTrigger as ParticleSystem;
  98.                 if (activate) {
  99.                     Transform t = ps.transform;
  100.                     t.position = triggeredGameObject.transform.position;
  101.                     t.rotation = triggeredGameObject.transform.rotation;
  102.                     ParticleSystem.ShapeModule sm = ps.shape;
  103.                     if (sm.shapeType == ParticleSystemShapeType.Mesh) {
  104.                         sm.mesh = triggeredGameObject.GetComponent<MeshFilter> ().mesh;
  105.                         sm.scale = triggeredGameObject.transform.lossyScale;
  106.                     } else if (sm.shapeType == ParticleSystemShapeType.MeshRenderer) {
  107.                         sm.meshRenderer = triggeredGameObject.GetComponent<MeshRenderer> ();
  108.                     }
  109.                     ps.Play ();
  110.                 } else {
  111.                     ps.Stop ();
  112.                 }
  113.             } else if (type == typeof(GameObject)) {
  114.                 (whatToTrigger as GameObject).SetActive (activate);
  115.             } else if (type == typeof(UnityEngine.Material)) {
  116.                 RememberedOriginalMaterial r = triggeredGameObject.GetComponent<RememberedOriginalMaterial> ();
  117.                 if (activate) {
  118.                     Material m = whatToTrigger as Material;
  119.                     if (r == null) {
  120.                         r = triggeredGameObject.AddComponent<RememberedOriginalMaterial> ();
  121.                         r.oldMaterial = triggeredGameObject.GetComponent<Renderer> ().material;
  122.                         triggeredGameObject.GetComponent<Renderer> ().material = m;
  123.                     }
  124.                 } else {
  125.                     if (r != null) {
  126.                         triggeredGameObject.GetComponent<Renderer> ().material = r.oldMaterial;
  127.                         Destroy (r);
  128.                     }
  129.                 }
  130.             } else if (typeof(IEnumerable).IsAssignableFrom (type)) {
  131.                 IEnumerable ienum = whatToTrigger as IEnumerable;
  132.                 IEnumerator iter = ienum.GetEnumerator ();
  133.                 while (iter.MoveNext ()) {
  134.                     DoActivateTrigger (triggeringObject, iter.Current, triggeredGameObject, activate);
  135.                 }
  136.             } else if (type == typeof(Animation)) {
  137.                 if (activate) {
  138.                     (whatToTrigger as Animation).Play ();
  139.                 } else {
  140.                     (whatToTrigger as Animation).Stop();
  141.                 }
  142.             } else {
  143.                 System.Reflection.MethodInfo[] m = type.GetMethods ();
  144.                 bool invoked = false;
  145.                 for (int i = 0; i < m.Length; ++i) {
  146.                     if (m[i].Name == "DoActivateTrigger" && m[i].GetParameters().Length == 0) {
  147.                         m[i].Invoke (whatToTrigger, new object[]{ });
  148.                         invoked = true;
  149.                         break;
  150.                     }
  151.                 }
  152.                 if(!invoked) {
  153.                     Debug.LogError ("Don't know how to "+((activate)?"activate":"deactivate")+" a \'" + type + "\'");
  154.                 }
  155.             }
  156.         }
  157.         /// <summary>Loads or unloads the level.</summary>
  158.         /// <param name="sceneName">scene name.</param>
  159.         /// <param name="load">If set to <c>true</c> load (or unload current and reload), otherwise unload (if there are multiple levels)</param>
  160.         public static void LoadLevel(string sceneName, bool load = true) {
  161.             if (load) {
  162.                 int currentSceneIndex = -1;
  163.                 for (int i = 0; i < SceneManager.sceneCount; ++i) {
  164.                     if (SceneManager.GetSceneAt (i).name == sceneName) {
  165.                         currentSceneIndex = i; break;
  166.                     }
  167.                 }
  168.                 if (SceneManager.sceneCount > 1 && currentSceneIndex >= 0) {
  169.                     // if the scene is already loaded, unload it. then load it once it is unloaded
  170.                     AsyncOperation op = SceneManager.UnloadSceneAsync(sceneName);
  171.                     op.completed += (AsyncOperation o)=>{ SceneManager.LoadScene (sceneName, LoadSceneMode.Additive); };
  172.                 } else {
  173.                     SceneManager.LoadScene (sceneName);
  174.                 }
  175.             } else {
  176.                 SceneManager.UnloadSceneAsync (sceneName);
  177.             }
  178.         }
  179.         public class RememberedOriginalMaterial : MonoBehaviour { public Material oldMaterial; }
  180.  
  181.         private static void ColToTrig(GameObject g) {
  182.             Collider c = g.GetComponent<Collider> ();      if (c) { c.isTrigger = true; }
  183.             Collider2D c2 = g.GetComponent<Collider2D> (); if (c2) { c2.isTrigger = true; }
  184.         }
  185.  
  186.         public static void AddTriggers(GameObject g, object w, TKind kind, string triggerTag, bool a, float s) {
  187.             bool is2D = false;
  188.             switch(kind){
  189.             case TKind.onTriggerEnter: case TKind.onTriggerExit: case TKind.onTriggerStay:
  190.                 is2D = g.GetComponent<Collider2D> () != null;
  191.                 break;
  192.             }
  193.             switch (kind) {
  194.             case TKind.onTriggerEnter:if(is2D) AddTaggedTrigger<OnTriggerEnter2D_> (g,w,triggerTag,a,s);
  195.                                       else     AddTaggedTrigger<OnTriggerEnter_>   (g,w,triggerTag,a,s); ColToTrig (g); break;
  196.             case TKind.onTriggerExit: if(is2D) AddTaggedTrigger<OnTriggerExit2D_>  (g,w,triggerTag,a,s);
  197.                                       else     AddTaggedTrigger<OnTriggerExit_>    (g,w,triggerTag,a,s); ColToTrig (g); break;
  198.             case TKind.onTriggerStay: if(is2D) AddTaggedTrigger<OnTriggerStay2D_>  (g,w,triggerTag,a,s);
  199.                                       else     AddTaggedTrigger<OnTriggerStay_>    (g,w,triggerTag,a,s); ColToTrig (g); break;
  200.             case TKind.onCollisionEnter:if(is2D) AddTaggedTrigger<OnCollisionEnter2D_> (g,w,triggerTag,a,s);
  201.                                         else     AddTaggedTrigger<OnCollisionEnter_>   (g,w,triggerTag,a,s); ColToTrig (g); break;
  202.             case TKind.onCollisionExit: if(is2D) AddTaggedTrigger<OnCollisionExit2D_>  (g,w,triggerTag,a,s);
  203.                                         else     AddTaggedTrigger<OnCollisionExit_>    (g,w,triggerTag,a,s); ColToTrig (g); break;
  204.             case TKind.onCollisionStay: if(is2D) AddTaggedTrigger<OnCollisionStay2D_>  (g,w,triggerTag,a,s);
  205.                                         else     AddTaggedTrigger<OnCollisionStay_>    (g,w,triggerTag,a,s); ColToTrig (g); break;
  206.             case TKind.onControllerColliderHit:AddTaggedTrigger<OnControllerColliderHit_> (g,w,triggerTag,a,s); break;
  207.             case TKind.onStart:             AddTrigger<OnStart_>    (g,w,a,s); break;
  208.             case TKind.onDestroy:           AddTrigger<OnDestroy_>  (g,w,a,s); break;
  209.             case TKind.onEnable:            AddTrigger<OnEnable_>   (g,w,a,s); break;
  210.             case TKind.onDisable:           AddTrigger<OnDisable_>  (g,w,a,s); break;
  211.             case TKind.onApplicationPause:  AddTrigger<OnApplicationPause_>   (g,w,a,s); break;
  212.             case TKind.onApplicationUnpause:AddTrigger<OnApplicationUnpause_> (g,w,a,s); break;
  213.             case TKind.onApplicationQuit:   AddTrigger<OnApplicationQuit_>    (g,w,a,s); break;
  214.             case TKind.onMouseEnter:        AddTrigger<OnMouseEnter_>(g,w,a,s); break;
  215.             case TKind.onMouseOver:         AddTrigger<OnMouseOver_> (g,w,a,s); break;
  216.             case TKind.onMouseExit:         AddTrigger<OnMouseExit_> (g,w,a,s); break;
  217.             case TKind.onMouseDown:         AddTrigger<OnMouseDown_> (g,w,a,s); break;
  218.             case TKind.onMouseDrag:         AddTrigger<OnMouseDrag_> (g,w,a,s); break;
  219.             case TKind.onMouseUp:           AddTrigger<OnMouseUp_>   (g,w,a,s); break;
  220.             case TKind.onMouseUpAsButton:   AddTrigger<OnMouseUpAsButton_> (g,w,a,s); break;
  221.             case TKind.onBecameInvisible:   AddTrigger<OnBecameInvisible_> (g,w,a,s); break;
  222.             case TKind.onBecameVisible:     AddTrigger<OnBecameVisible_> (g,w,a,s); break;
  223.             }
  224.         }
  225.  
  226.         public class _TriggerBase : MonoBehaviour {
  227.             public object whatToTrigger;
  228.             public float delayInSeconds = 0;
  229.             public bool activate = true;
  230.             public void DoActivateTrigger () {
  231.                 Trigger.DoActivateTrigger (gameObject, whatToTrigger, gameObject, activate, delayInSeconds);
  232.             }
  233.             public void DoTriggerMouse() { Trigger.DoActivateTrigger (Input.mousePosition, whatToTrigger, gameObject, activate); }
  234.         }
  235.         private static void AddTrigger<T>(GameObject gameObject, object whatToTrigger, bool activate, float s) where T : _TriggerBase {
  236.             T t = gameObject.AddComponent<T> ();
  237.             t.whatToTrigger = whatToTrigger;
  238.             t.activate = activate;
  239.             t.delayInSeconds = s;
  240.         }
  241.  
  242.         public class OnStart_ : _TriggerBase { void Start() { DoActivateTrigger(); }}
  243.         public class OnDestroy_ : _TriggerBase { void OnDestroy() { DoActivateTrigger(); }}
  244.         public class OnEnable_ : _TriggerBase { void OnEnable() { DoActivateTrigger(); }}
  245.         public class OnDisable_ : _TriggerBase { void OnDisable() { DoActivateTrigger(); }}
  246.         public class OnBecameInvisible_ : _TriggerBase { void OnBecameInvisible() { DoActivateTrigger(); }}
  247.         public class OnBecameVisible_ : _TriggerBase { void OnBecameVisible() { DoActivateTrigger(); }}
  248.         public class OnMouseEnter_ : _TriggerBase { void OnMouseEnter() { DoTriggerMouse (); }}
  249.         public class OnMouseOver_ : _TriggerBase { void OnMouseOver() { DoTriggerMouse (); }}
  250.         public class OnMouseExit_ : _TriggerBase { void OnMouseExit() { DoTriggerMouse (); }}
  251.         public class OnMouseDown_ : _TriggerBase { void OnMouseDown() { DoTriggerMouse (); }}
  252.         public class OnMouseDrag_ : _TriggerBase { void OnMouseDrag() { DoTriggerMouse (); }}
  253.         public class OnMouseUp_ : _TriggerBase { void OnMouseUp() { DoTriggerMouse (); }}
  254.         public class OnMouseUpAsButton_ : _TriggerBase { void OnMouseMouseUpAsButton() { DoTriggerMouse (); }}
  255.  
  256.         public delegate void BooleanAction(bool b);
  257.         public static void EquateUnityEditorPauseWithApplicationPause(BooleanAction b) {
  258.             #if UNITY_EDITOR
  259.             // This method is run whenever the playmode state is changed.
  260.             UnityEditor.EditorApplication.pauseStateChanged += (UnityEditor.PauseState ps) => {
  261.                 b(ps == UnityEditor.PauseState.Paused);
  262.             };
  263.             #endif
  264.         }
  265.         public class OnApplicationPause_ : _TriggerBase { void OnApplicationPause(bool pauseStatus) {
  266.             if (pauseStatus == true) { DoActivateTrigger (); }
  267.         } void Start() { EquateUnityEditorPauseWithApplicationPause (OnApplicationPause); }}
  268.         public class OnApplicationUnpause_ : _TriggerBase { void OnApplicationPause(bool pauseStatus) {
  269.             if (pauseStatus == false) { DoActivateTrigger (); }
  270.         } void Start() { EquateUnityEditorPauseWithApplicationPause (OnApplicationPause); }}
  271.  
  272.         public class OnApplicationQuit_ : _TriggerBase { void OnApplicationQuit() { DoActivateTrigger(); }}
  273.         //onTriggerEnter, onTriggerExit, onTriggerStay,
  274.         public class _TriggerAreaBase : _TriggerBase {
  275.             public string triggerTag;
  276.             public bool IsTriggeringObject(GameObject o){ return triggerTag == "" || o.tag == triggerTag || o.tag == ""; }
  277.             public void DoActivateTrigger (GameObject tobj) {
  278.                 if (IsTriggeringObject(tobj)) {
  279.                     Trigger.DoActivateTrigger (tobj, whatToTrigger, gameObject, activate, delayInSeconds); }
  280.             }
  281.         }
  282.         private static void AddTaggedTrigger<T>(GameObject gameObject, object whatToTrigger, string triggerTag, bool activate, float s) where T : _TriggerAreaBase {
  283.             T t = gameObject.AddComponent<T> ();
  284.             t.whatToTrigger = whatToTrigger;
  285.             t.triggerTag = triggerTag;
  286.             t.activate = activate;
  287.             t.delayInSeconds = s;
  288.         }
  289.  
  290.         public class OnTriggerEnter_ : _TriggerAreaBase { void OnTriggerEnter (Collider col) { DoActivateTrigger (col.gameObject); }}
  291.         public class OnTriggerExit_ : _TriggerAreaBase { void OnTriggerExit (Collider col) { DoActivateTrigger (col.gameObject); }}
  292.         public class OnTriggerStay_ : _TriggerAreaBase { void OnTriggerStay (Collider col) { DoActivateTrigger (col.gameObject); }}
  293.         public class OnTriggerEnter2D_ : _TriggerAreaBase { void OnTriggerEnter2D (Collider2D col) { DoActivateTrigger (col.gameObject); }}
  294.         public class OnTriggerExit2D_ : _TriggerAreaBase { void OnTriggerExit2D (Collider2D col) { DoActivateTrigger (col.gameObject); }}
  295.         public class OnTriggerStay2D_ : _TriggerAreaBase { void OnTriggerStay2D (Collider2D col) { DoActivateTrigger (col.gameObject); }}
  296.         public class OnCollisionEnter_ : _TriggerAreaBase { void OnCollisionEnter (Collider col) { DoActivateTrigger (col.gameObject); }}
  297.         public class OnCollisionExit_ : _TriggerAreaBase { void OnCollisionExit (Collider col) { DoActivateTrigger (col.gameObject); }}
  298.         public class OnCollisionStay_ : _TriggerAreaBase { void OnCollisionStay (Collider col) { DoActivateTrigger (col.gameObject); }}
  299.         public class OnCollisionEnter2D_ : _TriggerAreaBase { void OnCollisionEnter2D (Collider2D col) { DoActivateTrigger (col.gameObject); }}
  300.         public class OnCollisionExit2D_ : _TriggerAreaBase { void OnCollisionExit2D (Collider2D col) { DoActivateTrigger (col.gameObject); }}
  301.         public class OnCollisionStay2D_ : _TriggerAreaBase { void OnCollisionStay2D (Collider2D col) { DoActivateTrigger (col.gameObject); }}
  302.         public class OnControllerColliderHit_ : _TriggerAreaBase { void OnControllerColliderHit(CharacterController col) { DoActivateTrigger (col.gameObject); }}
  303.     }
  304. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement