Ящик пользовательских свойств Unity для UnityEngine.Объект

#c# #unity3d #unity-editor

#c# #unity3d #unity-редактор

Вопрос:

Я не знаю, смогу ли я это сделать, чтобы переопределить какое-либо свойство объекта, но я экспериментировал с переопределением различных типов объектов, и вместо того, чтобы показывать селектор полей для выбора объекта, я заставлял их показывать всплывающее окно только с именем объекта и назначением соответствующего файла при выборе. Это сработало для всех случаев, которые я создал, но я надеялся попытаться переопределить для всех случаев, когда поле запрашивает объект (я думаю, что это просто выглядит чище). Как бы я мог получить тип запрашиваемого объекта из его сериализованного свойства?

конкретный пример типа выглядит следующим образом

 public class Item : ScriptableObject {}  

если у меня нет созданных элементов, свойство отображается как обычно (предотвращает ошибки, связанные с исключениями нулевых ссылок).

Ящик свойств, когда элементов не существует

но когда у меня есть элементы, внешний вид свойства меняется на это (и гарантирует, что значение задано, если оно еще не задано).

введите описание изображения здесь

Ящик с собственностью довольно прост

 public override void OnGUI(/* parameters */) {  GUIContent[] names = GetNames(out Item[] items);  if(names.Length == 0) {  property.objectReferenceValue = EditorGUI.ObjectField(position, label, property.objectReferenceValue, typeof(Item), true);  } else {  if(property.objectReferenceValue == null) {  property.objectReferenceValue = items[0];  }  property.objectReferenceValue = items[EditorGUI.Popup(position, label, Array.IndexOf(items, (Item)property.objectReferenceValue), names)];  } }  

а метод GetNames заключается в следующем

 public static GUIContent[] GetNameslt;Tgt;(out T[] assets) where T : UnityEngine.Object {  Listlt;GUIContentgt; names = new Listlt;GUIContentgt;();  Listlt;Tgt; assets1 = new Listlt;Tgt;();  foreach(string guid in AssetDatabase.FindAssets($"t:{typeof(T).ToString().ToLower()}")) {  string path = AssetDatabase.GUIDToAssetPath(guid);  names.Add(new GUIContent(Path.GetFilenameWithoutExtension(path)));  assets1.Add(AssetDatabase.LoadAssetAtPathlt;Tgt;(path));  }  assets = assets1.ToArray();  return names.ToArray(); }  

Этот метод работает, если я пишу ящик свойств для определенного типа (т. Е. элемента), но я надеялся переопределить селектор объектов по умолчанию, чтобы следовать этому методу.

Комментарии:

1. Довольно неясно, чего вы пытаетесь достичь .. не могли бы вы показать какой-нибудь код, который вы пробовали до сих пор, и что именно работает не так, как ожидалось? Может быть, добавить несколько рисунков того, что должно произойти, и т. Д..

2. Я добавлю их через несколько минут.

3. Ну, я могу сказать вам, что обобщать это для каждого типа, полученного из UnityEngine.Object , — очень плохая идея! Давайте возьмем, например GameObject … вы действительно хотите, чтобы каждое Transform поле автоматически заполнялось первым GameObject найденным в ваших активах? И еще хуже: вы автоматически хотите загрузить их все в память?

4. Это правда, я понял это и решил, что пойду немного конкретнее и перейду от UnityEngine. ScriptableObject, но независимо от того, намеревался ли я сделать это для объекта или ScriptableObject, я все еще не могу заставить его работать