Search Unity

[SOLVED] How to programatically bind to script's property when clicking editor button?

Discussion in 'Scripting' started by kokizzu, Aug 13, 2019.

  1. kokizzu

    kokizzu

    Joined:
    Mar 7, 2018
    Posts:
    11
    https://stackoverflow.com/questions...pt-property-on-unity-edit-mode-not-at-runtime

    For example, I have MonoBehaviour derived class called Foo:
    Code (CSharp):
    1. class Foo : MonoBehaviour {
    2.    public Button lastButton;
    3.    public Image []images;
    4. }
    5.  
    6. [CustomEditor(typeof(Foo))]
    7. class FooEditor : Editor {
    8.  
    9.    public override void OnInspectorGUI()
    10.    {
    11.        DrawDefaultInspector();
    12.  
    13.        Foo foo = (Foo)target;
    14.        if(GUILayout.Button("Bind last Button and all Images")) {
    15.           /* how to bind programatically last foo.GetComponentsInChildren<Button>();
    16.              to foo.gameObject.scene's
    17.                 foo.gameObject.GetComponent<Foo>().lastButton
    18.              in edit mode (without have to drag on the editor)?
    19.           */
    20.           /* and how to bind programatically all foo.GetComponentsInChildren<Image>();
    21.              to foo.gameObject.scene's
    22.                 foo.gameObject.GetComponent<Foo>().images
    23.              in edit mode (without have to drag all one by one)?
    24.           */
    25.        }
    26.    }
    27. }
    I want to automate the binding without have to drag one by one or do it in runtime, how can I do it programatically on edit mode?
     
    Last edited: Aug 13, 2019
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    I'll do this with linq (any gc overhead people may argue about with linq doesn't matter in editor...)

    So stick:
    using System.Linq;
    at top of your editor code file

    then:
    Code (csharp):
    1.  
    2. foo.lastButton = foo.GetComponentsInChildren<Button>().LastOrDefault();
    3. foo.images = foo.GetComponentsInChildren<Image>();
    4.  
     
  3. kokizzu

    kokizzu

    Joined:
    Mar 7, 2018
    Posts:
    11
    the problem is not about getting the components, but setting the property of the `Editor.serializedObject.serializedProperty` (now I know that this is the one I should set).
    derHugo wrote an answer here: https://stackoverflow.com/a/57471388/1620210
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    So either:

    A) you get the SerializedProperty from the SerializedObject. And you set the appropriate fields using that interface:
    https://docs.unity3d.com/ScriptReference/SerializedProperty.html
    like you found on stack overflow

    B) after setting the values on 'foo', if I recall correctly (mind you not at my dev machine to test right now), you should be able to call SerializedObject.Update:
    https://docs.unity3d.com/ScriptReference/SerializedObject.Update.html

    So after those 2 lines I wrote just say:
    Code (csharp):
    1. serializedObject.Update();
    That 'should' work. Since Update syncs the target object to the serializedObject.

    Where as ApplyModifiedProperties goes from serializedObject to target object.
     
    Last edited: Aug 13, 2019
  5. kokizzu

    kokizzu

    Joined:
    Mar 7, 2018
    Posts:
    11