CustomEditor Unity:一次选择枚举+显示数组

时间:2018-09-29 22:05:22

标签: c# unity3d editor inspector

我试图在Unity上做某事并被赶上;

这可能有点复杂,但是请查看是否可以帮助我

What I got and what I want (image)

这是我现在得到的脚本

public class ClasseTest : MonoBehaviour{


    public enum TiposDeMissoes
    {
        TipoMatarGente,
        TipoPegarItem,
    };
        public TiposDeMissoes TiposMissoes;


    [Serializable]
    public class MatarGente
    {
        public int IDmissao;
        public GameObject[] ObjetosAtivarPraMissao;
        public GameObject[] Checkpoints;
        public GameObject[] InimigosPraMatar;
    }
    [Serializable]
    public class PegarItem
    {
        public int IDmissao;
        public GameObject[] ObjetosAtivarPraMissao;
        public GameObject[] Checkpoints;
        public GameObject[] ItemsEntregar;
    }

    [Serializable]
    public class Missoes
    {
        public TiposDeMissoes TiposMissoes;
        public PegarItem[] PegarItem;
        public MatarGente[] MatarGente;
    }

    public Missoes[] MissoesJogasso;

}

如果在枚举中选择了PegarItem,我只会显示类PegarItem。

现在只有PegarItem和MatarGente,但是会有更多的类。

我进行了一些研究,发现我是否想使用特定于我的InInspectorGUI(如果还有其他方法,请告诉我)

我在CustomEditor上获得了0经验,所以到目前为止我是

[CustomEditor(typeof(ClasseTest))]
public class TestCustomInspector : Editor
{
    public int numMissoes;

    public override void OnInspectorGUI()
    {
        ClasseTest script = (ClasseTest)target;

        numMissoes = EditorGUILayout.IntField("Numero de Missoes", numMissoes);

        EditorGUILayout.LabelField("Editante");
        var serializedObject = new SerializedObject(target);
        var property = serializedObject.FindProperty("MissoesJogasso");
        serializedObject.Update();
        EditorGUILayout.PropertyField(property, true);
        serializedObject.ApplyModifiedProperties();

        for (int i = 0; i < numMissoes; i++)
        {
            script.TiposMissoes = (ClasseTest.TiposDeMissoes)EditorGUILayout.EnumPopup("TIPO DE MISSAO", script.TiposMissoes);

            if (script.TiposMissoes == ClasseTest.TiposDeMissoes.TipoMatarGente)
            {
                script.TiposMissoes = (ClasseTest.TiposDeMissoes)EditorGUILayout.EnumPopup("Matar Gentes", script.TiposMissoes);
            }

            if (script.TiposMissoes == ClasseTest.TiposDeMissoes.TipoPegarItem)
            {
                script.TiposMissoes = (ClasseTest.TiposDeMissoes)EditorGUILayout.EnumPopup("Pegar Item", script.TiposMissoes);
            }
        }

    }

}

这意味着在编辑器中:

If I change the value of one enum, all the others copy it (image)

而这正是我所不想要的。 所有人,请记住当编辑器选择MatarGente或PegarItem时,我想显示这些类所拥有的所有可能变量。这包括具有非特定长度的数组。 而且,如果有2个'MatarGente',我希望能够用不同的对象填充这些数组,并稍后检索该信息以在其他地方使用。

1 个答案:

答案 0 :(得分:1)

试图了解您在做什么。您的错误是没有修改数组元素和其他一些问题。

这是您的新ClasseTest

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

public class ClasseTest : MonoBehaviour
{
    public enum TiposDeMissoes
    {
        TipoMatarGente,
        TipoPegarItem,
    }

    [Serializable]
    public class MatarGente
    {
        public int IDmissao;
        public GameObject[] ObjetosAtivarPraMissao;
        public GameObject[] Checkpoints;
        public GameObject[] InimigosPraMatar;
    }

    [Serializable]
    public class PegarItem
    {
        public int IDmissao;
        public GameObject[] ObjetosAtivarPraMissao;
        public GameObject[] Checkpoints;
        public GameObject[] ItemsEntregar;
    }

    [Serializable]
    public class Missoes
    {
        public TiposDeMissoes TiposMissoes;
        public PegarItem[] PegarItem;
        public MatarGente[] MatarGente;
    }

    public List<Missoes> MissoesJogasso;
    public int NumMissoes;
}

这是您的新TestCustomInspector类:

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

[CustomEditor(typeof(ClasseTest))]
public class TestCustomInspector : Editor
{
    public override void OnInspectorGUI()
    {
        ClasseTest script = (ClasseTest)target;

        script.NumMissoes = EditorGUILayout.IntField("Numero de Missoes", script.NumMissoes);
        // Ensure it cannot go into negative numbers.
        if (script.NumMissoes < 0) script.NumMissoes = 0;

        // Create the list if it does not exist.
        if(script.MissoesJogasso == null) script.MissoesJogasso = new List<ClasseTest.Missoes>();

        // numMissoes being greater than the current count means we need to extend the list.
        if (script.NumMissoes > script.MissoesJogasso.Count)
        {
            for (int i = 0; i < script.NumMissoes; i++)
            {
                script.MissoesJogasso.Add(new ClasseTest.Missoes());
            }
        }
        // numMissoes being less than the current count means we need to decrease the list.
        else if(script.NumMissoes < script.MissoesJogasso.Count)
        {
            int difference = script.MissoesJogasso.Count - script.NumMissoes;

            // Remove the last element difference number of times.
            for (int i = 0; i < difference; i++)
            {
                script.MissoesJogasso.RemoveAt(script.MissoesJogasso.Count - 1);
            }
        }

        var serializedTarget = new SerializedObject(target);

        for (int i = 0; i < script.MissoesJogasso.Count; i++)
        {
            var missoes = script.MissoesJogasso[i];

            switch(missoes.TiposMissoes)
            {
                case ClasseTest.TiposDeMissoes.TipoMatarGente:
                    missoes.TiposMissoes = (ClasseTest.TiposDeMissoes)EditorGUILayout.EnumPopup("Matar Gentes", missoes.TiposMissoes);
                    DrawProperty(serializedTarget, string.Format("MissoesJogasso.Array.data[{0}].MatarGente", i));
                    break;

                case ClasseTest.TiposDeMissoes.TipoPegarItem:
                    missoes.TiposMissoes = (ClasseTest.TiposDeMissoes)EditorGUILayout.EnumPopup("Pegar Item", missoes.TiposMissoes);
                    DrawProperty(serializedTarget, string.Format("MissoesJogasso.Array.data[{0}].PegarItem", i));
                    break;
            }
        }
    }

    private void DrawProperty(SerializedObject serializedObject, string propertyName)
    {
        var property = serializedObject.FindProperty(propertyName);
        serializedObject.Update();
        EditorGUILayout.PropertyField(property, true);
        serializedObject.ApplyModifiedProperties();
    }
}

在Unity中:

The custom inspector in Unity

希望这行得通。