自定义 GUI TextField 和 ObjectField 不分配值
custom GUI TextField's and ObjectField's don't assign values
我在使用 Unity 的 API 修改编辑器 GUI 来改变引用值时遇到问题。
当我进入编辑器更改 GUI 中的值时,它只是刷新并保留我在参数中提供的标签 text/object,为什么它不改变引用并显示它呢?
1.
我正在引用附加到特定游戏对象的 class ButtonManager script = target as ButtonManager;
我想更改 class script.thisImageCaption = EditorGUILayout.TextArea("Content for the main image slide", script.thisImageCaption);
的值,但这不起作用
奇怪的是...bools 工作,当我选中该框时,GUI 会记住我的选择并修改引用值,那么为什么其他人不呢?
script.hasAudioClip = EditorGUILayout.Toggle("Voice Over?", script.hasAudioClip);
2.
我还引用了 GameObjects 及其独立组件
//following code is a snippet of code, the full context isnt provided, only the context related to mutating referenced values
List<Tuple<int, Text, Image>> imageCloneHolder = new List<Tuple<int, Text, Image>>();
imageCloneHolder.Add(new Tuple<int, Text, Image>(
slide.GetInstanceID(),
slide.transform.GetChild(1).GetComponent<Text>(),//get reference to text
slide.transform.GetChild(0).GetComponent<Image>()//get reference to image
));
item.Item2.text = EditorGUILayout.TextArea("Content for the image cloneslide",
item.Item2.text);//dosen't modify the referenced text
item.Item3.sprite = EditorGUILayout.ObjectField("This second Image slides image",
item.Item3.sprite,
typeof(Sprite),
false) as Sprite;//doesn't modify the referenced image
我不太明白哪里出了问题,我认为当您在 Unity 和 C#(使用 classes、组件等)中获取引用时,它们将是指向真实对象的指针而不是副本,但是似乎 Unity 的 GUI API 让我修改副本?对于 class 中引用的字符串,这不是真的吗?或者对于某些 Unity 组件?
屏幕转储
我猜的主要问题是您没有将内容标记为 脏。这是保存任何更改所必需的。
一般来说,您应该不直接从 Editor
中对 target
进行更改。而是使用 SerializedProperty
。他们处理所有标记内容 dirty(从而保存更改)和 Undo/Redo 功能。
另外我不明白你为什么要在那里使用 List
如果无论如何你只添加一个元素...
我没有看到您的完整代码,尤其是 class 和完整的编辑器会有所帮助。但是对于您提供的内容,它应该类似于
public class YourEditor : Editor
{
private SerializedProperty thisImageCaption;
private SerializedProperty hasAudioClip;
// wherever you get this from
private XY item;
private void OnEnable()
{
// Link SerializedProperties to the real ones
thisImageCaption = serializedObject.FindProperty("thisImageCaption");
hasAudioClip = serializedObject.FindProperty("hasAudioClip");
}
public override void OnInpectorGUI()
{
// Load the current real values
// into the SerializedProperties
serializedObject.Update();
// Now only change the SerializedProperties
thisImageCaption.stringValue = EditorGUILayout.TextArea("Content for the main image slide", thisImageCaption.stringValue);
// Using PropertyField automatically
// uses the property drawer according
// to the property's type
EditorGUILayout.PropertyField(hasAudioClip);
// now to the tricky part
// for both slider sub-components you will need
// to create a serializedObject from the given components e.g.
var textSerializedObject = new SerializedObject(item.Item2);
var imageSerializedObject = new SerializedObject(item.Item3);
// do the update for both
textSerializedObject.Update();
imageSerializedObject.Update();
// now change what you want to change via serializedProperties e.g.
EditorGUILayout.PropertyField(textSerializedObject.FindProperty("m_text"), new GUIContent("Content for the image cloneslide"));
EditorGUILayout.PropertyField(imageSerializedObject.FindProperty("m_Sprite"), new GUIContent("This second Image slides image"));
// Write changes back to the real components
textSerializedObject.ApplyModifiedProperties();
imageSerializedObject.ApplyModifiedProperties();
serializedObject.ApplyModifiedProperties();
}
}
注意:在智能手机上打字,因此不提供保修,但我希望这个想法能清楚。
我在使用 Unity 的 API 修改编辑器 GUI 来改变引用值时遇到问题。
当我进入编辑器更改 GUI 中的值时,它只是刷新并保留我在参数中提供的标签 text/object,为什么它不改变引用并显示它呢?
1.
我正在引用附加到特定游戏对象的 class ButtonManager script = target as ButtonManager;
我想更改 class script.thisImageCaption = EditorGUILayout.TextArea("Content for the main image slide", script.thisImageCaption);
的值,但这不起作用
奇怪的是...bools 工作,当我选中该框时,GUI 会记住我的选择并修改引用值,那么为什么其他人不呢?
script.hasAudioClip = EditorGUILayout.Toggle("Voice Over?", script.hasAudioClip);
2. 我还引用了 GameObjects 及其独立组件
//following code is a snippet of code, the full context isnt provided, only the context related to mutating referenced values
List<Tuple<int, Text, Image>> imageCloneHolder = new List<Tuple<int, Text, Image>>();
imageCloneHolder.Add(new Tuple<int, Text, Image>(
slide.GetInstanceID(),
slide.transform.GetChild(1).GetComponent<Text>(),//get reference to text
slide.transform.GetChild(0).GetComponent<Image>()//get reference to image
));
item.Item2.text = EditorGUILayout.TextArea("Content for the image cloneslide",
item.Item2.text);//dosen't modify the referenced text
item.Item3.sprite = EditorGUILayout.ObjectField("This second Image slides image",
item.Item3.sprite,
typeof(Sprite),
false) as Sprite;//doesn't modify the referenced image
我不太明白哪里出了问题,我认为当您在 Unity 和 C#(使用 classes、组件等)中获取引用时,它们将是指向真实对象的指针而不是副本,但是似乎 Unity 的 GUI API 让我修改副本?对于 class 中引用的字符串,这不是真的吗?或者对于某些 Unity 组件?
屏幕转储
我猜的主要问题是您没有将内容标记为 脏。这是保存任何更改所必需的。
一般来说,您应该不直接从 Editor
中对 target
进行更改。而是使用 SerializedProperty
。他们处理所有标记内容 dirty(从而保存更改)和 Undo/Redo 功能。
另外我不明白你为什么要在那里使用 List
如果无论如何你只添加一个元素...
我没有看到您的完整代码,尤其是 class 和完整的编辑器会有所帮助。但是对于您提供的内容,它应该类似于
public class YourEditor : Editor
{
private SerializedProperty thisImageCaption;
private SerializedProperty hasAudioClip;
// wherever you get this from
private XY item;
private void OnEnable()
{
// Link SerializedProperties to the real ones
thisImageCaption = serializedObject.FindProperty("thisImageCaption");
hasAudioClip = serializedObject.FindProperty("hasAudioClip");
}
public override void OnInpectorGUI()
{
// Load the current real values
// into the SerializedProperties
serializedObject.Update();
// Now only change the SerializedProperties
thisImageCaption.stringValue = EditorGUILayout.TextArea("Content for the main image slide", thisImageCaption.stringValue);
// Using PropertyField automatically
// uses the property drawer according
// to the property's type
EditorGUILayout.PropertyField(hasAudioClip);
// now to the tricky part
// for both slider sub-components you will need
// to create a serializedObject from the given components e.g.
var textSerializedObject = new SerializedObject(item.Item2);
var imageSerializedObject = new SerializedObject(item.Item3);
// do the update for both
textSerializedObject.Update();
imageSerializedObject.Update();
// now change what you want to change via serializedProperties e.g.
EditorGUILayout.PropertyField(textSerializedObject.FindProperty("m_text"), new GUIContent("Content for the image cloneslide"));
EditorGUILayout.PropertyField(imageSerializedObject.FindProperty("m_Sprite"), new GUIContent("This second Image slides image"));
// Write changes back to the real components
textSerializedObject.ApplyModifiedProperties();
imageSerializedObject.ApplyModifiedProperties();
serializedObject.ApplyModifiedProperties();
}
}
注意:在智能手机上打字,因此不提供保修,但我希望这个想法能清楚。