diff options
Diffstat (limited to 'Runtime/Graphs/UnityEngine.Graphs')
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 |