- Home /
Question by
lezard1999 · Mar 05, 2018 at 04:18 AM ·
custom editorcustom-inspector
How can I custom part of editor's fields on Inspector?
Here is my target Script which is derives from ScriptObject as a data asset‘s template to create data container.
public class UnitSpawnerProperty : ScriptableObjectBase
{
public string unitName="UnitSpawner";
public GameObject unitPrefab;
public int unitMaxHp;
public float unitSpawnInterval=2;
public int spawnWave = 1;
public UnitState.UnitLogic[] unitLogicName;
public int[] unitCountofOneWave;
public ScriptableObject[] unitSpawnDatas;
public UnitState.BehaviourType unitBehaviourType= UnitState.BehaviourType.ConstructionType;
public UnitState.BehaviourState unitBehaviourState= UnitState.BehaviourState.Idling;
public UnitState.UnitMoveType unitMoveType= UnitState.UnitMoveType.CanNotMove;
private void OnEnable()
{
tagName = "UnitSpawner";
unitPrefab = Resources.Load("Prefab/Unit/UnitSpawner") as GameObject;
if (unitLogicName == null)
{
unitLogicName = new UnitState.UnitLogic[spawnWave];
unitLogicName[0] = UnitState.UnitLogic.Soldier;
}
if (unitCountofOneWave == null)
{
unitCountofOneWave = new int[spawnWave];
unitCountofOneWave[0] = 1;
}
if (unitSpawnDatas == null)
{
unitSpawnDatas = new ScriptableObject[spawnWave];
unitSpawnDatas[0] = null;
}
}
}
Now what I want exactly is make a CustomEditor just to redraw
unitLogicName unitCountofOneWave unitSpawnDatas
this 3 part.
And I am already made a a satisfied code with them,like this:
[CustomEditor(typeof(UnitSpawnerProperty))]
public class UnitSpawnerPropertyEditor : Editor
{
private bool[] showSpawnUnitGUI;
private UnitSpawnerProperty unitSpawnerProperty;
private SerializedProperty unitLogicNameProperty;
private SerializedProperty unitCountofOneWaveProperty;
private SerializedProperty unitSpawnDatasProperty;
private const string unitLogicNamePropertyName = "unitLogicName";
private const string unitCountofOneWaveName = "unitCountofOneWave";
private const string unitSpawnDatasName = "unitSpawnDatas";
private const float addButtonWidth = 50f;
private const float removeButtonWidth = 80f;
private void OnEnable()
{
unitSpawnerProperty = (UnitSpawnerProperty)target;
if (target == null)
{
DestroyImmediate(this);
return;
}
showSpawnUnitGUI = new bool[unitSpawnerProperty.spawnWave];
//currentArrayLength = showSpawnUnitGUI.Length;
unitLogicNameProperty = serializedObject.FindProperty(unitLogicNamePropertyName);
unitCountofOneWaveProperty = serializedObject.FindProperty(unitCountofOneWaveName);
unitSpawnDatasProperty = serializedObject.FindProperty(unitSpawnDatasName);
}
public override void OnInspectorGUI()
{
serializedObject.Update();
unitSpawnerProperty = (UnitSpawnerProperty)target;
for (int i = 0; i < unitSpawnerProperty.spawnWave; i++)
{
SpawnUnitGUI(i);
}
EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Add", GUILayout.Width(addButtonWidth)))
{
//UnitSpawnerProperty.spawnWave += 1;
unitSpawnerProperty.spawnWave += 1;
bool[] tempShowSpawnUnitGUI= showSpawnUnitGUI;
showSpawnUnitGUI = new bool[unitSpawnerProperty.spawnWave];
for (int i = 0; i < showSpawnUnitGUI.Length -1; i++)
{
showSpawnUnitGUI[i] = tempShowSpawnUnitGUI[i];
}
showSpawnUnitGUI[showSpawnUnitGUI.Length - 1] = true;
unitLogicNameProperty.AddToUnitLogicNameArray(UnitState.UnitLogic.Soldier);
unitCountofOneWaveProperty.AddToIntArray(1);
SoldierProperty newUnitData = CreateInstance<SoldierProperty>();
unitSpawnDatasProperty.AddToObjectArray(newUnitData);
}
EditorGUILayout.EndHorizontal();
serializedObject.ApplyModifiedProperties();
}
private void SpawnUnitGUI(int index)
{
bool hasBeenRemoved = false;
EditorGUILayout.BeginVertical(GUI.skin.box);
EditorGUI.indentLevel++;
EditorGUILayout.BeginHorizontal();
showSpawnUnitGUI[index] = EditorGUILayout.Foldout(showSpawnUnitGUI[index], "SpawnWave " + index);
GUILayout.FlexibleSpace();
if (GUILayout.Button("Remove", GUILayout.Width(removeButtonWidth)))
{
unitLogicNameProperty.RemoveFromIntArrayAt(index);
unitCountofOneWaveProperty.RemoveFromIntArrayAt(index);
unitSpawnDatasProperty.RemoveFromObjectArrayAt(index);
bool[] tempshowSpawnUnitGUI = showSpawnUnitGUI;
unitSpawnerProperty.spawnWave -= 1;
showSpawnUnitGUI = new bool[unitSpawnerProperty.spawnWave];
for (int i = 0; i < showSpawnUnitGUI.Length; i++)
{
if(i<index)
{
showSpawnUnitGUI[i] = tempshowSpawnUnitGUI[i];
}
else
{
showSpawnUnitGUI[i] = tempshowSpawnUnitGUI[i+1];
}
}
hasBeenRemoved = true;
}
EditorGUILayout.EndHorizontal();
if (!hasBeenRemoved)
{
if (showSpawnUnitGUI[index])
{
EditorGUILayout.PropertyField(unitLogicNameProperty.GetArrayElementAtIndex(index), new GUIContent("Type"));
EditorGUILayout.PropertyField(unitCountofOneWaveProperty.GetArrayElementAtIndex(index), new GUIContent("Count"));
EditorGUILayout.PropertyField(unitSpawnDatasProperty.GetArrayElementAtIndex(index), new GUIContent("Data"));
}
}
EditorGUI.indentLevel--;
EditorGUILayout.EndVertical();
}
}
Now thhe inspector is look like this and I'm happy with it:
Now the Only Question is how to easily display other fields by default ? Is there a quick way to do that because I really don't want to finds tons of other field‘s SerializedProperty and define them one by one.
123.jpg
(11.5 kB)
Comment