Unity CreateInspectorGUI 重绘显示按钮

问题描述 投票:0回答:1

我正在开发一个 Unity 程序,其中有一个基于网格的系统。我正在尝试为网格系统制作一个自定义编辑器,基本上您可以更改网格的大小,让它显示一组代表网格的按钮,每次单击按钮时,它都会迭代一些图块。

我已经完成了大部分工作,只是当宽度/高度发生变化时,我无法让检查器重新绘制网格。如果我运行游戏,它可以运行,但不会自动运行。据我所知,调用 CreateInspectorGUI 似乎不可能发生。有没有一种方法可以在不使用 OnInspectorGUI 的情况下做到这一点?我试图留在 UIElements 系统中,但我不确定我是否有选择。

我的检查器代码如下所示:

using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;


[CustomEditor(typeof(GridHolder))]
[CanEditMultipleObjects]
public class Grid_Inspector : Editor
{
SerializedProperty m_Grid_Width;
SerializedProperty m_Grid_Height;
SerializedProperty m_Grid_Size_X;
SerializedProperty m_Grid_Size_Y;

private void OnEnable()
{
    m_Grid_Width = serializedObject.FindProperty("gridWidth");
    m_Grid_Height = serializedObject.FindProperty("gridHeight");
    m_Grid_Size_X = serializedObject.FindProperty("gridXSize");
    m_Grid_Size_Y = serializedObject.FindProperty("gridYSize");
}

// public override void OnInspectorGUI()
// {
//     EditorGUILayout.PropertyField(m_Grid_Width, new GUIContent("Grid Width"), GUILayout.Height(20));

//     serializedObject.ApplyModifiedProperties();
// } 

public override VisualElement CreateInspectorGUI()
{
    VisualElement container = new VisualElement();

    Label title = new Label("Grid Inspector Element");

    container.Add(title);

    VisualElement gridDimensions = new VisualElement();
    gridDimensions.style.flexDirection = FlexDirection.Row;

    PropertyField gridWidth = new PropertyField(m_Grid_Width, "Grid Dimensions (X,Y):");
    PropertyField gridHeight = new PropertyField(m_Grid_Height);

    gridDimensions.TrackPropertyValue(m_Grid_Width, _ => {
        UnityEngine.Debug.Log("Hit");
        Repaint();
    });

    gridDimensions.Add(gridWidth);
    gridDimensions.Add(gridHeight);

    VisualElement gridElementSize = new VisualElement();
    gridElementSize.style.flexDirection = FlexDirection.Row;

    PropertyField gridXSize = new PropertyField(m_Grid_Size_X, "Grid Size (in meters):");
    PropertyField gridYSize = new PropertyField(m_Grid_Size_Y);

    gridElementSize.Add(gridXSize);
    gridElementSize.Add(gridYSize);

    container.Add(gridDimensions);
    container.Add(gridElementSize);

//     // randomColorButton.style.width = new Length(50, LengthUnit.Pixel);
//     // randomColorButton.style.height = new Length(50, LengthUnit.Pixel);

    container.Add(DrawGrid());

    return container;
}

private VisualElement CreateButton(string text, int sizeX, int sizeY)
{

    Button b = new Button() { text = text };
    b.style.width = new Length(sizeX, LengthUnit.Pixel);
    b.style.height = new Length(sizeY, LengthUnit.Pixel);
    return b;
}

private VisualElement DrawGrid()
{
    VisualElement container = new VisualElement();
    try
    {
        for(int i = 0; i < m_Grid_Height.intValue; i++)
        {
            VisualElement row = new VisualElement();
            row.style.flexDirection = FlexDirection.Row;
            for(int j = 0; j < m_Grid_Width.intValue; j++)
            {
                //TODO Connect this to the bool array in GridHolder
                string text = true?" ":"X";
                row.Add(CreateButton(text, 50, 50));
            }
            container.Add(row);
        }
    }
    catch(System.Exception e)
    {
        UnityEngine.Debug.LogWarning(e.Message);
    }
    return container;
}
}

感谢您提供的任何帮助!最坏的情况是我切换到 IMGUI 系统,但我宁愿不必这样做

unity-game-engine user-interface
1个回答
0
投票

您必须重新创建网格,而不是仅仅调用

Repaint

所以你可能会做类似的事情

public override VisualElement CreateInspectorGUI()
{
    ...
    
    var gridContainer = new VisualElement();

    gridDimensions.TrackPropertyValue(m_Grid_Width, _ => {
        UnityEngine.Debug.Log("Hit");
        DrawGrid(gridContainer);
    });

    ...

    container.Add(gridContainer);
    
    DrawGrid(gridContainer);
    
    return container;
}

// instead of creating and returning the container rather just
// take a container as parameter and generate the grid into it
private VisualElement DrawGrid(VisualElement container)
{
    // remove any previous content
    container.Clear();
    try
    {
        for(int i = 0; i < m_Grid_Height.intValue; i++)
        {
            VisualElement row = new VisualElement();
            row.style.flexDirection = FlexDirection.Row;
            for(int j = 0; j < m_Grid_Width.intValue; j++)
            {
                //TODO Connect this to the bool array in GridHolder
                string text = true?" ":"X";
                row.Add(CreateButton(text, 50, 50));
            }
            container.Add(row);
        }
    }
    catch(System.Exception e)
    {
        UnityEngine.Debug.LogWarning(e.Message);
    }
}

因此,您不必在

CreateInspectorGUI
中仅创建一次网格,而是在每次修改大小时重新创建网格,并传入要放置其的根容器。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.