CustomEditor Unity: одновременный выбор перечислений + отображение массива - PullRequest
0 голосов
/ 30 сентября 2018

Я пытаюсь сделать что-то на Unity и попал в тупик;

Это может быть немного сложно, но посмотрим, сможете ли вы мне помочь:

Что яполучил и то, что я хочу (изображение)

Это скрипт, который я получил сейчас

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, но будет больше классов.

Я провел некоторое исследование и выяснил, что я должен использовать OnInspectorGUI, если я хочу быть таким конкретным (если есть другиенаоборот, пожалуйста, скажите мне)

Я получил 0 опыта на CustomEditor, так что я получил до сих пор

[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);
            }
        }

    }

}

И это значит, в редакторе:

Если я изменю значение одного перечисления, все остальные копируют его (изображение)

И это именно то, чего я не хочу.И имейте в виду, когда редактор выбирает MatarGente или PegarItem, я хотел бы показать все те возможные переменные, которые содержатся в этих классах.Это включает в себя массивы с неопределенной длины.А также, если есть 2 «MatarGente», я бы хотел иметь возможность заполнять эти массивы различными объектами и впоследствии получать эту информацию, чтобы использовать ее где-то еще.

1 Ответ

0 голосов
/ 30 сентября 2018

Пытался понять, что ты делал.Ваша ошибка не состояла в изменении элементов массива и несколько других проблем.

Это ваш новый 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

Надеюсь, это сработает.

...