【问题标题】:Unity EditorGuiLayout change slider properties depending on other valuesUnity EditorGuiLayout 根据其他值更改滑块属性
【发布时间】:2022-01-27 05:07:05
【问题描述】:

我想为我的脚本制作一个自定义检查器脚本。我需要两个游戏对象和一个滑块。但是,滑块的最大值取决于两个游戏对象之间的距离。我正在使用 EditorGUILayout(编辑器)。直到现在我都尝试用EditorGUI.BeginChangeCheck() 和一个if 语句if (EditorGUI.EndChangeCheck()){...} 来改变它。但是,这并没有真正起作用,滑块也没有出现。我在 OnInspectorGUI() 方法中做所有事情。我是新手,所以我也不知道我还能做什么。

代码如下:

public override void OnInspectorGUI()
{
    UILineRenderer renderer = (UILineRenderer) target;
    EditorGUI.BeginChangeCheck();
    EditorGUILayout.BeginHorizontal();
    EditorGUILayout.LabelField("Points");
    renderer.startTR = (GameObject) EditorGUILayout.ObjectField(renderer.startTR, typeof(GameObject), true);
    renderer.endTR = (GameObject)EditorGUILayout.ObjectField(renderer.endTR, typeof(GameObject), true);
    EditorGUILayout.EndHorizontal();
    if (EditorGUI.EndChangeCheck())
    {
        if(renderer.startTR != null && renderer.endTR != null)
        {
            float val = Mathf.Abs(renderer.startTR.GetComponent<RectTransform>().anchoredPosition.x - renderer.endTR.GetComponent<RectTransform>().anchoredPosition.x);
            renderer.radius = EditorGUILayout.Slider("Radius", renderer.radius, 0, val);
        }
    }
}

有没有办法保存 createt EditorGUILayout 元素并在之后更改它的属性?如果没有,我该如何解决我的问题?提前感谢您的帮助!

【问题讨论】:

    标签: c# unity3d editor inspector unity-editor


    【解决方案1】:

    你犯了一个巨大但典型的错误;)

    您正在通过target 直接访问和设置值。但这不会将对象和更改的字段标记为 dirty,这意味着

    • 这些值未保存
    • 更改不适用于撤消/重做
    • 预制件不会被正确覆盖

    最严重的当然已经是第一个了;)

    除非您确切地知道自己在做什么并将对象手动标记为脏,否则您总是宁愿通过SerializedObjectSerializedPropertys。

    这需要更多的努力来设置它,但它会自动处理所有提到的事情:

    SerializedProperty startTr;
    SerializedProperty endTr;
    SerializedProperty radius;
    
    private void OnEnable ()
    {
        // Once link up the serialized properties whith their desired underlying fields
        startTr = serializedObject.FindPropery(nameof(UILimeRenderer.startTr));
        endTr = serializedObject.FindPropery(nameof(UILimeRenderer.endTr));
        radius = serializedObject.FindPropery(nameof(UILimeRenderer.radius));
    }
    
    public override void OnInspectorGUI()
    {
        // Load current values into the serialized object
        serializedObject.Update();
    
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Points");
    
         // Use the default drawer for these properties
         // GUIContent.None for omitting the label
        EditorGUILayout.PropertyField(startTR, GUIContent.None, true);
        EditorGUILayout.PropertyField(endTR, GUIContent.None, true);
        
        EditorGUILayout.EndHorizontal();
        
        if(startTR.objectReferenceValue && endTR.objectReferenceValue)
        {
            var maxValue = Mathf.Abs(((GameObject)startTR.objectReferenceValue).GetComponent<RectTransform>().anchoredPosition.x - ((GameObject)endTR.objectReferenceValue).GetComponent<RectTransform>().anchoredPosition.x);
            radius.floatValue = EditorGUILayout.Slider("Radius", radius.floatValue, 0, maxValue);
        }
    
        // Write back changed values. This handles all the mentioned dirty marking
        serializedObject.ApplyModifiedProperties();
    }
    

    我还建议实际使用RectTransform 字段而不是GameObject,然后去掉GetComponent

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-29
      • 2017-08-30
      • 2018-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-28
      相关资源
      最近更新 更多