CustomEditor Unity:一次选择枚举+显示数组
CustomEditor Unity: chosing enums at once + showing array
我正试图在 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,我只显示 class PegarItem。
现在只有 PegarItem 和 MatarGente,但以后会有更多 classes。
我做了一些研究,发现我应该使用 OnInspectorGUI 如果我想要那么具体(如果有其他方法,请告诉我)
我在 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 时,我想显示这些 classes 包含的所有可能变量。这包括具有非特定长度的数组。
而且,如果有 2 'MatarGente',我希望能够用不同的对象填充这些数组并稍后检索该信息以在其他地方使用它。
试图理解你在做什么。你的错误是没有修改数组元素和其他一些问题。
这是你的新 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
class:
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 中:
希望这有效。
我正试图在 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,我只显示 class PegarItem。
现在只有 PegarItem 和 MatarGente,但以后会有更多 classes。
我做了一些研究,发现我应该使用 OnInspectorGUI 如果我想要那么具体(如果有其他方法,请告诉我)
我在 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 时,我想显示这些 classes 包含的所有可能变量。这包括具有非特定长度的数组。 而且,如果有 2 'MatarGente',我希望能够用不同的对象填充这些数组并稍后检索该信息以在其他地方使用它。
试图理解你在做什么。你的错误是没有修改数组元素和其他一些问题。
这是你的新 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
class:
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 中:
希望这有效。