CustomEditor Unity: одновременный выбор перечислений + отображение массива
Я пытаюсь сделать что-то на 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 ответ
Пытался понять, что ты делал. Ваша ошибка не состояла в изменении элементов массива и нескольких других проблем.
Это твой новый 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();
}
}
В единстве:
Надеюсь, это работает.