1

例如,我有MonoBehaviour一个名为Foo

class Foo : MonoBehaviour {
   public Button lastButton; 
   public Image []images;
}

[CustomEditor(typeof(Foo))]
class FooEditor : Editor {

    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        Foo foo = (Foo)target;
        if(GUILayout.Button("Bind last Button and all Images")) {
           /* how to bind programatically last foo.GetComponentsInChildren<Button>(); 
              to foo.gameObject.scene's 
                 foo.gameObject.GetComponent<Foo>().lastButton 
              in edit mode's property window 
                 (without have to drag on the editor)?
           */
           /* and how to bind programatically all foo.GetComponentsInChildren<Image>(); 
              to foo.gameObject.scene's 
                 foo.gameObject.GetComponent<Foo>().images 
              in edit mode's property window 
                 (without have to drag all one by one)?
           */
        }
    }
}

我想自动绑定,而不必一一拖动或在运行时进行,如何以编程方式进行?

我能想到的唯一解决方法(如果没有这样的 API)是保存场景,解析场景yaml,然后更新 yaml 文件上的绑定,并强制 UnityEditor 重新加载 yaml,但不确定它是否会工作加载 yaml 并重写它不会产生相同的价值

4

1 回答 1

3

尽管老实说我仍然不明白“绑定”的目的,但在我看来,您实际上是在谈论通过编辑器脚本简单地引用所有组件,而不是必须拖放它们。(也许绑定包含在这里,我只是不知道它的名称?)

首先确保将整个代码FooEditor放在一个名为的文件夹中Editor或将其包装在

#if UNITY_EDITOR
    // any code using UnityEditor namespace
#endif

为了在以后的构建中剥离它们。否则你会得到编译器错误,因为UnityEditor构建中不存在。

那么重要的是始终在编辑器脚本中操作SerializedPropertys 的s。SerializedObject这会将所有标记处理为,为您保存更改和撤消/重做条目。如果您碰巧直接操纵领域,您将不得不自己处理这些事情......

因此,一个关键角色用于在真实目标组件SerializedObject.Update及其SerializedObject.ApplyModifiedProperties序列化对象之间加载和写回值 - 我喜欢称它为“影子克隆”。

#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using UnityEngine.UI;

class Foo : MonoBehaviour
{
    public Button lastButton;
    public Image[] images;
}

#if UNITY_EDITOR
[CustomEditor(typeof(Foo))]
class FooEditor : Editor
{

    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        // fetch current values from the real target into the serialized "clone"
        serializedObject.Update();

        Foo foo = (Foo)target;
        if (GUILayout.Button("Bind last Button and all Images"))
        {
            // get last button field as serialized property
            var lastButtonField = serializedObject.FindProperty("lastButton");

            // get last Button reference
            // pass true to also get eventually inactive children
            var buttons = foo.GetComponentsInChildren<Button>(true);
            var lastButton = buttons[buttons.Length - 1];

            // asign lastButton to the lastButtonField
            lastButtonField.objectReferenceValue = lastButton;


            // slightly more complex but similar
            // get the field as serialized property
            var imagesField = serializedObject.FindProperty("images");

            // get the images references
            // again pass true to also get eventually inactive ones
            var images = foo.GetComponentsInChildren<Image>(true);

            // now first set the according list size
            imagesField.arraySize = images.Length;

            // assign all references
            for (var i = 0; i < imagesField.arraySize; i++)
            {
                // serialized property of the element in the field list
                var entry = imagesField.GetArrayElementAtIndex(i);

                // simply assign the reference like before with the button
                entry.objectReferenceValue = images[i];
            }
        }

        // write back changes to the real target
        // automatically handles marking as dirty and undo/redo
        serializedObject.ApplyModifiedProperties();
    }
}
#endif

在此处输入图像描述


我希望我没有完全离开,这就是你所说的“绑定”。


请注意,如果您想进一步更改您选择的引用的值,该引用不是目标本身,您可以轻松使用new SerializedObject(objectReference)以获得序列化对象,例如

var serializedLastButton = new SerializedObject (lastButton);

或者也

var serializedLastButton = new SerializedObject(lastButtonField.objectReferenceValue);

现在再次使用更改其中的任何字段时,FindProperty(propertyName)请确保再次使用

serializedLastButton.Update();

// make changes

serializedLastButton.ApplyModifiedProperties();
于 2019-08-13T05:03:55.103 回答