【问题标题】:How to modify a Serialized variable from a Custom Editor script in Unity如何从 Unity 中的自定义编辑器脚本修改序列化变量
【发布时间】:2019-04-13 10:08:17
【问题描述】:

我有一个带有 1 个序列化字符串的测试脚本,我试图通过在 TextField 中键入内容来访问和修改它,但我不知道将 TextField 分配给什么。

测试脚本:

using UnityEngine;

public class Test : MonoBehaviour
{
    [SerializeField] private string value;

}

TestTool 脚本:

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(Test))]
public class TestTool : Editor
{
[ExecuteInEditMode]
public override void OnInspectorGUI()
{

    base.OnInspectorGUI();

    Rect textFieldRect = new Rect(EditorGUILayout.GetControlRect(false, EditorGUIUtility.currentViewWidth));

    EditorGUI.DrawRect(textFieldRect, Color.gray);

    EditorGUI.TextField(textFieldRect, "Type here...");
}
}

【问题讨论】:

    标签: c# user-interface unity3d editor


    【解决方案1】:

    我会建议使用直接更改值

    Test myTest = (Test)target;
    myTest.value = EditorGUI.TextField(textFieldRect, myTest.value);
    

    改为使用SerializedProperty

    private SerializedProperty _value;
    
    private void OnEnable()
    {
        // Link the SerializedProperty to the variable 
        _value = serializedObject.FindProperty("value");
    }
    
    public override OnInspectorGUI()
    {
        // fetch current values from the target
        serializedObject.Update();
    
        EditorGUI.PropertyField(textFieldRect, _value);
    
        // Apply values to the target
        serializedObject.ApplyModifiedValues();
    }
    

    这样做的巨大优势是撤消/重做以及将场景和类标记为“脏”都是自动处理的,您不必手动执行。

    但是,要使这项工作变量必须始终是 public[SerializedField],您的班级已经是这种情况了。

    我实际上建议您使用EditorGUILayout.PropertyField 而不是rect,并通过GUILayout.ExpandWidthGUILayout.ExpandHeight 或其他可用的方式设置大小

    选项

    GUILayout.Width, GUILayout.Height, GUILayout.MinWidth, GUILayout.MaxWidth, GUILayout.MinHeight, GUILayout.MaxHeight, GUILayout.ExpandWidth, GUILayout.ExpandHeight。

    为了不显示标签,请使用GUIContent.none

    所以它可能看起来像

    EditorGUILayout.PropertyField(_value, GUIContent.none, GUILayout.ExpandHeight, GUILayout.ExpandWith);
    

    【讨论】:

    • 当 Rect 很小时它不起作用,我怎样才能让它不显示属性的名称?由于名称,它也会弄乱 Rect 。 prntscr.com/lgh2saprntscr.com/lgh2ff
    • 我更新了我的答案。但我现在意识到你实际上是使用另一个框架内的矩形来绘制它。在问题中的第一张图片上,它看起来有点不同。但是您也可以简单地将GUIContent.none 用于EditorGUI 版本
    【解决方案2】:

    这个:

    Test myTest = (Test)target;
    myTest.value = EditorGUI.TextField(textFieldRect, myTest.value);
    

    target 是通过 Editor 超类提供的属性,包含对正在检查的任何对象实例的引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-09
      相关资源
      最近更新 更多