two-way binding properties node.

Forums General Discussion two-way binding properties node.

Tagged: 

This topic contains 3 replies, has 2 voices, and was last updated by  toto007 1 hour, 2 minutes ago.

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #2121

    toto007
    Participant

    Hi guys,

    I have created a custom node ‘TweenPosition’ with different properties (look image attachment). When the node is selected then I want change for example the value of property Y via script.

    This is my attempt:

    
    [ContextMenu("Test Change Value Node")]
        public void TestChangeValueNode()
        {
            Node activeNode = GraphEditorUtility.activeNode;
            TweenPosition node = activeNode as TweenPosition;
            ValueInput<float> port = node.GetInputPort("y") as  ValueInput<float>;
    	port.SetDefaultAndSerializedValue(float.Parse(input.text));
        }
    

    I don’t know if this is the right way to do that because in this way I’m changing the default value and not the current value.

    Anyway, I want to edit this value both ways (two-way binding).

    I need to do that because I want to show current gameobject status on which the selected node is working in editor mode.

    Any suggestions?
    Thank you
    Giuseppe

    Attachments:
    You must be logged in to view attached files.
    #2131

    Gavalakis
    Keymaster

    Hello there,

    Using the [ContextMenu] attribute is totaly valid within nodes like you do, but to change the “current value” please dont use the “SetDefaultAndSerializedValue”. Simply set the “.serializedValue” property. Setting this property will actually only set the serialized value that you see in the inspector and leave the defaultValue unchanged.
    “SetDefaultAndSerializedValue” is just a shortcut to setting both “.defaultValue” and “.serializedValue” properties :).

    Please let me know if that works for you.
    Thank you.

    #2133

    toto007
    Participant

    Thanks, It’s works!

    I want that user can editing some variables of node through the tools of support.
    So, I have created a node custom “TweenPosition” for create an animation of an object in a determinate position (To). You can look my example here:

    If you can look at my code I would like to know if it is the correct way to achieve this goal.Basically what I do that when the node is selected I then transfer the reference of the “to” field of the node to an internal my class that serves to manage the waypoint on the scene.

    This class is my custom flownode
    Tweenposition.cs

    
    using NodeCanvas.Editor;
    using NodeCanvas.Framework;
    using ParadoxNotion.Design;
    using UnityEditor;
    using UnityEngine;
    
    namespace FlowCanvas.Nodes
    {
    
        [Name("Tween Position")]
        [Category("ActionSwipeStory")]
        [Description("crea effetto transizione")]
        public class TweenPosition : FlowControlNode
        {
    
            ValueInput<GameObject> obj;
            ValueInput<Vector3> to;
            protected override void RegisterPorts()
            {
    
                obj = AddValueInput<GameObject>("object");
                to = AddValueInput<Vector3>("to");
    
                var t = AddValueInput<float>("time");
                var start = AddFlowOutput("startEvent");
                var end = AddFlowOutput("finishEvent");
    
                AddFlowInput("In", (f) =>
                {
                    Debug.Log("Tween position");
                    start.Call(f);
    
                    LeanTween.move(obj.value, to.value, t.value).setOnComplete(() =>
                     {
                         end.Call(f);
                     });
    
                });
            }
    
            protected override void OnNodePicked()
            {
                if (obj.value != null)
                {
                    ConfigurationPlaceholder();
                    GraphEditorUtility.onActiveElementChanged += onActiveElementChanged;
                }
            }
            void ConfigurationPlaceholder()
            {
                Debug.Log("ConfigurationPlaceholder");
                if (obj.value != null)
                {
                    TweenPositionMonoB action = obj.value.GetComponent<TweenPositionMonoB>();
                    if (action == null)
                    {
                        action = obj.value.AddComponent<TweenPositionMonoB>();
                    }
                    action.to = to;
                    Selection.activeGameObject = obj.value;
                }
    
            }
            void OnNodeUnPicked()
            {
                Selection.activeGameObject = null;
            }
    
            void onActiveElementChanged(IGraphElement node)
            {
                if (node != this)
                {
                    OnNodeUnPicked();
                    GraphEditorUtility.onActiveElementChanged -= onActiveElementChanged;
                }
            }
    
            protected override void OnNodeGUI()
            {
                base.OnNodeGUI();
            }
    
            protected override void OnNodeReleased()
            {
                Debug.Log("Nodo rilasciato");
            }
        }
    }
    

    This class is useful to create the placeholder waypoint on the object on which the node works
    TweenPositionEditor.cs

    using System.Collections;
    using System.Collections.Generic;
    using UnityEditor;
    using UnityEngine;
    
    [CustomEditor(typeof(TweenPositionMonoB))]
    public class TweenPositionEditor : Editor
    {
        void OnSceneGUI()
        {
            var t = target as TweenPositionMonoB;
    
            if (t.to != null)
            {
                t.to.serializedValue = Handles.FreeMoveHandle(t.to.value, Quaternion.identity, 0.7f, Vector2.zero, Handles.CylinderHandleCap);
                Handles.DrawLine(t.transform.localPosition, t.to.value);
            }
        }
    }
    

    This class does the through to share the variable position of the node “Tweenposition.cs” with the class “TweenPositionEditor.cs “that manage the waypoint drawn the handles on the Scenaview
    TweenPositionMonoB.cs

    
    using System.Collections;
    using System.Collections.Generic;
    using FlowCanvas;
    using UnityEngine;
    
    public class TweenPositionMonoB : MonoBehaviour
    {
        public ValueInput<Vector3> to;
        // Use this for initialization
        void Start()
        {
    
        }
    
    }
    

    If I may I would ask you another advice. I would like to know when the Serializevalue changes value. I thought I’d extend the class Valueinput<T> and overwrite the serializedvalue set method to launch an event when its value changes from the previous.

    #2136

    toto007
    Participant

    Regarding the advice I asked you about how I could listen to the change in the value of an ValueInput, I extended the ValueInput class this way:

    
    using FlowCanvas;
    using NodeCanvas.Editor;
    using NodeCanvas.Framework;
    using ParadoxNotion.Design;
    using UnityEditor;
    using UnityEngine;
    
    namespace MyProject.FlowCanvas
    {
    
        public class ObservableValueInput<T> : global::FlowCanvas.ValueInput<T>
        {
    
            public ObservableValueInput() { }
            public ObservableValueInput(FlowNode parent, string name, string ID) : base(parent, name, ID) { }
    
            public event System.Action<T, T> onValueChanged;
            public override object serializedValue
            {
                get { return base.serializedValue; }
                set
                {
                    System.Object oldvalue = base.serializedValue;
                    base.serializedValue = value;
    
                    if (oldvalue != value)
                    {
                        if (onValueChanged != null)
                        {
                            onValueChanged((T)oldvalue, (T)value);
                        }
                    }
    
                }
            }
        }
    }
    

    I also had to extend the FlowControlNode class by adding the AddObservableValueInput method. The problem that to do this I had to modify the class changing the access level of the QualifyPortNameAndID method and the inputPorts variable from private to protected. How can I achieve the same result without modifying your framework? I do not want to have to report my changes to your framework every time when there is a new update

    using FlowCanvas;
    using NodeCanvas.Editor;
    using NodeCanvas.Framework;
    using ParadoxNotion.Design;
    using UnityEditor;
    using UnityEngine;
    
    namespace MyProject.FlowCanvas
    {
        /// <summary>
        /// To be able to extend the class correctly, you have changed the visibility levels to the parent class of the source framework:
        /// inputPorts da private a protected
        /// QualitiPortNameAndId da private a protected
        /// 
        /// 
        /// /// </summary>
        abstract public class FlowControlNode :FlowCanvas.Nodes.FlowControlNode
        {
            /// <summary>
            /// Consente di poter aggiungere al nodo una input port di tipo ObservableValueInput 
            /// in cui ci si può mettere in ascolto quando i suo valore cambia
            /// </summary>
            /// <param name="name">porta</param>
            /// <param name="ID"></param>
            /// <typeparam name="T"></typeparam>
            /// <returns></returns>
            public ObservableValueInput<T> AddObservableValueInput<T>(string name, string ID = "")
            {
                QualifyPortNameAndID(ref name, ref ID, inputPorts);
                return (ObservableValueInput<T>)(inputPorts[ID] = new ObservableValueInput<T>(this, name, ID));
            }
    
            protected override void OnNodePicked()
            {
                GraphEditorUtility.onActiveElementChanged += onActiveElementChanged;
            }
            protected abstract void OnNodeUnPicked();
            void onActiveElementChanged(IGraphElement node)
            {
                if (node != this)
                {
                    OnNodeUnPicked();
                    GraphEditorUtility.onActiveElementChanged -= onActiveElementChanged;
                }
            }
    
        }
    
    }
    
Viewing 4 posts - 1 through 4 (of 4 total)

You must be logged in to reply to this topic.