summaryrefslogtreecommitdiff
path: root/Runtime/Graphs/UnityEngine.Graphs
diff options
context:
space:
mode:
Diffstat (limited to 'Runtime/Graphs/UnityEngine.Graphs')
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/AnimationNodeLibrary.cs22
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/Attributes.cs96
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/DefaultValueAttribute.cs33
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/GraphBehaviour.cs121
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Animation/AnimationNodes.cs76
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Animation/SimpleAnimationPlayer.cs78
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/AudioSource/AudioSourceNodes.cs19
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/CharacterController/SimpleCharacterControllerNodes.cs24
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Collections/CollectionsNodes.cs128
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Collider/OnCollisionEvent.cs74
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Collider/OnMouseEvent.cs22
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Collider/OnTriggerEvent.cs48
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Component/ComponentNodes.cs10
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/InputNodes.cs82
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnAxis.cs37
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnButton.cs38
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnInputNode.cs50
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnKey.cs38
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnMouseButton.cs38
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/LogicNodeUtility.cs5
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Material/MaterialNodes.cs113
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/NodeLibrary.cs94
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/NodeLibraryForTesting.txt124
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Rigidbody/RigidbodyNodes.cs104
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/LookAt.cs46
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/MoveTo.cs45
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/RotateTo.cs45
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/TransformNodes.cs122
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/YieldedTransformNodeBase.cs27
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/YieldedNodeBase.cs54
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/LogicNodeTestLibrary.cs359
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/ColliderDummyBase.cs25
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/OnAnimationEventDummy.cs51
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/OnCollisionEventDummy.cs43
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/OnMouseEventDummy.cs41
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/OnTriggerEventDummy.cs40
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/TestHelpers.cs33
-rw-r--r--Runtime/Graphs/UnityEngine.Graphs/UnityEngine.Graphs.csproj92
38 files changed, 2497 insertions, 0 deletions
diff --git a/Runtime/Graphs/UnityEngine.Graphs/AnimationNodeLibrary.cs b/Runtime/Graphs/UnityEngine.Graphs/AnimationNodeLibrary.cs
new file mode 100644
index 0000000..7ee2299
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/AnimationNodeLibrary.cs
@@ -0,0 +1,22 @@
+#if UNITY_ANIMATION_GRAPH
+
+using UnityEngine.Graphs.LogicGraph;
+using UnityEngine;
+
+namespace UnityEngine.Graphs
+{
+ public class AnimationNodeLibrary
+ {
+ [AnimationLogic(typeof(Animation))]
+ public static void SetSpeed1 (Animation self, string animName, float speed)
+ {
+ // Sanity check
+ if (self)
+ self[animName].speed = speed;
+ else
+ Debug.LogWarning("SetSpeed self parameter is null");
+ }
+ }
+}
+
+#endif
diff --git a/Runtime/Graphs/UnityEngine.Graphs/Attributes.cs b/Runtime/Graphs/UnityEngine.Graphs/Attributes.cs
new file mode 100644
index 0000000..1e6bca9
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/Attributes.cs
@@ -0,0 +1,96 @@
+using System;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Parameter)]
+ public class SettingAttribute : Attribute { }
+
+ // TODO : should be abstract
+ // for almost everything logic graph related (classes, functions, variables, ...)
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Event | AttributeTargets.Field | AttributeTargets.Property)]
+ public class CodeGeneratingLogicAttribute : Attribute
+ {
+ public Type type;
+ public Type inputsType;
+ public Type stateType;
+ }
+
+ // for almost everything logic graph related (classes, functions, variables, ...)
+ public class LogicAttribute : CodeGeneratingLogicAttribute
+ {
+ public LogicAttribute() { type = null; }
+ public LogicAttribute(Type type) { this.type = type; }
+ public LogicAttribute(Type type, Type inputsType)
+ {
+ base.type = type;
+ base.inputsType = inputsType;
+ }
+ public LogicAttribute(Type type, Type inputsType, Type stateType)
+ {
+ base.type = type;
+ base.inputsType = inputsType;
+ base.stateType = stateType;
+ }
+ }
+
+ // for evaluator nodes
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
+ public class LogicEvalAttribute : Attribute
+ {
+ public Type type;
+ public Type stateType;
+
+ public LogicEvalAttribute() { type = null; }
+ public LogicEvalAttribute(Type type) { this.type = type; }
+ public LogicEvalAttribute(Type type, Type stateType)
+ {
+ this.type = type;
+ this.stateType = stateType;
+ }
+ }
+
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field)]
+ public class LogicExpressionAttribute: Attribute
+ {
+ public string name;
+ public LogicExpressionAttribute() { name = string.Empty;}
+ public LogicExpressionAttribute(string name) { this.name = name; }
+ }
+
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
+ public class LogicTargetAttribute : Attribute { }
+
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue)]
+ public class TitleAttribute : Attribute
+ {
+ public string title;
+ public TitleAttribute(string title) { this.title = title; }
+ }
+
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Event | AttributeTargets.Field | AttributeTargets.Property)]
+ public class ValidateAttribute : Attribute
+ {
+ public string validateFunction;
+ public ValidateAttribute(string validateFunction) { this.validateFunction = validateFunction; }
+ }
+
+ #if UNITY_ANIMATION_GRAPH
+ // for almost everything logic graph related (classes, functions, variables, ...)
+ public class AnimationLogicAttribute : CodeGeneratingLogicAttribute
+ {
+ public AnimationLogicAttribute() { type = null; }
+ public AnimationLogicAttribute(Type type) { base.type = type; }
+ public AnimationLogicAttribute(Type type, Type inputsType)
+ {
+ base.type = type;
+ base.inputsType = inputsType;
+ }
+ public AnimationLogicAttribute(Type type, Type inputsType, Type stateType)
+ {
+ base.type = type;
+ base.inputsType = inputsType;
+ base.stateType = stateType;
+ }
+ }
+ #endif
+}
diff --git a/Runtime/Graphs/UnityEngine.Graphs/DefaultValueAttribute.cs b/Runtime/Graphs/UnityEngine.Graphs/DefaultValueAttribute.cs
new file mode 100644
index 0000000..2dd334a
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/DefaultValueAttribute.cs
@@ -0,0 +1,33 @@
+using System;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ [AttributeUsage(AttributeTargets.All)]
+ public class DefaultValueAttribute : Attribute
+ {
+ private object m_Value;
+ private Type m_Type;
+
+ public object value
+ {
+ get { return m_Value; }
+ }
+
+ public Type type
+ {
+ get { return m_Type; }
+ }
+
+ public DefaultValueAttribute(object value)
+ {
+ m_Value = value;
+ }
+
+ public DefaultValueAttribute(Type type, string value)
+ {
+ m_Value = value;
+ m_Type = type;
+ }
+ }
+}
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/GraphBehaviour.cs b/Runtime/Graphs/UnityEngine.Graphs/GraphBehaviour.cs
new file mode 100644
index 0000000..2330c66
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/GraphBehaviour.cs
@@ -0,0 +1,121 @@
+using System;
+using UnityEngine;
+
+#if TESTING
+using Object = UnityEngine.Graphs.Testing.Object;
+#else
+using Object = UnityEngine.Object;
+#endif
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public interface IMonoBehaviourEventCaller
+ {
+ event GraphBehaviour.VoidDelegate OnAwake;
+ event GraphBehaviour.VoidDelegate OnStart;
+ event GraphBehaviour.VoidUpdateDelegate OnUpdate;
+ event GraphBehaviour.VoidUpdateDelegate OnLateUpdate;
+ event GraphBehaviour.VoidUpdateDelegate OnFixedUpdate;
+ }
+
+ //TODO: we can optimize this, now say Update will get called always for each graph even though nothing is using it
+ // we can generate code for those in generated graph instead
+
+ // Component that represents graph in the hierarchy.
+ // When used in editor it stores all LogicGraph state as well, but since those are editor side classes they get stripped out when the player is built.
+ public class GraphBehaviour :
+ #if TESTING
+ Object, IMonoBehaviourEventCaller
+ #else
+ MonoBehaviour, IMonoBehaviourEventCaller
+ #endif
+ {
+ [NonSerialized]
+ private bool m_IsInitialized;
+
+ #region Nodes
+ public delegate void VoidDelegate ();
+ public delegate void VoidUpdateDelegate (float deltaTime);
+
+ [Logic]
+ [Title("Flow Events/On Awake")]
+ public event VoidDelegate OnAwake;
+
+ [Logic]
+ [Title("Flow Events/On Start")]
+ public event VoidDelegate OnStart;
+
+ [Logic]
+ [Title("Flow Events/On Update")]
+ public event VoidUpdateDelegate OnUpdate;
+
+ [Logic]
+ [Title("Flow Events/On Late Update")]
+ public event VoidUpdateDelegate OnLateUpdate;
+
+ [Logic]
+ [Title("Flow Events/On Fixed Update")]
+ public event VoidUpdateDelegate OnFixedUpdate;
+
+ protected virtual void @ΣInit()
+ {
+ }
+
+ private void Initialize()
+ {
+ if (m_IsInitialized)
+ return;
+ m_IsInitialized = true;
+ @ΣInit();
+ }
+
+ public void OnEnable()
+ {
+ Initialize ();
+ }
+
+ public void Awake ()
+ {
+ Initialize ();
+
+ if (OnAwake != null)
+ OnAwake();
+ }
+
+ public void Start ()
+ {
+ if (OnStart != null)
+ OnStart ();
+ }
+
+ public void Update ()
+ {
+ if (OnUpdate != null)
+ OnUpdate (Time.deltaTime);
+ }
+
+ public void LateUpdate ()
+ {
+ if (OnLateUpdate != null)
+ OnLateUpdate (Time.deltaTime);
+ }
+
+ public void FixedUpdate ()
+ {
+ if (OnFixedUpdate != null)
+ OnFixedUpdate (Time.deltaTime);
+ }
+ #endregion
+
+ protected void PullSceneReferenceVariables(string references)
+ {
+ foreach (var asm in System.AppDomain.CurrentDomain.GetAssemblies())
+ if (asm.GetName().Name == "UnityEditor.Graphs.LogicGraph")
+ {
+ var method = asm.GetType("UnityEditor.Graphs.LogicGraph.CompilerUtils").GetMethod("SetEditorModeGeneratedGraphSceneReferences");
+ method.Invoke(null, new object[] {this, references});
+ break;
+ }
+ }
+ }
+}
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Animation/AnimationNodes.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Animation/AnimationNodes.cs
new file mode 100644
index 0000000..28d0efd
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Animation/AnimationNodes.cs
@@ -0,0 +1,76 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public partial class AnimationNodes
+ {
+ [Logic(typeof(Animation))]
+ [return: Title("Animation State")]
+ public static AnimationState GetAnimationState (Animation self, [Setting] string animationStateName)
+ {
+ return self[animationStateName];
+ }
+
+ [Logic(typeof(Animation))]
+ [return: Title("Animation State")]
+ public static AnimationState PlayAnimation (Animation self, [Setting] string animationName, [Setting] bool crossfade, [Setting] float fadeLength, [Setting] PlayMode playMode)
+ {
+ AnimationState animationState = self[animationName == "" ? self.clip.name : animationName];
+
+ if (crossfade)
+ self.CrossFade (animationState.name, fadeLength, playMode);
+ else
+ self.Play (animationState.name, playMode);
+
+ return animationState;
+ }
+
+ [Logic(typeof(Animation))]
+ [return: Title("Animation State")]
+ public static AnimationState PlayQueuedAnimation (Animation self, [Setting] string animationName, [Setting] bool crossfade, [Setting] float fadeLength, [Setting] QueueMode queueMode, [Setting] PlayMode playMode)
+ {
+ if (animationName == "")
+ animationName = self.clip.name;
+
+ var animationState = crossfade ?
+ self.CrossFadeQueued (animationName, fadeLength, queueMode, playMode) :
+ self.PlayQueued (animationName, queueMode, playMode);
+
+ return animationState;
+ }
+
+ [Logic(typeof(Animation))]
+ public static void StopAnimation (Animation self, [Setting] string animationName)
+ {
+ if (animationName == "")
+ self.Stop();
+ else
+ self.Stop(animationName);
+ }
+
+ [Logic (typeof (Animation))]
+ public static void SampleAnimation (Animation self)
+ {
+ self.Sample ();
+ }
+
+ [Logic(typeof(Animation))]
+ public static void StopAnimationState (Animation self, AnimationState animationState)
+ {
+ self.Stop(animationState.name);
+ }
+
+ [Logic(typeof(Animation))]
+ public static void BlendAnimationState (Animation self, AnimationState animationState, float targetWeight, [Setting] float fadeLength)
+ {
+ self.Blend (animationState.name, targetWeight, fadeLength);
+ }
+
+ [Logic(typeof(Animation))]
+ public static void SyncAnimationLayer (Animation self, int layer)
+ {
+ self.SyncLayer (layer);
+ }
+ }
+}
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Animation/SimpleAnimationPlayer.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Animation/SimpleAnimationPlayer.cs
new file mode 100644
index 0000000..9b1ee07
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Animation/SimpleAnimationPlayer.cs
@@ -0,0 +1,78 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public partial class AnimationNodes
+ {
+ [Logic(typeof(Animation))]
+ public sealed class SimpleAnimationPlayer
+ {
+ // Logic Target
+ public Animation self;
+
+ // Settings
+ private AnimationState m_AnimationState;
+ [Setting]
+ public string animationName
+ {
+ set
+ {
+ m_AnimationState = self[value != "" ? value : self.clip.name];
+ }
+ }
+ private bool m_Crossfade;
+ [Setting]
+ public bool crossfade { set { m_Crossfade = value; } }
+ private float m_FadeLength;
+ [Setting]
+ public float fadeLength { set { m_FadeLength = value; } }
+
+ private bool m_IsPaused;
+ private float m_ResumeSpeed;
+
+ public SimpleAnimationPlayer () { }
+
+ public SimpleAnimationPlayer (Animation self, string animationName, bool crossfade, float fadeLength)
+ {
+ this.self = self;
+ this.animationName = animationName;
+ m_Crossfade = crossfade;
+ m_FadeLength = fadeLength;
+ }
+
+ public void Play ()
+ {
+ if (m_Crossfade)
+ self.CrossFade (m_AnimationState.name, m_FadeLength);
+ else
+ self.Play (m_AnimationState.name);
+ }
+
+ public void Stop ()
+ {
+ StopAnimationState (m_AnimationState);
+ }
+
+ [Title("Pause/Resume")]
+ public void PauseResume ()
+ {
+ float tmpSpeed = m_AnimationState.speed;
+ m_AnimationState.speed = m_IsPaused ? m_ResumeSpeed : 0.0f;
+
+ m_ResumeSpeed = tmpSpeed;
+ m_IsPaused = !m_IsPaused;
+ }
+
+ public void Rewind ()
+ {
+ m_AnimationState.time = 0.0f;
+ }
+
+ private static void StopAnimationState (AnimationState animationState)
+ {
+ animationState.enabled = false;
+ animationState.time = 0.0f;
+ }
+ }
+ }
+}
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/AudioSource/AudioSourceNodes.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/AudioSource/AudioSourceNodes.cs
new file mode 100644
index 0000000..75b9f90
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/AudioSource/AudioSourceNodes.cs
@@ -0,0 +1,19 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public class AudioSourceNodes
+ {
+ [Logic (typeof(AudioSource))]
+ public static IEnumerator PlayOneShot (AudioSource self, AudioClip clip, float volume)
+ {
+ self.PlayOneShot (clip, volume);
+
+ yield return new WaitForSeconds (clip.length);
+ }
+ }
+}
+
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/CharacterController/SimpleCharacterControllerNodes.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/CharacterController/SimpleCharacterControllerNodes.cs
new file mode 100644
index 0000000..89d791a
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/CharacterController/SimpleCharacterControllerNodes.cs
@@ -0,0 +1,24 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public sealed class SimpleCharacterControllerNodes
+ {
+ [Logic(typeof(CharacterController))]
+ public static void SimpleMove (CharacterController self, Vector3 speed, Action grounded, Action airborne)
+ {
+ if (self.SimpleMove (speed))
+ {
+ if (grounded != null) grounded ();
+ }
+ else if (airborne != null) airborne ();
+ }
+
+ [Logic(typeof(CharacterController))]
+ public static CollisionFlags Move (CharacterController self, Vector3 motion)
+ {
+ return self.Move (motion);
+ }
+ }
+}
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Collections/CollectionsNodes.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Collections/CollectionsNodes.cs
new file mode 100644
index 0000000..f585bc0
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Collections/CollectionsNodes.cs
@@ -0,0 +1,128 @@
+using System;
+using System.Collections.Generic;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public class CollectionsNodes
+ {
+ public enum IteratorIn { Reset, Next }
+ public delegate void IteratorOut<T> (T element, int index);
+ public delegate void IteratorElementOut<T>(T element);
+
+ [Logic(null, typeof(IteratorIn), typeof(int))]
+ [Title("Collections/Iterator")]
+ public static void Iterator<T> (IteratorIn input, [DefaultValue(-1)] ref int index, List<T> collection, IteratorOut<T> resetOut, IteratorOut<T> iteration, IteratorOut<T> done)
+ {
+ if (input == IteratorIn.Reset)
+ {
+ index = -1;
+ if (resetOut != null) resetOut (default(T), index);
+ return;
+ }
+
+ if (++index >= collection.Count)
+ {
+ if (done != null) done (default (T), index);
+ }
+ else
+ {
+ if (iteration != null) iteration (collection[index], index);
+ if (index + 1 >= collection.Count)
+ if (done != null) done (default (T), index);
+ }
+ }
+
+ [Logic]
+ [Title("Collections/IterateAll")]
+ public static void IterateAll<T> (List<T> collection, IteratorOut<T> iteration, IteratorOut<T> done)
+ {
+ for (int index = 0; index < collection.Count; ++index)
+ if (iteration != null) iteration (collection[index], index);
+
+ if (done != null) done (default (T), collection.Count - 1);
+ }
+
+ [Logic]
+ [Title("Collections/Add")]
+ public static void Add<T> (List<T> collection, T objectToAdd)
+ {
+ collection.Add (objectToAdd);
+ }
+
+ [Logic]
+ [Title("Collections/Insert")]
+ public static void Insert<T> (List<T> collection, T objectToAdd, int index)
+ {
+ collection.Insert (index, objectToAdd);
+ }
+
+ [Logic]
+ [Title("Collections/GetElementAt")]
+ public static void GetElementAt<T>(List<T> collection, int index, IteratorElementOut<T> success, IteratorElementOut<T> notPresent)
+ {
+ if (index < 0 || collection.Count <= index)
+ {
+ if (notPresent != null)
+ notPresent ((T) (typeof (T).IsValueType ? Activator.CreateInstance (typeof (T)) : null));
+ }
+ else
+ if (success != null)
+ success(collection[index]);
+ }
+
+ [Logic]
+ [Title("Collections/SetElementAt")]
+ public static void SetElementAt<T>(List<T> collection, T element, int index, Action success, Action notPresent)
+ {
+ if (index < 0 || collection.Count <= index)
+ {
+ if (notPresent != null)
+ notPresent();
+ }
+ else
+ {
+ collection[index] = element;
+
+ if (success != null)
+ success ();
+ }
+ }
+
+ [Logic]
+ [Title("Collections/Contains")]
+ public static void Contains<T> (List<T> collection, T objectToTest, Action present, Action notPresent)
+ {
+ if (collection.Contains (objectToTest))
+ {
+ if (present != null) present ();
+ }
+ else if (notPresent != null) notPresent ();
+ }
+
+ [Logic]
+ [Title("Collections/Remove")]
+ public static void Remove<T> (List<T> collection, T objectToRemove, Action removed, Action notPresent)
+ {
+ if (collection.Remove (objectToRemove))
+ {
+ if (removed != null) removed ();
+ }
+ else if (notPresent != null) notPresent ();
+ }
+
+ [Logic]
+ [Title("Collections/RemoveAt")]
+ public static void RemoveAt<T> (List<T> collection, int index)
+ {
+ collection.RemoveAt (index);
+ }
+
+ [Logic]
+ [Title("Collections/Clear")]
+ public static void Clear<T> (List<T> collection)
+ {
+ collection.Clear ();
+ }
+ }
+}
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Collider/OnCollisionEvent.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Collider/OnCollisionEvent.cs
new file mode 100644
index 0000000..acc732e
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Collider/OnCollisionEvent.cs
@@ -0,0 +1,74 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public partial class ColliderNodes
+ {
+ // This is only used for node declaration. Implementation is in the OnCollisionEventDummy monobehaviour.
+ [Logic(typeof(Collider))]
+ public class OnCollisionEvent
+ {
+ [LogicTarget]
+ public Collider self;
+
+ public Action enter;
+ public Action exit;
+ public Action stay;
+
+ private Vector3 m_RelativeVelocity;
+ public Vector3 relativeVelocity
+ {
+ get { return m_RelativeVelocity; }
+ }
+
+ private Collider m_Other;
+ public Collider other
+ {
+ get { return m_Other; }
+ }
+
+ //TODO: would be nice to have, but no nodes in graphs yet know about how to work with arrays
+ //private ContactPoint[] m_Contacts;
+ //public ContactPoint[] contacts
+ //{
+ // get { return m_Contacts; }
+ //}
+
+ internal void EnterDummy(Collision collision)
+ {
+ if (enter == null)
+ return;
+
+ m_RelativeVelocity = collision.relativeVelocity;
+ m_Other = collision.collider;
+ //m_Contacts = collision.contacts;
+
+ enter ();
+ }
+
+ internal void ExitDummy(Collision collision)
+ {
+ if (exit == null)
+ return;
+
+ m_RelativeVelocity = collision.relativeVelocity;
+ m_Other = collision.collider;
+ //m_Contacts = collision.contacts;
+
+ exit();
+ }
+
+ internal void StayDummy(Collision collision)
+ {
+ if (stay == null)
+ return;
+
+ m_RelativeVelocity = collision.relativeVelocity;
+ m_Other = collision.collider;
+ //m_Contacts = collision.contacts;
+
+ stay();
+ }
+ }
+ }
+}
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Collider/OnMouseEvent.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Collider/OnMouseEvent.cs
new file mode 100644
index 0000000..869fc5e
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Collider/OnMouseEvent.cs
@@ -0,0 +1,22 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public partial class ColliderNodes
+ {
+ // This is only used for node declaration. Implementation is in the OnMouseEventDummy monobehaviour.
+ [Logic(typeof(Collider))]
+ public class OnMouseEvent
+ {
+ [LogicTarget]
+ public Collider self;
+
+ public Action enter;
+ public Action over;
+ public Action exit;
+ public Action down;
+ public Action up;
+ public Action drag;
+ }
+ }
+}
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Collider/OnTriggerEvent.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Collider/OnTriggerEvent.cs
new file mode 100644
index 0000000..4be1fbc
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Collider/OnTriggerEvent.cs
@@ -0,0 +1,48 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public partial class ColliderNodes
+ {
+ // This is only used for node declaration. Implementation is in the OnCollisionEventDummy monobehaviour.
+ [Logic(typeof(Collider))]
+ public class OnTriggerEvent
+ {
+ [LogicTarget]
+ public Collider self;
+
+ public Action enter;
+ public Action exit;
+ public Action stay;
+
+ private Collider m_Other;
+
+ public Collider other
+ {
+ get { return m_Other; }
+ }
+
+ internal void EnterDummy(Collider other)
+ {
+ if (enter == null)
+ return;
+ m_Other = other;
+ enter();
+ }
+ internal void ExitDummy(Collider other)
+ {
+ if (exit == null)
+ return;
+ m_Other = other;
+ exit();
+ }
+ internal void StayDummy(Collider other)
+ {
+ if (stay == null)
+ return;
+ m_Other = other;
+ stay();
+ }
+ }
+ }
+}
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Component/ComponentNodes.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Component/ComponentNodes.cs
new file mode 100644
index 0000000..2467573
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Component/ComponentNodes.cs
@@ -0,0 +1,10 @@
+using UnityEngine;
+using System.Collections;
+using System;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public class ComponentNodes
+ {
+ }
+}
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/InputNodes.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/InputNodes.cs
new file mode 100644
index 0000000..d1687db
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/InputNodes.cs
@@ -0,0 +1,82 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public partial class InputNodes
+ {
+ public delegate void AxisDelegate (float value);
+ public delegate void MouseDelegate (Vector3 mousePosition);
+
+ [Logic]
+ [Title("Input/Get Button")]
+ public static void GetButton(string buttonName, Action onDown, Action onUp, Action down, Action up)
+ {
+ if (onDown != null && Input.GetButtonDown (buttonName))
+ onDown ();
+
+ if (onUp != null && Input.GetButtonUp (buttonName))
+ onUp ();
+
+ if (down != null || up != null)
+ {
+ var stateDelegate = Input.GetButton (buttonName) ? down : up;
+ if (stateDelegate != null)
+ stateDelegate ();
+ }
+ }
+
+ [Logic]
+ [Title("Input/Get Mouse Button")]
+ public static void GetMouseButton (int mouseButton, MouseDelegate onDown, MouseDelegate onUp, MouseDelegate down, MouseDelegate up)
+ {
+ if (onDown != null && Input.GetMouseButtonDown(mouseButton))
+ onDown(Input.mousePosition);
+
+ if (onUp != null && Input.GetMouseButtonUp(mouseButton))
+ onUp(Input.mousePosition);
+
+ if (down != null || up != null)
+ {
+ MouseDelegate stateDelegate = Input.GetMouseButton(mouseButton) ? down : up;
+ if (stateDelegate != null)
+ stateDelegate(Input.mousePosition);
+ }
+ }
+
+ [Logic]
+ [Title("Input/Get Key")]
+ public static void GetKey(KeyCode key, Action onDown, Action onUp, Action down, Action up)
+ {
+ if (onDown != null && Input.GetKeyDown (key))
+ onDown ();
+
+ if (onUp != null && Input.GetKeyUp (key))
+ onUp ();
+
+ if (down != null || up != null)
+ {
+ var stateDelegate = Input.GetKey (key) ? down : up;
+ if (stateDelegate != null)
+ stateDelegate ();
+ }
+ }
+
+ [Logic]
+ [Title("Input/Get Axis")]
+ public static void GetAxis(string axisName, AxisDelegate down, AxisDelegate up)
+ {
+ AxisDelegate stateDelegate = Input.GetButton (axisName) ? down : up;
+ if (stateDelegate != null)
+ stateDelegate (Input.GetAxis (axisName));
+ }
+
+ [LogicEval]
+ [Title("Input/Mouse Position")]
+ [return: Title("Mouse Position")]
+ public static Vector3 MousePosition ()
+ {
+ return Input.mousePosition;
+ }
+ }
+}
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnAxis.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnAxis.cs
new file mode 100644
index 0000000..f9bdcb6
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnAxis.cs
@@ -0,0 +1,37 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public partial class InputNodes
+ {
+ [Logic]
+ [Title("Input/On Axis")]
+ public sealed class OnAxis : OnInputNode
+ {
+ private float m_Value;
+ public float value { get { return m_Value; } }
+
+ private string m_AxisName;
+ public string axisName { set { m_AxisName = value; } }
+
+ public OnAxis (GraphBehaviour graphBehaviour) : base (graphBehaviour) { }
+ public OnAxis (IMonoBehaviourEventCaller graphBehaviour, string axisName) : base (graphBehaviour)
+ {
+ m_AxisName = axisName;
+ }
+
+ protected override void OnUpdate ()
+ {
+ if (down == null && up == null)
+ return;
+
+ m_Value = Input.GetAxis (m_AxisName);
+
+ var stateDelegate = Input.GetButton (m_AxisName) ? down : up;
+ if (stateDelegate != null)
+ stateDelegate ();
+ }
+ }
+ }
+}
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnButton.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnButton.cs
new file mode 100644
index 0000000..a5d0809
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnButton.cs
@@ -0,0 +1,38 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public partial class InputNodes
+ {
+ [Logic]
+ [Title("Input/On Button")]
+ public sealed class OnButton : OnStateInputNode
+ {
+ private string m_ButtonName;
+ public string buttonName { set { m_ButtonName = value; } }
+
+ public OnButton (GraphBehaviour graphBehaviour) : base (graphBehaviour) { }
+ public OnButton (IMonoBehaviourEventCaller graphBehaviour, string buttonName) : base (graphBehaviour)
+ {
+ m_ButtonName = buttonName;
+ }
+
+ protected override void OnUpdate ()
+ {
+ if (onDown != null && Input.GetButtonDown (m_ButtonName))
+ onDown ();
+
+ if (onUp != null && Input.GetButtonUp (m_ButtonName))
+ onUp ();
+
+ if (down != null || up != null)
+ {
+ var stateDelegate = Input.GetButton (m_ButtonName) ? down : up;
+ if (stateDelegate != null)
+ stateDelegate ();
+ }
+ }
+ }
+ }
+}
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnInputNode.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnInputNode.cs
new file mode 100644
index 0000000..70032f2
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnInputNode.cs
@@ -0,0 +1,50 @@
+using System;
+
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public partial class InputNodes
+ {
+ public abstract class OnInputNode
+ {
+ protected IMonoBehaviourEventCaller m_GraphBehaviour;
+
+ protected float m_DeltaTime;
+ public float deltaTime { get { return m_DeltaTime; } }
+
+ public Action down;
+ public Action up;
+
+ protected OnInputNode () { }
+
+ protected OnInputNode (GraphBehaviour graphBehaviour)
+ {
+ m_GraphBehaviour = graphBehaviour;
+ m_GraphBehaviour.OnUpdate += OnBaseUpdate;
+ }
+
+ protected OnInputNode (IMonoBehaviourEventCaller graphBehaviour)
+ {
+ m_GraphBehaviour = graphBehaviour;
+ m_GraphBehaviour.OnUpdate += OnBaseUpdate;
+ }
+
+ private void OnBaseUpdate (float deltaTime)
+ {
+ m_DeltaTime = deltaTime;
+ OnUpdate ();
+ }
+
+ protected abstract void OnUpdate ();
+ }
+
+ public abstract class OnStateInputNode : OnInputNode
+ {
+ public Action onDown;
+ public Action onUp;
+
+ protected OnStateInputNode (GraphBehaviour graphBehaviour) : base (graphBehaviour) { }
+ protected OnStateInputNode (IMonoBehaviourEventCaller graphBehaviour) : base (graphBehaviour) { }
+ }
+ }
+}
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnKey.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnKey.cs
new file mode 100644
index 0000000..64732f7
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnKey.cs
@@ -0,0 +1,38 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public partial class InputNodes
+ {
+ [Logic]
+ [Title("Input/On Key")]
+ public sealed class OnKey : OnStateInputNode
+ {
+ private KeyCode m_Key;
+ public KeyCode key { set { m_Key = value; } }
+
+ public OnKey (GraphBehaviour graphBehaviour) : base (graphBehaviour) { }
+ public OnKey (IMonoBehaviourEventCaller graphBehaviour, KeyCode key) : base (graphBehaviour)
+ {
+ m_Key = key;
+ }
+
+ protected override void OnUpdate ()
+ {
+ if (onDown != null && Input.GetKeyDown (m_Key))
+ onDown ();
+
+ if (onUp != null && Input.GetKeyUp (m_Key))
+ onUp ();
+
+ if (down != null || up != null)
+ {
+ var stateDelegate = Input.GetKey (m_Key) ? down : up;
+ if (stateDelegate != null)
+ stateDelegate ();
+ }
+ }
+ }
+ }
+}
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnMouseButton.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnMouseButton.cs
new file mode 100644
index 0000000..544a1e8
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Input/OnMouseButton.cs
@@ -0,0 +1,38 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public partial class InputNodes
+ {
+ [Logic]
+ [Title("Input/On Mouse Button")]
+ public sealed class OnMouseButton : OnStateInputNode
+ {
+ private int m_MouseButton;
+ public int mouseButton { set { m_MouseButton = value; } }
+
+ public OnMouseButton (GraphBehaviour graphBehaviour) : base (graphBehaviour) { }
+ public OnMouseButton (IMonoBehaviourEventCaller graphBehaviour, int mouseButton) : base (graphBehaviour)
+ {
+ m_MouseButton = mouseButton;
+ }
+
+ protected override void OnUpdate ()
+ {
+ if (onDown != null && Input.GetMouseButtonDown (m_MouseButton))
+ onDown ();
+
+ if (onUp != null && Input.GetMouseButtonUp (m_MouseButton))
+ onUp ();
+
+ if (down != null || up != null)
+ {
+ var stateDelegate = Input.GetMouseButton (m_MouseButton) ? down : up;
+ if (stateDelegate != null)
+ stateDelegate ();
+ }
+ }
+ }
+ }
+}
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/LogicNodeUtility.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/LogicNodeUtility.cs
new file mode 100644
index 0000000..1caca64
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/LogicNodeUtility.cs
@@ -0,0 +1,5 @@
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public delegate void Action ();
+}
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Material/MaterialNodes.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Material/MaterialNodes.cs
new file mode 100644
index 0000000..734968b
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Material/MaterialNodes.cs
@@ -0,0 +1,113 @@
+using UnityEngine;
+using System.Collections;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public class MaterialNodes
+ {
+ #if REIMPLEMENT_USING_CLASS_NODES
+ [Logic(typeof(Renderer), typeof(NodeLibrary.StartStopEvents))]
+ public static IEnumerator UVScroll (Renderer self, ByRef<NodeLibrary.StartStopEvents> evt, string property, Vector2 magnitude, float frequency, int mode)
+ {
+ Material mat = self.material;
+ if (property == null || property == "")
+ property = "_MainTex";
+
+ if (mode == 0)
+ {
+ while (true)
+ {
+ // scroll uv
+ Vector2 uv = mat.GetTextureOffset(property);
+ uv += magnitude * Time.deltaTime;
+ mat.SetTextureOffset(property, uv);
+
+ // Handle Stop event
+ if (evt.Value == NodeLibrary.StartStopEvents.Stop)
+ break;
+ yield return 0;
+ }
+ }
+ else
+ {
+ // Elapsed time, measured in cycles.
+ float elapsed = 0;
+
+ Vector2 lastUV = mat.GetTextureOffset(property);
+
+ float stopElapsed = 0f;
+ bool exit = false;
+
+ while (true)
+ {
+ // Handle Stop event
+ if (evt.Value == NodeLibrary.StartStopEvents.Stop)
+ {
+ // When stopping, complete the current cycle before really stopping
+ // Update: Actually we only need to complete the current half-cycle
+ // because the cycle always has the same value in the middle as in the beginning and end.
+ if (stopElapsed == 0)
+ stopElapsed = Mathf.Ceil(elapsed * 2) * 0.5f;
+
+ // When we reach the end of the cycle, stop at the exact time
+ else if (elapsed >= stopElapsed)
+ {
+ elapsed = stopElapsed;
+ exit = true;
+ }
+ }
+
+ Vector2 uv = Vector2.zero;
+ // Triangle wave (centered around 0)
+ if (mode == 1)
+ uv += magnitude * (Mathf.PingPong(elapsed * 2f + 0.5f, 1) - 0.5f);
+ // Sine wave (centered around 0)
+ if (mode == 2)
+ uv += magnitude * 0.5f * Mathf.Sin(elapsed * 2f * Mathf.PI);
+
+ mat.SetTextureOffset(property, mat.GetTextureOffset(property) + (uv - lastUV));
+ lastUV = uv;
+
+ if (exit)
+ break;
+
+ elapsed += Time.deltaTime * frequency;
+
+ yield return 0;
+ }
+ }
+
+ }
+
+ [Logic(typeof(Renderer), typeof(NodeLibrary.StartStopEvents))]
+ public static IEnumerator UVCycler (Renderer self, ByRef<NodeLibrary.StartStopEvents> evt, string property, int xTiles, int yTiles, float speed)
+ {
+ Material mat = self.material;
+ if (property == null || property == "")
+ property = "_MainTex";
+
+ // TODO: find out what initial frame is based on uv offset in the beginning?
+
+ float elapsed = 0;
+ while (true)
+ {
+ int frame = Mathf.FloorToInt(elapsed);
+
+ float xOffset = frame % xTiles;
+ float yOffset = yTiles - 1 - (frame / xTiles) % yTiles;
+
+ Vector2 uv = new Vector2(xOffset / xTiles, yOffset / yTiles);
+ mat.SetTextureOffset(property, uv);
+
+ // Handle Stop event
+ if (evt.Value == NodeLibrary.StartStopEvents.Stop)
+ break;
+
+ elapsed += Time.deltaTime * speed;
+
+ yield return 0;
+ }
+ }
+ #endif
+ }
+}
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/NodeLibrary.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/NodeLibrary.cs
new file mode 100644
index 0000000..4723b37
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/NodeLibrary.cs
@@ -0,0 +1,94 @@
+using System.Collections;
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public class NodeLibrary
+ {
+ public enum ToggleEnum { On, Off, Toggle }
+
+ public static string version
+ {
+ get { return "0.3a"; }
+ }
+
+ // this is actually used, leave here when cleaning up this class
+ public static float Iff(bool a, float t, float f)
+ {
+ return a ? t : f;
+ }
+
+ public static int Iffint(bool a, int t, int f)
+ {
+ return a ? t : f;
+ }
+
+ public static bool IsTrigger(Collider target)
+ {
+ return target.isTrigger;
+ }
+
+ public static bool IsNotTrigger(Collider target)
+ {
+ return !target.isTrigger;
+ }
+
+ [Logic]
+ [Title("Logic/Log")]
+ public static void Log (string str)
+ {
+ Debug.Log(str);
+ }
+
+ [Logic]
+ [Title("Logic/Wait")]
+ public static IEnumerator Wait (float waitSeconds)
+ {
+ yield return new WaitForSeconds(waitSeconds);
+ }
+
+ [Logic]
+ [Title("Logic/Timer")]
+ public static IEnumerator Timer (float waitSeconds, int repeatCount, Action tick, Action done)
+ {
+ for (int i = 0; i < repeatCount; i++)
+ {
+ yield return new WaitForSeconds(waitSeconds);
+ if (tick != null)
+ tick();
+ }
+
+ if (done != null)
+ done();
+ }
+
+ [Logic]
+ [Title("Logic/Nop")]
+ public static T Nop<T>(T arg)
+ {
+ return arg;
+ }
+
+ [Logic]
+ [Title("Object/Instantiate")]
+ [return: Title("Instantiated Object")]
+ public static Object Instantiate ([Title("Object")] Object obj, Vector3 position, Quaternion rotation)
+ {
+ return Object.Instantiate(obj, position, rotation);
+ }
+
+ [Logic]
+ [Title("Object/Destroy")]
+ public static void Destroy ([Title("Object")] Object obj)
+ {
+ Object.Destroy(obj);
+ }
+
+ [Logic]
+ [Title("Object/Dont Destroy On Load")]
+ public static void DontDestroyOnLoad([Title("Object")] Object obj)
+ {
+ Object.DontDestroyOnLoad (obj);
+ }
+ }
+}
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/NodeLibraryForTesting.txt b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/NodeLibraryForTesting.txt
new file mode 100644
index 0000000..7a69517
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/NodeLibraryForTesting.txt
@@ -0,0 +1,124 @@
+ [Logic]
+ public static void ExplosionForce (float force, Vector3 position, float radius, float upwardsModifier, float occlusion)
+ {
+ // Get all colliders in radius
+ Collider[] colliders = Physics.OverlapSphere(position, radius);
+
+ // Get all of those that have rigidbodies
+ List<Rigidbody> rigids = new List<Rigidbody> ();
+ foreach (Collider col in colliders)
+ {
+ Rigidbody rigid = col.rigidbody;
+ if (rigid != null)
+ rigids.Add(rigid);
+ }
+
+ if (occlusion <= 0)
+ {
+ // Apply the explosion force
+ for (int i=0; i<rigids.Count; i++)
+ {
+ rigids[i].AddExplosionForce(force, position, radius, upwardsModifier, ForceMode.Impulse);
+ }
+ }
+ else
+ {
+ // Save original layers of all the rigidbodies
+ // Then but them into Ignore Raycast layer
+ int[] origLayers = new int[rigids.Count];
+ for (int i=0; i<rigids.Count; i++)
+ {
+ origLayers[i] = rigids[i].gameObject.layer;
+ rigids[i].gameObject.layer = 2; // Ignore Raycast
+ }
+
+ // Find out which of the rigidbodies are occuded
+ bool[] occluded = new bool[rigids.Count];
+ for (int i=0; i<rigids.Count; i++)
+ {
+ Vector3 pos = rigids[i].transform.position;
+ if (Physics.Raycast(pos, position - pos, (position - pos).magnitude))
+ occluded[i] = true;
+ }
+
+ // Set layers back to the original values
+ for (int i=0; i<rigids.Count; i++)
+ {
+ rigids[i].gameObject.layer = origLayers[i];
+ }
+
+ // Finally apply the explosion force
+ float mult = Mathf.Clamp01(1-occlusion);
+ for (int i=0; i<rigids.Count; i++)
+ {
+ float thisForce = force;
+ if (occluded[i])
+ thisForce *= mult;
+ rigids[i].AddExplosionForce(thisForce, position, radius, upwardsModifier, ForceMode.Impulse);
+ }
+ }
+ }
+ [Logic]
+ public static void FindCollidersInRadius (Vector3 center, float radius, ColliderDelegate affected, ColliderDelegate done)
+ {
+ Collider[] colliders = Physics.OverlapSphere(center, radius);
+ foreach (Collider col in colliders)
+ {
+ affected(col);
+ }
+ if (done == null)
+ Debug.LogWarning("done delegate is null");
+ else
+ done(colliders[0]);
+ }
+
+ [Logic]
+ public static float AssignFloat (float value)
+ {
+ return value;
+ }
+
+ // Eval
+ [LogicEval]
+ public static Vector3 Vector3FromFloats (float x, float y, float z)
+ {
+ return new Vector3(x, y, z);
+ }
+
+ public enum Vector3Element {X, Y, Z}
+ [LogicEval]
+ public static float ElementFromVector3 (Vector3 vector, Vector3Element element)
+ {
+ switch (element)
+ {
+ case Vector3Element.X:
+ return vector.x;
+ case Vector3Element.Y:
+ return vector.y;
+ case Vector3Element.Z:
+ return vector.z;
+ default:
+ return 0f;
+ }
+ }
+
+ [LogicEval]
+ public static Vector3 ScaleVector (Vector3 vector, float scalar)
+ {
+ return vector * scalar;
+ }
+
+ [LogicEval]
+ public static Vector3 AddVectors (Vector3 vector1, Vector3 vector2)
+ {
+ return vector1 + vector2;
+ }
+
+ [LogicEval]
+ public static Vector3 InverseDistVector (Vector3 from, Vector3 to, float multiplier)
+ {
+ float dist = Vector3.Distance(from, to);
+ if (dist == 0)
+ return Vector3.zero;
+ return (to - from) / (dist * dist) * multiplier;
+ }
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Rigidbody/RigidbodyNodes.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Rigidbody/RigidbodyNodes.cs
new file mode 100644
index 0000000..d151a62
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Rigidbody/RigidbodyNodes.cs
@@ -0,0 +1,104 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public class RigidbodyNode
+ {
+ #if REIMPLEMENT_USING_CLASS_NODES
+ [Logic(typeof(Rigidbody), typeof(NodeLibrary.StartStopEvents))]
+ public static IEnumerator Force (Rigidbody self, ByRef<NodeLibrary.StartStopEvents> evt, Vector3 force, bool localSpace, bool ignoreMass)
+ {
+ if (evt.Value == NodeLibrary.StartStopEvents.Stop)
+ yield break;
+ if (self)
+ {
+ ForceMode mode = (ignoreMass ? ForceMode.Acceleration : ForceMode.Force);
+
+ if (localSpace)
+ {
+ while (evt.Value != NodeLibrary.StartStopEvents.Stop)
+ {
+ yield return new WaitForFixedUpdate();
+ self.AddRelativeForce(force, mode);
+ }
+ }
+ else
+ {
+ while (evt.Value != NodeLibrary.StartStopEvents.Stop)
+ {
+ yield return new WaitForFixedUpdate();
+ self.AddForce(force, mode);
+ }
+ }
+ }
+ else
+ Debug.LogWarning("Force self parameter is null");
+ }
+
+ [Logic(typeof(Rigidbody), typeof(NodeLibrary.StartStopEvents))]
+ public static IEnumerator Torque (Rigidbody self, ByRef<NodeLibrary.StartStopEvents> evt, Vector3 torque, bool localSpace, bool ignoreMass)
+ {
+ if (evt.Value == NodeLibrary.StartStopEvents.Stop)
+ yield break;
+ if (self)
+ {
+ ForceMode mode = (ignoreMass ? ForceMode.Acceleration : ForceMode.Force);
+
+ if (localSpace)
+ {
+ while (evt.Value != NodeLibrary.StartStopEvents.Stop)
+ {
+ yield return new WaitForFixedUpdate();
+ self.AddRelativeTorque(torque, mode);
+ }
+ }
+ else
+ {
+ while (evt.Value != NodeLibrary.StartStopEvents.Stop)
+ {
+ yield return new WaitForFixedUpdate();
+ self.AddTorque(torque, mode);
+ }
+ }
+ }
+ else
+ Debug.LogWarning("Torque self parameter is null");
+ }
+ #endif
+
+ [Logic(typeof(Rigidbody))]
+ public static void ApplyForce (Rigidbody self, Vector3 force, Space relativeTo, ForceMode forceMode)
+ {
+ if (relativeTo == Space.Self)
+ self.AddRelativeForce(force, forceMode);
+ else
+ self.AddForce(force, forceMode);
+ }
+
+ [Logic(typeof(Rigidbody))]
+ public static void ApplyTorque (Rigidbody self, Vector3 torque, Space relativeTo, ForceMode forceMode)
+ {
+ if (relativeTo == Space.Self)
+ self.AddRelativeTorque(torque, forceMode);
+ else
+ self.AddTorque(torque, forceMode);
+ }
+
+ [Logic(typeof(Rigidbody))]
+ public static void SetVelocity (Rigidbody self, Vector3 velocity, Space relativeTo)
+ {
+ if (relativeTo == Space.Self)
+ velocity = self.transform.rotation * velocity;
+ self.velocity = velocity;
+ }
+
+ [Logic(typeof(Rigidbody))]
+ public static void SetAngularVelocity (Rigidbody self, Vector3 angularVelocity, Space relativeTo)
+ {
+ if (relativeTo == Space.Self)
+ angularVelocity = self.transform.rotation * angularVelocity;
+ self.angularVelocity = angularVelocity;
+ }
+ }
+
+}
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/LookAt.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/LookAt.cs
new file mode 100644
index 0000000..4ba9bd0
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/LookAt.cs
@@ -0,0 +1,46 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public partial class TransformNodes
+ {
+ [Logic(typeof(Transform))]
+ public sealed class LookAt : YieldedTransformNodeBase
+ {
+ private readonly ILookAtRotationCalculator m_RotationCalculator;
+ private Quaternion m_InitialRotation;
+ private Vector3 m_TargetRelativePosition;
+
+ public override Transform target { set { m_Target = value; } }
+ public Vector3 targetOffset { set { m_TargetRelativePosition = value; } }
+
+
+ public LookAt ()
+ {
+ m_RotationCalculator = StandardLookAtRotationCalculator.s_Instance;
+ }
+
+ public LookAt (Transform self, Transform target, Vector3 targetRelativePosition, float time, ILookAtRotationCalculator rotationCalculator) : base (self, target, time)
+ {
+ m_TargetRelativePosition = targetRelativePosition;
+ m_RotationCalculator = rotationCalculator;
+ }
+
+ protected override void OnStart()
+ {
+ m_InitialRotation = self.rotation;
+ }
+
+ protected override void OnUpdate()
+ {
+ self.rotation = m_RotationCalculator.CalculateRotation(self, m_Target, m_TargetRelativePosition, m_InitialRotation, m_Percentage, m_Curve);
+ }
+
+ protected override void OnDone()
+ {
+ self.rotation = m_RotationCalculator.CalculateRotation(self, m_Target, m_TargetRelativePosition, m_InitialRotation, 1.0f, m_Curve);
+ }
+ }
+ }
+}
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/MoveTo.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/MoveTo.cs
new file mode 100644
index 0000000..b60454c
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/MoveTo.cs
@@ -0,0 +1,45 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public partial class TransformNodes
+ {
+ [Logic (typeof (Transform))]
+ public sealed class MoveTo : YieldedTransformNodeBase
+ {
+ private readonly IMoveToPositionCalculator m_PositionCalculator;
+ private Vector3 m_InitialPosition;
+ private Vector3 m_TargetRelativePosition;
+
+ public override Transform target { set { m_Target = value; } }
+ public Vector3 targetOffset { set { m_TargetRelativePosition = value; } }
+
+ public MoveTo()
+ {
+ m_PositionCalculator = StandardMoveToPositionCalculator.s_Instance;
+ }
+
+ public MoveTo(Transform self, Transform target, Vector3 targetRelativePosition, float time, IMoveToPositionCalculator positionCalculator) : base (self, target, time)
+ {
+ m_TargetRelativePosition = targetRelativePosition;
+ m_PositionCalculator = positionCalculator;
+ }
+
+
+ protected override void OnStart()
+ {
+ m_InitialPosition = self.position;
+ }
+
+ protected override void OnUpdate()
+ {
+ self.position = m_PositionCalculator.CalculatePosition(m_Target, m_TargetRelativePosition, m_InitialPosition, m_Percentage, m_Curve);
+ }
+
+ protected override void OnDone()
+ {
+ self.position = m_PositionCalculator.CalculatePosition(m_Target, m_TargetRelativePosition, m_InitialPosition, 1.0f, m_Curve);
+ }
+ }
+ }
+}
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/RotateTo.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/RotateTo.cs
new file mode 100644
index 0000000..8b44479
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/RotateTo.cs
@@ -0,0 +1,45 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public partial class TransformNodes
+ {
+ [Logic (typeof (Transform))]
+ public sealed class RotateTo : YieldedTransformNodeBase
+ {
+ private readonly IRotateToRotationCalculator m_RotationCalculator;
+ private Quaternion m_InitialRotation;
+ private Quaternion m_TargetRelativeRotation;
+
+ public override Transform target { set { m_Target = value; } }
+ public Quaternion targetOffset { set { m_TargetRelativeRotation = value; } }
+
+ public RotateTo ()
+ {
+ m_RotationCalculator = StandardRotateToRotationCalculator.s_Instance;
+ }
+
+ public RotateTo (Transform self, Transform target, Quaternion targetRelativeRotation, float time, IRotateToRotationCalculator rotationCalculator)
+ : base (self, target, time)
+ {
+ m_TargetRelativeRotation = targetRelativeRotation;
+ m_RotationCalculator = rotationCalculator;
+ }
+
+ protected override void OnStart ()
+ {
+ m_InitialRotation = self.rotation;
+ }
+
+ protected override void OnUpdate ()
+ {
+ self.rotation = m_RotationCalculator.CalculateRotation (m_Target, m_TargetRelativeRotation, m_InitialRotation, m_Percentage, m_Curve);
+ }
+
+ protected override void OnDone ()
+ {
+ self.rotation = m_RotationCalculator.CalculateRotation (m_Target, m_TargetRelativeRotation, m_InitialRotation, 1.0f, m_Curve);
+ }
+ }
+ }
+}
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/TransformNodes.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/TransformNodes.cs
new file mode 100644
index 0000000..5e99275
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/TransformNodes.cs
@@ -0,0 +1,122 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public partial class TransformNodes
+ {
+ #region Nodes
+ [Logic(typeof(Transform))]
+ public static void Translate(Transform self, Vector3 translation, Space relativeTo)
+ {
+ self.Translate(translation, relativeTo);
+ }
+
+ [Logic(typeof(Transform))]
+ public static void Rotate(Transform self, Vector3 axis, float angle, Space relativeTo)
+ {
+ self.Rotate(axis, angle, relativeTo);
+ }
+
+ [Logic(typeof(Transform))]
+ public static void Mimic(Transform self, Transform target, bool mimicPosition, bool mimicRotation, bool mimicScale, bool useLocalSpace)
+ {
+ if (mimicPosition)
+ if (useLocalSpace)
+ self.localPosition = target.localPosition;
+ else
+ self.position = target.position;
+
+ if (mimicRotation)
+ if (useLocalSpace)
+ self.localRotation = target.localRotation;
+ else
+ self.rotation = target.rotation;
+
+ if (mimicScale)
+ self.localScale = target.localScale;
+ }
+
+ [LogicEval(typeof(Transform))]
+ [Title("Get Position")]
+ public static Vector3 GetPosition(Transform target)
+ {
+ if (target == null)
+ return Vector3.zero;
+ return target.position;
+ }
+
+ [Logic(typeof(Transform))]
+ [Title("Set Position")]
+ public static void SetPosition(Transform target, Vector3 position)
+ {
+ if (target == null)
+ return;
+ target.position = position;
+ }
+ #endregion
+
+ #region Node Helpers
+ private static Quaternion LookAtLookRotation(Transform self, Transform target, Vector3 targetRelativePosition)
+ {
+ return Quaternion.LookRotation(AbsoluteTargetPosition(target, targetRelativePosition) - self.position);
+ }
+
+ private static Vector3 AbsoluteTargetPosition(Transform target, Vector3 targetRelativePosition)
+ {
+ if (target != null)
+ return target.position + targetRelativePosition;
+ return targetRelativePosition;
+ }
+ #endregion
+
+ #region Transform Calculators
+ public interface IMoveToPositionCalculator
+ {
+ Vector3 CalculatePosition (Transform target, Vector3 targetRelativePosition, Vector3 initialPosition, float percentage, AnimationCurve curve);
+ }
+
+ class StandardMoveToPositionCalculator : IMoveToPositionCalculator
+ {
+ public static readonly IMoveToPositionCalculator s_Instance = new StandardMoveToPositionCalculator ();
+
+ public Vector3 CalculatePosition (Transform target, Vector3 targetRelativePosition, Vector3 initialPosition, float percentage, AnimationCurve curve)
+ {
+ return Vector3.Lerp (initialPosition, AbsoluteTargetPosition (target, targetRelativePosition), curve.Evaluate (percentage));
+ }
+ }
+
+
+ public interface IRotateToRotationCalculator
+ {
+ Quaternion CalculateRotation (Transform target, Quaternion targetRelativeRotation, Quaternion initialRotation, float percentage, AnimationCurve curve);
+ }
+
+ class StandardRotateToRotationCalculator : IRotateToRotationCalculator
+ {
+ public static readonly IRotateToRotationCalculator s_Instance = new StandardRotateToRotationCalculator ();
+
+ public Quaternion CalculateRotation (Transform target, Quaternion targetRelativeRotation, Quaternion initialRotation, float percentage, AnimationCurve curve)
+ {
+ return Quaternion.Lerp (initialRotation, targetRelativeRotation * target.rotation, curve.Evaluate (percentage));
+ }
+ }
+
+
+ public interface ILookAtRotationCalculator
+ {
+ Quaternion CalculateRotation (Transform self, Transform target, Vector3 targetRelativePosition, Quaternion initialRotation, float percentage, AnimationCurve curve);
+ }
+
+ class StandardLookAtRotationCalculator : ILookAtRotationCalculator
+ {
+ public static readonly ILookAtRotationCalculator s_Instance = new StandardLookAtRotationCalculator ();
+
+ public Quaternion CalculateRotation (Transform self, Transform target, Vector3 targetRelativePosition, Quaternion initialRotation, float percentage, AnimationCurve curve)
+ {
+ return Quaternion.Lerp (initialRotation, LookAtLookRotation (self, target, targetRelativePosition), curve.Evaluate (percentage));
+ }
+ }
+ #endregion
+ }
+}
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/YieldedTransformNodeBase.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/YieldedTransformNodeBase.cs
new file mode 100644
index 0000000..e95f699
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Transform/YieldedTransformNodeBase.cs
@@ -0,0 +1,27 @@
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public abstract class YieldedTransformNodeBase : YieldedNodeBase
+ {
+ [LogicTarget]
+ public Transform self;
+
+ protected Transform m_Target;
+ protected AnimationCurve m_Curve;
+
+ public virtual Transform target { set { m_Target = value; } }
+ public virtual AnimationCurve curve { set { m_Curve = value; } }
+
+ protected YieldedTransformNodeBase ()
+ {
+ m_Curve = new AnimationCurve ();
+ }
+
+ protected YieldedTransformNodeBase (Transform self, Transform target, float time) : base (time)
+ {
+ this.self = self;
+ m_Target = target;
+ }
+ }
+}
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/YieldedNodeBase.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/YieldedNodeBase.cs
new file mode 100644
index 0000000..2086d95
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/YieldedNodeBase.cs
@@ -0,0 +1,54 @@
+using System.Collections;
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public abstract class YieldedNodeBase
+ {
+ protected float m_Time;
+ protected float m_Percentage;
+
+ public Action done;
+ public Action update;
+
+ public virtual float totalTime { set { m_Time = value; } }
+ public virtual float percentage { get { return m_Percentage; } }
+
+ protected YieldedNodeBase () {}
+
+ protected YieldedNodeBase (float time)
+ {
+ m_Time = time;
+ }
+
+ public IEnumerator Start ()
+ {
+ OnStart ();
+
+ if (m_Time > 0.0f)
+ {
+ float doneTime = Time.time + m_Time;
+ float t = 0;
+ do
+ {
+ t += Time.deltaTime;
+ m_Percentage = t / m_Time;
+
+ OnUpdate();
+ if (update != null)
+ update();
+
+ yield return 0;
+ } while (Time.time < doneTime);
+ }
+
+ OnDone();
+ if (done != null)
+ done();
+ }
+
+ protected abstract void OnStart ();
+ protected abstract void OnUpdate ();
+ protected abstract void OnDone ();
+ }
+}
diff --git a/Runtime/Graphs/UnityEngine.Graphs/LogicNodeTestLibrary.cs b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeTestLibrary.cs
new file mode 100644
index 0000000..b92555a
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/LogicNodeTestLibrary.cs
@@ -0,0 +1,359 @@
+
+#if NOT
+// Nodes for trying-out purposes. Complete mess.
+
+using System.Collections;
+using UnityEngine;
+using EmptyDelegate = UnityEngine.Graphs.LogicGraph.LogicNodeUtility.EmptyDelegate;
+using ColliderDelegate = UnityEngine.Graphs.LogicGraph.NodeLibrary.ColliderDelegate;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ public class LogicNodeTestLibrary
+ {
+ [Logic]
+ public static IEnumerator DoSomethingWithAnimationCurve(AnimationCurve curve)
+ {
+ var go = GameObject.Find("Cube");
+
+ for (float f = 0; f < 2f; f+=0.01f)
+ {
+ go.transform.Rotate(new Vector3(curve.Evaluate(f) * 10f, 0,0));
+ yield return new WaitForFixedUpdate();
+ }
+ }
+
+ [Logic]
+ public class LimitedInvoker
+ {
+ public int invokeTimes = 500;
+ int currentInvokeIndex = 0;
+
+ public delegate void VoidDelegate();
+
+ public VoidDelegate myOut;
+
+ public void In()
+ {
+ if (++currentInvokeIndex > invokeTimes)
+ return;
+
+ if (currentInvokeIndex % 500 == 0)
+ Debug.Log(currentInvokeIndex);
+
+ if (myOut != null)
+ myOut();
+ }
+ }
+
+ [Logic(null, null, typeof(int))]
+ public static void Counter(ref int state, int UpTo, EmptyDelegate done)
+ {
+ state++;
+ if (state >= UpTo)
+ if (done != null)
+ done();
+ }
+
+ [Logic]
+ public static void HasTag(GameObject go, string tag, EmptyDelegate True, EmptyDelegate False)
+ {
+ if (go.tag == tag)
+ {
+ if (True != null)
+ True();
+ }
+ else
+ {
+ if (False != null)
+ False();
+ }
+ }
+
+ [Logic]
+ public static event EmptyDelegate StaticEvent;
+
+ public static void CauseStaticEvent()
+ {
+ if (StaticEvent != null)
+ StaticEvent();
+ }
+
+ // Enums for in slots
+ public enum StartStopEvents { Start, Stop }
+ public enum StartPauseStopEvents { Start, Pause, Stop }
+
+ [LogicEval(typeof(Transform))]
+ public static float GetPositionY(Transform self)
+ {
+ return self.position.y;
+ }
+
+ [Logic]
+ public static string PassString()
+ {
+ return "Some String";
+ }
+
+ [Logic]
+ public static string AddStrings(string a, string b)
+ {
+ return a + " + " + b;
+ }
+
+ [Logic]
+ public static void LogCollidersGO(Collider collider)
+ {
+ Debug.Log("Ouch!.. " + collider.gameObject.name);
+ }
+
+ [Logic(typeof(Collider))]
+ public static void ColliderFunction(Collider self)
+ {
+ Debug.Log("ColliderFunction " + self.gameObject.name);
+ }
+
+ [Logic]
+ public static IEnumerator YieldedFunction(string strParam)
+ {
+ yield return new WaitForSeconds(3);
+ Debug.Log(strParam);
+ }
+
+ public enum MyActions { Start, Stop, Pause }
+
+ [Logic(typeof(AudioSource), typeof(MyActions))]
+ public static void PlayAudio(AudioSource self, MyActions action)
+ {
+ switch (action)
+ {
+ case MyActions.Start:
+ self.Play();
+ break;
+ case MyActions.Stop:
+ self.Stop();
+ break;
+ case MyActions.Pause:
+ self.Pause();
+ break;
+ }
+ }
+
+ public class Expressions
+ {
+ [LogicExpression]
+ public static int CustomFn(int f)
+ {
+ return f*f;
+ }
+
+ [LogicExpression]
+ public static float Prop
+ {
+ get
+ {
+ return 3f;
+ }
+ }
+ }
+
+ [Logic]
+ public static int intVar;
+
+ [Logic]
+ public static string strProperty { get { return "0"; } set { Debug.Log("setting to: " + value); } }
+
+ [Logic]
+ public static int SetInt (int a)
+ {
+ return a;
+ }
+
+ [Logic]
+ public static void EvaluateBool (bool b, EmptyDelegate True, EmptyDelegate False)
+ {
+ if (b)
+ True();
+ else
+ False();
+ }
+
+ [Logic]
+ public static void Destroy (GameObject self)
+ {
+ Object.Destroy(self);
+ }
+
+ [Logic]
+ public static GameObject Instantiate (GameObject obj, Vector3 position, Quaternion rotation)
+ {
+ return (GameObject)GameObject.Instantiate(obj, position, rotation);
+ }
+
+ [Logic]
+ public static void Do() { }
+
+ [Logic]
+ public static void FindCollidersInRadius (Vector3 center, float radius, ColliderDelegate affected, ColliderDelegate done)
+ {
+ Collider[] colliders = Physics.OverlapSphere(center, radius);
+ foreach (Collider col in colliders)
+ {
+ affected(col);
+ }
+ if (done == null)
+ Debug.LogWarning("done delegate is null");
+ else
+ done(colliders[0]);
+ }
+
+ // Eval
+
+ [LogicEval]
+ public static Vector3 Vector3FromFloats (float x, float y, float z)
+ {
+ return new Vector3(x, y, z);
+ }
+
+ [LogicEval]
+ public static int Add (int a, int b)
+ {
+ return a + b;
+ }
+
+ [LogicEval]
+ public static float Random (float min, float max)
+ {
+ return UnityEngine.Random.Range(min, max);
+ }
+
+ [LogicEval]
+ public static float InputAxis (string axisName)
+ {
+ return Input.GetAxis(axisName);
+ }
+
+ [LogicEval]
+ public static GameObject GameObjectVar (GameObject obj)
+ {
+ return obj;
+ }
+
+ [LogicEval]
+ public static Vector3 InverseDistVector (Vector3 from, Vector3 to, float multiplier)
+ {
+ float dist = Vector3.Distance(from, to);
+ if (dist == 0)
+ return Vector3.zero;
+ else
+ return (to - from) / (dist * dist) * multiplier;
+ }
+
+ }
+
+ [Logic]
+ public class NodeInClass
+ {
+ public int simpleVariable;
+ public string onlyGet
+ {
+ get { return string.Empty; }
+ }
+
+ public string onlySet
+ {
+ set { }
+ }
+
+ public delegate void VoidDelegate();
+ public VoidDelegate ExitLink1;
+ public VoidDelegate ExitLink2;
+
+ public void Input1() { Debug.Log("input1");}
+ public IEnumerator YieldedInput() { return null; }
+ }
+
+ [Logic(typeof(Collider))]
+ public class ColliderNodeInClass
+ {
+ public Collider target;
+ public void DoSomething() { Debug.Log(target);}
+ }
+
+ [Logic]
+ public class TitledStuff
+ {
+ public enum TitledEnum { [Title("Crazy")]Start, [Title("Thing")] Stop, [Title("ToDo")] Pause }
+
+ public delegate void TwoStringTitledDelegate([Title("String 1")]string str1, [Title("String 2")]string str2);
+ public delegate void TwoObjectsTitledEvent([Title("GO arg")]Object go, [Title("other arg")]Object other);
+
+ [Logic]
+ [Title("-::Custom Named Fn::-")]
+ [return: Title("My ÀÛT")]
+ public static int FunctionWithCustomTitles([Title("First variable")]string var1, [Title("Second variable")]int var2) { return 0; }
+
+ [Logic]
+ [Title("-::Custom Named delegate Fn::-")]
+ public static void CustomNameFnWithDelegates([Title("Str input")]string string1, [Title("Output 1")]TwoStringTitledDelegate out1, [Title("Output 2")]TwoStringTitledDelegate out2) { }
+
+ [Logic]
+ [Title("@#^@#$")]
+ public static TwoObjectsTitledEvent TitledEvent;
+
+ [Logic]
+ [Title("Ghy")]
+ public static int titledVar;
+ [Logic]
+ [Title("Ghy@$^")]
+ public static int titledProp { get { return 0; } }
+
+ [LogicEval]
+ [Title("Eval 123")]
+ [return: Title("Eval Ret")]
+ public static int TitledEval([Title("eval arg")]string str) { return 0; }
+
+ [Logic(null, typeof(TitledEnum))]
+ [Title("it's really titled")]
+ public static void TitledMultiInputFunction(TitledEnum actions, [Title("Var In 1")]int prm1, [Title("Var In 2")]string prm2) { }
+ }
+
+ [Logic]
+ [Title("-::Custom Named Class::-")]
+ public class CustomTitleNodeInClass
+ {
+ [Title("Var Custom")]
+ public int simpleVariable;
+
+ [Title("Property Custom")]
+ public string onlyGet { get { return string.Empty; } }
+
+ public delegate void VoidDelegate();
+ [Title("Exit link custom")]
+ public VoidDelegate ExitLink1;
+
+ [Title("Input custom")]
+ public void Input1() { }
+ }
+
+ [Logic]
+ public class ValidatingNodes
+ {
+ public delegate void GOEvent(GameObject go);
+ [Logic(typeof(GameObject)), Validate("MyValidate")] public static GOEvent ValidatedDelegate;
+ [Logic(typeof(GameObject)), Validate("MyValidate")] public static event GOEvent ValidatedEvent;
+
+ [Logic(typeof(GameObject)), Validate("MyValidate")]
+ public static void FunctionNodeWithValidate(GameObject target){}
+
+ public static bool MyValidate(GameObject target) { return target.name == "ShowMe"; }
+ }
+
+ [Logic(typeof(GameObject)), Validate("ValidatingNodes.MyValidate")]
+ public class ClassWithValidate
+ {
+ public GameObject target;
+ public void Input(){}
+ }
+}
+#endif \ No newline at end of file
diff --git a/Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/ColliderDummyBase.cs b/Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/ColliderDummyBase.cs
new file mode 100644
index 0000000..2d7efca
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/ColliderDummyBase.cs
@@ -0,0 +1,25 @@
+using System;
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ // For now we do triggers by attaching this MonoBehaviour to needed gameobjects. Class then sends events to logic graph nodes.
+ public abstract class ColliderDummyBase : MonoBehaviour
+ {
+ protected static Component AttachToCollider(Collider self, Type dummyType)
+ {
+ var attached = GetAndAddComponentIfNeeded(self.gameObject, dummyType);
+
+ if (attached == null)
+ throw new ArgumentException("Failed to attach Logic Graph Collider Event handler to a game object of component '" + self + "'.");
+
+ return attached;
+ }
+
+ private static Component GetAndAddComponentIfNeeded(GameObject go, Type type)
+ {
+ return go.GetComponent(type) ?? go.AddComponent(type);
+ }
+ }
+}
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/OnAnimationEventDummy.cs b/Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/OnAnimationEventDummy.cs
new file mode 100644
index 0000000..66bf531
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/OnAnimationEventDummy.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ // This component gets attached to a GameObject with Animation component and handles special LogicGraphEvent.
+ public class OnAnimationEventDummy : MonoBehaviour
+ {
+ private Dictionary<string, Action> m_Events = new Dictionary<string, Action> ();
+
+ public static void AttachToGameObject(Animation component, string eventName, Action delegateToCall)
+ {
+ var animEventDummy = component.gameObject.GetComponent (typeof (OnAnimationEventDummy)) as OnAnimationEventDummy ??
+ component.gameObject.AddComponent(typeof(OnAnimationEventDummy)) as OnAnimationEventDummy;
+
+ if (animEventDummy == null)
+ throw new ArgumentException("Failed to attach Logic Graph Animation Event handler to a game object of component '" + component + "'.");
+
+ animEventDummy.AddNewEvent(eventName, delegateToCall);
+ }
+
+ private void AddNewEvent(string eventName, Action delegateToCall)
+ {
+ if (!m_Events.ContainsKey(eventName))
+ m_Events.Add(eventName, delegateToCall);
+ else
+ m_Events[eventName] += delegateToCall;
+ }
+
+ public void LogicGraphEvent(string eventName)
+ {
+ Action delegateToCall;
+
+ if (!m_Events.TryGetValue(eventName, out delegateToCall))
+ {
+ Debug.LogError("Logic Graph failed to handle Animation Event '" + eventName + "'. Receiver was not found.");
+ return;
+ }
+
+ if (delegateToCall == null)
+ {
+ Debug.LogError("Logic Graph failed to handle Animation Event '" + eventName + "'. Receiver was null.");
+ return;
+ }
+
+ delegateToCall ();
+ }
+ }
+}
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/OnCollisionEventDummy.cs b/Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/OnCollisionEventDummy.cs
new file mode 100644
index 0000000..09ccc8a
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/OnCollisionEventDummy.cs
@@ -0,0 +1,43 @@
+using System;
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ // For now we do triggers by attaching this MonoBehaviour to needed gameobjects. Class then sends events to logic graph nodes.
+ public class OnCollisionEventDummy : ColliderDummyBase
+ {
+ public delegate void CollisionOutDelegate(Collision other);
+
+ private CollisionOutDelegate m_OnEnter;
+ private CollisionOutDelegate m_OnExit;
+ private CollisionOutDelegate m_OnStay;
+
+ public static void AttachToCollider(ColliderNodes.OnCollisionEvent node)
+ {
+ var attached = AttachToCollider(node.self, typeof(OnCollisionEventDummy)) as OnCollisionEventDummy;
+ attached.m_OnEnter += node.EnterDummy;
+ attached.m_OnExit += node.ExitDummy;
+ attached.m_OnStay += node.StayDummy;
+ }
+
+ public void OnCollisionEnter(Collision collision)
+ {
+ if (m_OnEnter == null)
+ return;
+ m_OnEnter (collision);
+ }
+ public void OnCollisionExit(Collision collision)
+ {
+ if (m_OnExit == null)
+ return;
+ m_OnExit(collision);
+ }
+ public void OnCollisionStay(Collision collision)
+ {
+ if (m_OnStay == null)
+ return;
+ m_OnStay(collision);
+ }
+ }
+}
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/OnMouseEventDummy.cs b/Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/OnMouseEventDummy.cs
new file mode 100644
index 0000000..c359edf
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/OnMouseEventDummy.cs
@@ -0,0 +1,41 @@
+using System;
+using UnityEngine;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ // For now we do triggers by attaching this MonoBehaviour to needed gameobjects. Class then sends events to logic graph nodes.
+ public class OnMouseEventDummy : ColliderDummyBase
+ {
+ private Action m_OnEnter;
+ private Action m_OnOver;
+ private Action m_OnExit;
+ private Action m_OnDown;
+ private Action m_OnUp;
+ private Action m_OnDrag;
+
+ public static void AttachToCollider (ColliderNodes.OnMouseEvent node)
+ {
+ var attached = AttachToCollider(node.self, typeof(OnMouseEventDummy)) as OnMouseEventDummy;
+ attached.m_OnEnter += node.enter;
+ attached.m_OnOver += node.over;
+ attached.m_OnExit += node.exit;
+ attached.m_OnDown += node.down;
+ attached.m_OnUp += node.up;
+ attached.m_OnDrag += node.drag;
+ }
+
+ public void OnMouseEnter () { CallEventDelegate (m_OnEnter); }
+ public void OnMouseOver () { CallEventDelegate (m_OnOver); }
+ public void OnMouseExit () { CallEventDelegate (m_OnExit); }
+ public void OnMouseDown () { CallEventDelegate (m_OnDown); }
+ public void OnMouseUp () { CallEventDelegate (m_OnUp); }
+ public void OnMouseDrag () { CallEventDelegate (m_OnDrag); }
+
+ protected static void CallEventDelegate(Action eventDelegate)
+ {
+ if (eventDelegate != null)
+ eventDelegate();
+ }
+ }
+}
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/OnTriggerEventDummy.cs b/Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/OnTriggerEventDummy.cs
new file mode 100644
index 0000000..992f240
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/MonoBehaviourEventDummies/OnTriggerEventDummy.cs
@@ -0,0 +1,40 @@
+using System;
+using UnityEngine;
+using System.Collections.Generic;
+
+namespace UnityEngine.Graphs.LogicGraph
+{
+ // For now we do triggers by attaching this MonoBehaviour to needed gameobjects. Class then sends events to logic graph nodes.
+ public class OnTriggerEventDummy : ColliderDummyBase
+ {
+ public delegate void TriggerOutDelegate (Collider other);
+ private TriggerOutDelegate m_OnEnter;
+ private TriggerOutDelegate m_OnExit;
+ private TriggerOutDelegate m_OnStay;
+
+ public static void AttachToCollider(ColliderNodes.OnTriggerEvent node)
+ {
+ var attached = AttachToCollider(node.self, typeof(OnTriggerEventDummy)) as OnTriggerEventDummy;
+ attached.m_OnEnter += node.EnterDummy;
+ attached.m_OnExit += node.ExitDummy;
+ attached.m_OnStay += node.StayDummy;
+ }
+
+ public void OnTriggerEnter(Collider other)
+ {
+ if (m_OnEnter != null)
+ m_OnEnter (other);
+ }
+ public void OnTriggerExit(Collider other)
+ {
+ if (m_OnExit != null)
+ m_OnExit(other);
+ }
+ public void OnTriggerStay(Collider other)
+ {
+ if (m_OnStay != null)
+ m_OnStay (other);
+ }
+ }
+}
+
diff --git a/Runtime/Graphs/UnityEngine.Graphs/TestHelpers.cs b/Runtime/Graphs/UnityEngine.Graphs/TestHelpers.cs
new file mode 100644
index 0000000..feb438b
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/TestHelpers.cs
@@ -0,0 +1,33 @@
+#if TESTING
+
+using UnityEngine;
+
+namespace UnityEngine.Graphs
+{
+ public class Testing
+ {
+ public class Object
+ {
+ public string name;
+ }
+
+ public class ObjectSub1 : Object { }
+ public class ObjectSub2 : Object { }
+
+ // fake animation curve. can't seem to be able to initialize real one out of Unity
+ public class AnimationCurve
+ {
+ public WrapMode postWrapMode;
+ public WrapMode preWrapMode;
+ public Keyframe[] keys;
+ public AnimationCurve(params Keyframe[] frames) { keys = frames; }
+ }
+
+ public static bool AmIRunningInMono()
+ {
+ // internet says this is a supported way of detecting mono runtime
+ return System.Type.GetType ("Mono.Runtime") != null;
+ }
+ }
+}
+#endif
diff --git a/Runtime/Graphs/UnityEngine.Graphs/UnityEngine.Graphs.csproj b/Runtime/Graphs/UnityEngine.Graphs/UnityEngine.Graphs.csproj
new file mode 100644
index 0000000..7f3a47b
--- /dev/null
+++ b/Runtime/Graphs/UnityEngine.Graphs/UnityEngine.Graphs.csproj
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{10E97B21-AEA1-4E95-BC6B-717815F18EBE}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <RootNamespace>UnityEngine.Graphs</RootNamespace>
+ <AssemblyName>UnityEngine.Graphs</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation />
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>TRACE;DEBUG</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\Projects\CSharp\UnityEngine.csproj">
+ <Project>{F0499708-3EB6-4026-8362-97E6FFC4E7C8}</Project>
+ <Name>UnityEngine</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AnimationNodeLibrary.cs" />
+ <Compile Include="Attributes.cs" />
+ <Compile Include="DefaultValueAttribute.cs" />
+ <Compile Include="GraphBehaviour.cs" />
+ <Compile Include="LogicNodeLibrary\Animation\AnimationNodes.cs" />
+ <Compile Include="LogicNodeLibrary\Animation\SimpleAnimationPlayer.cs" />
+ <Compile Include="LogicNodeLibrary\AudioSource\AudioSourceNodes.cs" />
+ <Compile Include="LogicNodeLibrary\CharacterController\SimpleCharacterControllerNodes.cs" />
+ <Compile Include="LogicNodeLibrary\Collections\CollectionsNodes.cs" />
+ <Compile Include="LogicNodeLibrary\Collider\OnCollisionEvent.cs" />
+ <Compile Include="LogicNodeLibrary\Collider\OnMouseEvent.cs" />
+ <Compile Include="LogicNodeLibrary\Collider\OnTriggerEvent.cs" />
+ <Compile Include="LogicNodeLibrary\Component\ComponentNodes.cs" />
+ <Compile Include="LogicNodeLibrary\Input\InputNodes.cs" />
+ <Compile Include="LogicNodeLibrary\Input\OnAxis.cs" />
+ <Compile Include="LogicNodeLibrary\Input\OnButton.cs" />
+ <Compile Include="LogicNodeLibrary\Input\OnInputNode.cs" />
+ <Compile Include="LogicNodeLibrary\Input\OnKey.cs" />
+ <Compile Include="LogicNodeLibrary\Input\OnMouseButton.cs" />
+ <Compile Include="LogicNodeLibrary\LogicNodeUtility.cs" />
+ <Compile Include="LogicNodeLibrary\Material\MaterialNodes.cs" />
+ <Compile Include="LogicNodeLibrary\NodeLibrary.cs" />
+ <Compile Include="LogicNodeLibrary\Rigidbody\RigidbodyNodes.cs" />
+ <Compile Include="LogicNodeLibrary\Transform\LookAt.cs" />
+ <Compile Include="LogicNodeLibrary\Transform\MoveTo.cs" />
+ <Compile Include="LogicNodeLibrary\Transform\RotateTo.cs" />
+ <Compile Include="LogicNodeLibrary\Transform\TransformNodes.cs" />
+ <Compile Include="LogicNodeLibrary\Transform\YieldedTransformNodeBase.cs" />
+ <Compile Include="LogicNodeLibrary\YieldedNodeBase.cs" />
+ <Compile Include="LogicNodeTestLibrary.cs" />
+ <Compile Include="MonoBehaviourEventDummies\ColliderDummyBase.cs" />
+ <Compile Include="MonoBehaviourEventDummies\OnAnimationEventDummy.cs" />
+ <Compile Include="MonoBehaviourEventDummies\OnCollisionEventDummy.cs" />
+ <Compile Include="MonoBehaviourEventDummies\OnMouseEventDummy.cs" />
+ <Compile Include="MonoBehaviourEventDummies\OnTriggerEventDummy.cs" />
+ <Compile Include="TestHelpers.cs" />
+ </ItemGroup>
+ <ItemGroup />
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file