一天中的好时光。 我不参与编辑器的定制,但我决定看看一些东西以及如何,同时组织我的检查器。 面对获取私有字段并不是那么容易的问题。我通过反思阅读了应该做的事情。 最后,一切似乎都很好,直到我遇到了一个问题: 由于某种原因,该值未保存...这是代码:
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
[CustomEditor(typeof(Door))]
public class DoorEditor : Editor
{
private Door _target;
private SerializedObject _serializedObject;
private SerializedProperty
_state,
_startPoint;
private void OnEnable() {
_target = (Door)target;
_serializedObject = new SerializedObject(_target);
_startPoint = _serializedObject.FindProperty("_startPoint");
_state = serializedObject.FindProperty("_state");
}
public override void OnInspectorGUI() {
EditorGUILayout.BeginVertical("box");
_startPoint.objectReferenceValue = (Transform)EditorGUILayout.ObjectField("Start Point", _startPoint.objectReferenceValue, typeof(Transform), true);
_state.enumValueIndex = (int)(DoorState)EditorGUILayout.EnumPopup((DoorState)_state.enumValueIndex);
//Actually the line above does not work. and to be more precise, even "_state.enumValueIndex = 1" does not change the value _state.enumValueIndex, why?...
EditorGUILayout.EndVertical();
EndOnInspectorGUI();
}
private void EndOnInspectorGUI() {
if (_serializedObject != null)
_serializedObject.ApplyModifiedProperties();
if (GUI.changed) SetObjectDirty(_target.gameObject);
}
public static void SetObjectDirty(GameObject obj) {
EditorUtility.SetDirty(obj);
EditorSceneManager.MarkSceneDirty(obj.scene);
}
}
编写编辑器的类:
public class Door : MonoBehaviour, IInteract
{
[SerializeField] private Transform _startPoint; public Transform StartPoint => _startPoint;
[SerializeField] private DoorState _state = DoorState.Open; public DoorState State => _state;
[SerializeField] private DoorType _type = DoorType.Standart;
[SerializeField, TextArea(1, 3)] private string _massage = "Error! Сообщение не назначено";
[SerializeField] private AudioSource _audioSource;
[SerializeField] private DoorOpeningSounds _doorOpeningSounds;
public UnityEvent OnOpenDoor;
public UnityEvent OnEnterTheDoor;
public void SetMassage(string newMassage) {
_massage = newMassage;
}
public void SetState(DoorState newState) {
_state = newState;
}
public void OpenTheDoor() {
_audioSource.clip = _doorOpeningSounds.GetClip(_type);
_audioSource.Play();
OnOpenDoor.Invoke();
}
private void EnterTheDoor() {
OpenTheDoor();
OnEnterTheDoor.Invoke();
}
public void Interact() {
if (_state == DoorState.Open) {
EnterTheDoor();
} else if (_state == DoorState.Loced) {
SubtitlesManager.Instance.ShowSubtitles(new Subtitle("Закрыто", 2f), true);
} else if (_state == DoorState.Broken) {
SubtitlesManager.Instance.ShowSubtitles(new Subtitle("Ручка сломана", 2f), true);
} else if (_state == DoorState.Bloked) {
SubtitlesManager.Instance.ShowSubtitles(new Subtitle("Дверь что-то блокирует", 2f), true);
} else if (_state == DoorState.NoActive) {
SubtitlesManager.Instance.ShowSubtitles(new Subtitle("Не поддаётся", 2f), true);
} else if (_state == DoorState.Massage) {
SubtitlesManager.Instance.ShowSubtitles(new Subtitle(_massage, 2f), true);
} else {
Debug.LogError("Действие двери в состоянии " + _state + " не реализовано");
}
}
}
枚举是最常见的:
public enum DoorState
{
Open,
Loced,
Broken,
Bloked,
NoActive,
Massage
}
不是我不会设置值,我已经试过很多方法了。事实上,设置值会在 OnInspectorGUI 的下一次迭代中重置。 如果我安装它并在一次迭代中进行检查和操作,一切都会正常,但是一旦下一次迭代开始,该值将立即重置。 不知何故,设置值后,我不保存它,但一般保存发生在 EndOnInspectorGUI() 的每次迭代结束时; 这是一个无法设置值的视频:https://youtu.be/PZm9jiLxTM4
我在检查器中尝试了各种显示选项。但问题是 _state.enumValueIndex 在赋值时不保存值