У меня есть сборный сценарий со скриптом MonoBehaviour с именем RoomInfo
. Я использую собственный редактор для переопределения OnSceneGUI()
, чтобы сделать кликабельные кубы, чтобы изменить список выходов из комнаты. Когда я открываю готовый сборник для редакции, изменения должны быть применены к сборному активу, но я не могу найти, как это сделать.
Это в префаб-режиме (начиная с Unity 2018) при открытии префаба. Я пытался использовать методы из класса PrefabUtility
, но GameObject
, возвращаемый из ((RoomInfo)target).gameObject
, не принадлежит ни к какому префабу (?!?), См. Функцию IsPartOfAnyPrefab(Object componentOrGameObject)
. Кроме того, проблема заключается только в сохранении готового ресурса, поскольку при редактировании готового экземпляра в GameScene он работает.
Класс для проверки:
public class RoomInfo : MonoBehaviour
{
[SerializeField, Range(1, 10)]
private int XTile = 1;
[SerializeField, Range(1, 7)]
private int YTile = 1;
[SerializeField, HideInInspector]
private List<Vector2Int> Exits_Up = new List<Vector2Int>();
[SerializeField, HideInInspector]
private List<Vector2Int> Exits_Down = new List<Vector2Int>();
[SerializeField, HideInInspector]
private List<Vector2Int> Exits_Right = new List<Vector2Int>();
[SerializeField, HideInInspector]
private List<Vector2Int> Exits_Left = new List<Vector2Int>();
}
Редактор:
[CustomEditor(typeof(RoomInfo), true)]
public class RoomInspector : Editor
{
private RoomInfo room = null;
private SerializedProperty upExitsProperty;
private SerializedProperty downExitsProperty;
private SerializedProperty rightExitsProperty;
private SerializedProperty leftExitsProperty;
private void Awake()
{
room = target as RoomInfo;
upExitsProperty = serializedObject.FindProperty("Exits_Up");
downExitsProperty = serializedObject.FindProperty("Exits_Down");
rightExitsProperty = serializedObject.FindProperty("Exits_Right");
leftExitsProperty = serializedObject.FindProperty("Exits_Left");
}
public void OnSceneGUI()
{
serializedObject.Update();
for (int i = 0; i < room.XTileNb; i++) // Down
{
Vector3 pos = new Vector3(i + 0.5f, -0.5f, -0.5f);
Vector2Int coordinates = new Vector2Int(i, 0);
int index = -1;
bool contain = Contains(downExitsProperty, coordinates, ref index);
if (contain)
Handles.color = new Color(0.0f, 1.0f, 0.0f, 0.8f);
else
Handles.color = new Color(1.0f, 0.0f, 0.0f, 0.8f);
if (Handles.Button(pos, Quaternion.identity, 1.0f, 1.0f, Handles.CubeHandleCap))
{
if (contain)
Remove(downExitsProperty, index);
else
Add(downExitsProperty, coordinates);
Repaint();
}
}
// ...
// Repeated 3 times for up, left and right of the room
serializedObject.ApplyModifiedPropertiesWithoutUndo();
}
Методы Contains
, Remove
и Add
являются просто справочными функциями для управления сериализованными свойствами в виде списка.
Я хотел бы иметь возможность применить изменения к сборным активам, поскольку они сделаны, чтобы дизайнеры могли создавать сборные комнаты, их нельзя изменять в игровой сцене. Спасибо за любую помощь! :)