C# 我怎样才能画一张清单和它的全部';检查器编辑器脚本中的项目?

C# 我怎样才能画一张清单和它的全部';检查器编辑器脚本中的项目?,c#,unity3d,C#,Unity3d,主脚本: using System.Collections; using System.Collections.Generic; using UnityEngine; public class DialogueTrigger : MonoBehaviour { public List<Dialogue> dialogue = new List<Dialogue>(); [HideInInspector] public int dialogueN

主脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DialogueTrigger : MonoBehaviour
{
    public List<Dialogue> dialogue = new List<Dialogue>();

    [HideInInspector]
    public int dialogueNum = 0;

    private bool triggered = false;

    public void TriggerDialogue()
    {
        if (triggered == false)
        {
            if (FindObjectOfType<DialogueManager>() != null)
            {
                FindObjectOfType<DialogueManager>().StartDialogue(dialogue[dialogueNum]);
                dialogueNum += 1;
            }
            triggered = true;
        }
    }

    private void Update()
    {
        if (DialogueManager.dialogueEnded == true)
        {
            if (dialogueNum == dialogue.Count)
            {
                return;
            }
            else
            {
                FindObjectOfType<DialogueManager>().StartDialogue(dialogue[dialogueNum]);
                DialogueManager.dialogueEnded = false;
                dialogueNum += 1;
            }
        }
    }
}
和编辑器脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(DialogueTrigger))]
public class DialogueTriggerEditor : Editor
{
    private SerializedProperty _dialogues;

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        _dialogues = serializedObject.FindProperty("dialogue");
        serializedObject.Update();

        for (int i = 0; i < _dialogues.arraySize; i++)
        {
            var dialogue = _dialogues.GetArrayElementAtIndex(i);
            EditorGUILayout.PropertyField(dialogue, new GUIContent("Dialogue " + i));
        }
    }
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEditor;
使用UnityEngine;
[CustomEditor(typeof(DialogueTrigger))]
公共类DialogueTriggerEditor:编辑器
{
私人财产对话;
公共覆盖无效OnInspectorGUI()
{
base.OnInspectorGUI();
_对话=serializedObject.FindProperty(“对话”);
serializedObject.Update();
for(int i=0;i<\u dialogs.arraySize;i++)
{
var dialogue=\u dialogs.getArrayelementIndex(i);
PropertyField(对话,新GUI内容(“对话”+i));
}
}
}
但是现在我有了一个对话变量在检查器中,我可以设置对话的数量,每个对话的名称和句子

但在它下面,它会根据我设置的对话数量创建更多的对话

我想在Inspector中有一个主要的对话:

然后在里面我可以设置对话的数量。例如,如果我设置5,那么在对话下将有:对话1对话2对话3对话4对话5


然后在每个对话的下面,例如对话1,会有它的名字和句子。可以更改每个对话的句子大小。

如果使用对话列表上的SerializeField属性,则将获得“dialogue”的根元素,其中可以指定列表中元素的数量,并且每个子元素都将是dialog类的实例,如果在编辑器脚本中序列化字段,则如果在脚本中添加到列表中,元素也将更新

编辑:你还需要更新你的编辑器脚本,如果你想从编辑器脚本中添加元素,你可以从游戏对象中抓取一个类的实例,只需将元素添加到列表中(只要列表是公共的)

范例

Script.cs

[SerializeField]
public List<Dialogue> dialogue = new List<Dialogue>();
[序列化字段]
公共列表对话=新建列表();
Editor.cs

public override void OnInspectorGUI()
{
    base.OnInspectorGUI();

    Script script = GameObject.Find("GameObject").GetComponent<Script>();
    script.dialogue.Add(new Dialogue());
    EditorUtility.SetDirty(script);
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
Script Script=GameObject.Find(“GameObject”).GetComponent();
script.dialogue.Add(newdialogue());
SetDirty(脚本);
}

问题在于默认情况下,
EditorGUILayout.PropertyField
不支持嵌套属性

最简单的修复方法是使用正确的重载

其中包括儿童:

[CustomEditor(typeof(DialogueTrigger))]
public class DialogueTriggerEditor : Editor
{
    private SerializedProperty _dialogues;

    private void OnEnable()
    {
        // do this only once here
        _dialogues = serializedObject.FindProperty("dialogue");
    }

    public override void OnInspectorGUI()
    {
        //base.OnInspectorGUI();

        serializedObject.Update();

        // Ofcourse you also want to change the list size here
        _dialogues.arraySize = EditorGUILayout.IntField("Size", _dialogues.arraySize);

        for (int i = 0; i < _dialogues.arraySize; i++)
        {
            var dialogue = _dialogues.GetArrayElementAtIndex(i);
            EditorGUILayout.PropertyField(dialogue, new GUIContent("Dialogue " + i), true);
        }

        // Note: You also forgot to add this
        serializedObject.ApplyModifiedProperties();
    }
}
[CustomEditor(typeof(DialogueTrigger))]
公共类DialogueTriggerEditor:编辑器
{
私人财产对话;
私有void OnEnable()
{
//在这里只做一次
_对话=serializedObject.FindProperty(“对话”);
}
公共覆盖无效OnInspectorGUI()
{
//base.OnInspectorGUI();
serializedObject.Update();
//当然,您还需要在此处更改列表大小
_dialogs.arraySize=EditorGUILayout.IntField(“大小”,_dialogs.arraySize);
for(int i=0;i<\u dialogs.arraySize;i++)
{
var dialogue=\u dialogs.getArrayelementIndex(i);
属性字段(对话,新GUIContent(“对话”+i),true);
}
//注意:您还忘记添加此项
serializedObject.ApplyModifiedProperties();
}
}


注意,还有其他更多可定制的解决方案。另一个快速方法可能是手动获取这些嵌套特性,并定义如何绘制它们:

[CustomEditor(typeof(DialogueTrigger))]
public class DialogueTriggerEditor : Editor
{
    private SerializedProperty _dialogues;

    // store which dialogue is foldout
    private List<bool> dialogueFoldout = new List<bool>();

    private void OnEnable()
    {
        _dialogues = serializedObject.FindProperty("dialogue");

        for (var i = 0; i < _dialogues.arraySize; i++)
        {
            dialogueFoldout.Add(false);
        }
    }

    public override void OnInspectorGUI()
    {
        //base.OnInspectorGUI();

        serializedObject.Update();

        var color = GUI.color;

        EditorGUI.BeginChangeCheck();
        _dialogues.arraySize = EditorGUILayout.IntField("Size", _dialogues.arraySize);
        if (EditorGUI.EndChangeCheck())
        {
            dialogueFoldout.Clear();

            for (var i = 0; i < _dialogues.arraySize; i++)
            {
                dialogueFoldout.Add(false);
            }

            serializedObject.ApplyModifiedProperties();
            return;
        }

        for (var i = 0; i < _dialogues.arraySize; i++)
        {
            var dialogue = _dialogues.GetArrayElementAtIndex(i);

            dialogueFoldout[i] = EditorGUILayout.Foldout(dialogueFoldout[i], "Dialogue " + i);

            // make the next fields look nested below the before one
            EditorGUI.indentLevel++;

            if (dialogueFoldout[i])
            {
                var name = dialogue.FindPropertyRelative("name");
                var sentences = dialogue.FindPropertyRelative("sentences");

                if (string.IsNullOrWhiteSpace(name.stringValue)) GUI.color = Color.yellow;
                EditorGUILayout.PropertyField(name);
                GUI.color = color;

                // if you still want to be able to controll the size
                sentences.arraySize = EditorGUILayout.IntField("Senteces size", sentences.arraySize);

                // make the next fields look nested below the before one
                EditorGUI.indentLevel++;
                for (var s = 0; s < sentences.arraySize; s++)
                {
                    var sentence = sentences.GetArrayElementAtIndex(s);
                    if (string.IsNullOrWhiteSpace(sentence.stringValue)) GUI.color = Color.yellow;
                    EditorGUILayout.PropertyField(sentence, new GUIContent("Sentece " + s));
                    GUI.color = color;
                }
                EditorGUI.indentLevel--;
            }

            EditorGUI.indentLevel--;
        }

        serializedObject.ApplyModifiedProperties();
    }
}
[CustomEditor(typeof(DialogueTrigger))]
公共类DialogueTriggerEditor:编辑器
{
私人财产对话;
//存储哪个对话是折叠式的
私有列表对话框UEFOLDOUT=新列表();
私有void OnEnable()
{
_对话=serializedObject.FindProperty(“对话”);
对于(变量i=0;i<\u dialogs.arraySize;i++)
{
对话框foldout.Add(false);
}
}
公共覆盖无效OnInspectorGUI()
{
//base.OnInspectorGUI();
serializedObject.Update();
var color=GUI.color;
EditorGUI.BeginChangeCheck();
_dialogs.arraySize=EditorGUILayout.IntField(“大小”,_dialogs.arraySize);
if(EditorGUI.EndChangeCheck())
{
dialogueFoldout.Clear();
对于(变量i=0;i<\u dialogs.arraySize;i++)
{
对话框foldout.Add(false);
}
serializedObject.ApplyModifiedProperties();
返回;
}
对于(变量i=0;i<\u dialogs.arraySize;i++)
{
var dialogue=\u dialogs.getArrayelementIndex(i);
dialogueFoldout[i]=EditorGUILayout.Foldout(dialogueFoldout[i],“Dialogue”+i);
//使下一个字段看起来嵌套在前一个字段的下面
EditorGUI.indentLevel++;
if(对话框foldout[i])
{
变量名称=对话。FindPropertyRelative(“名称”);
var句子=对话。FindPropertyRelative(“句子”);
if(string.IsNullOrWhiteSpace(name.stringValue))GUI.color=color.yellow;
EditorGUILayout.PropertyField(名称);
GUI.color=颜色;
//如果你还想控制尺寸的话
句子.arraySize=EditorGUILayout.IntField(“句子大小”,句子.arraySize);
//使下一个字段看起来嵌套在前一个字段的下面
EditorGUI.indentLevel++;
for(var s=0;s<句子.arraySize;s++)
{
var句子=句子。GetArrayElementIndex(s);
if(string.IsNullOrWhiteSpace(句子.stringValue))GUI.color=color.yellow;
EditorGUILayout.PropertyField(句子,新内容
[CustomEditor(typeof(DialogueTrigger))]
public class DialogueTriggerEditor : Editor
{
    private SerializedProperty _dialogues;

    // store which dialogue is foldout
    private List<bool> dialogueFoldout = new List<bool>();

    private void OnEnable()
    {
        _dialogues = serializedObject.FindProperty("dialogue");

        for (var i = 0; i < _dialogues.arraySize; i++)
        {
            dialogueFoldout.Add(false);
        }
    }

    public override void OnInspectorGUI()
    {
        //base.OnInspectorGUI();

        serializedObject.Update();

        var color = GUI.color;

        EditorGUI.BeginChangeCheck();
        _dialogues.arraySize = EditorGUILayout.IntField("Size", _dialogues.arraySize);
        if (EditorGUI.EndChangeCheck())
        {
            dialogueFoldout.Clear();

            for (var i = 0; i < _dialogues.arraySize; i++)
            {
                dialogueFoldout.Add(false);
            }

            serializedObject.ApplyModifiedProperties();
            return;
        }

        for (var i = 0; i < _dialogues.arraySize; i++)
        {
            var dialogue = _dialogues.GetArrayElementAtIndex(i);

            dialogueFoldout[i] = EditorGUILayout.Foldout(dialogueFoldout[i], "Dialogue " + i);

            // make the next fields look nested below the before one
            EditorGUI.indentLevel++;

            if (dialogueFoldout[i])
            {
                var name = dialogue.FindPropertyRelative("name");
                var sentences = dialogue.FindPropertyRelative("sentences");

                if (string.IsNullOrWhiteSpace(name.stringValue)) GUI.color = Color.yellow;
                EditorGUILayout.PropertyField(name);
                GUI.color = color;

                // if you still want to be able to controll the size
                sentences.arraySize = EditorGUILayout.IntField("Senteces size", sentences.arraySize);

                // make the next fields look nested below the before one
                EditorGUI.indentLevel++;
                for (var s = 0; s < sentences.arraySize; s++)
                {
                    var sentence = sentences.GetArrayElementAtIndex(s);
                    if (string.IsNullOrWhiteSpace(sentence.stringValue)) GUI.color = Color.yellow;
                    EditorGUILayout.PropertyField(sentence, new GUIContent("Sentece " + s));
                    GUI.color = color;
                }
                EditorGUI.indentLevel--;
            }

            EditorGUI.indentLevel--;
        }

        serializedObject.ApplyModifiedProperties();
    }
}