@Almost

Как отобразить все поля наследуемых классов с помощью Odin Inspector в Unity?

Здравствуйте.

Есть такой простой пример:

using System;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;

namespace Examples
{
	[CreateAssetMenu(fileName = "Enemies", menuName = "Enemies", order = 0)]
	public class Enemies : ScriptableObject
	{
		public List<Enemy> list = new List<Enemy>();
		
		[Serializable]
		public class Enemy
		{
			public int id;
		}

		[Serializable]
		public class Dragon : Enemy
		{
			public string name;
		}
		
		[Serializable]
		public class Robot : Enemy
		{
			public double damage;
		}
		
		[Button]
		public void AddRobot()
		{
			list.Add(new Robot());
		}
		
		[Button]
		public void AddDragon()
		{
			list.Add(new Dragon());
		}
	}
}


Элементы, добавленные в список, отображают только id классов.
Как сделать, чтобы отображались поля наследуемых классов (урон робота и имя дракона)?
Как вариант, можно добавить атрибут [SerializeReference] к списку и он будет выводиться корректно (без Odin Inspector).
Но если используется Odin Inspector (расширение, которое позволяет очень разнообразно кастомизировать отображение объектов в инспекторе), то поля не выводятся. Хочется увидеть отображение именно в стиле Odin'a, чтобы была возможность настраивать редактор.

5f086364de677559026136.png
  • Вопрос задан
  • 34 просмотра
Пригласить эксперта
Ответы на вопрос 1
DanceM
@DanceM Куратор тега Unity Game Engine
Кто хочет -ищет способ, кто не хочет -ищет причину
Этот вопрос надо адресовать разработчиками Odin'а, пусть добавят поддержку.

Я лишь можу предложить не использовать Odin и реализовать средствами Unity то, что вам надо.
5f08794c05da8280139954.png
ScriptableObjectEditor.cs

using UnityEngine;
using Examples;
using UnityEditor;

[CustomEditor(typeof(Enemies))]
public class ScriptableObjectEditor : Editor
{
	public override void OnInspectorGUI()
	{
		GUILayout.Label("Scriptable Object Editor");
			
		DrawDefaultInspector();

		var myScript = (Enemies)target;
		if(GUILayout.Button("Add Dragon"))
		{
			myScript.AddDragon();
			SaveAsset();
		}
		
		if(GUILayout.Button("Add Robot"))
		{
			myScript.AddRobot();
			SaveAsset();
		}

		void SaveAsset()
		{
			EditorUtility.SetDirty(myScript);
			AssetDatabase.SaveAssets();
			AssetDatabase.Refresh();
		}
	}
}

Enemies.cs
using System;
using System.Collections.Generic;
using UnityEngine;

namespace Examples
{
	[CreateAssetMenu(fileName = "Enemies", menuName = "Enemies", order = 0)]
	public class Enemies : ScriptableObject
	{
		[SerializeReference]
		public List<Enemy> list = new List<Enemy>();
    
		[Serializable]
		public class Enemy
		{
			public int id;
		}

		public class Dragon : Enemy
		{
			public string name;
		}
    
		public class Robot : Enemy
		{
			public double damage;
		}
    
		public void AddRobot()
		{
			list.Add(new Robot());
		}
    
		public void AddDragon()
		{
			list.Add(new Dragon());
		}
	}
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы