尽管老实说我仍然不明白“绑定”的目的,但在我看来,您实际上是在谈论通过编辑器脚本简单地引用所有组件,而不是必须拖放它们。(也许绑定包含在这里,我只是不知道它的名称?)
首先确保将整个代码FooEditor
放在一个名为的文件夹中Editor
或将其包装在
#if UNITY_EDITOR
// any code using UnityEditor namespace
#endif
为了在以后的构建中剥离它们。否则你会得到编译器错误,因为UnityEditor
构建中不存在。
那么重要的是始终在编辑器脚本中操作SerializedProperty
s 的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();