我有一个自定义EditorWindow
,auxPanel(ScriptableObject
)和许多常规类,它们在面板上都吸引自己的注意力。在这些课程中,我有各种各样的活动。当我启动窗口时-类的实例正在订阅某些事件,并且工作正常。但是,当我更改代码中的某些内容并保存时- Unity 重新编译脚本( Unity 在编译过程中对数据进行序列化和反序列化),并且所有事件均停止工作。例如:
MainWindow:
public class MainWindow : EditorWindow {
public static MainWindow Instance;
public AuxPanel auxPanel;
[MenuItem("Examples/MainWindow")]
static void InitAndRun() {
if (Instance == null) {
Init();
} else {
GetWindow<MainWindow>();
Instance.Focus();
}
}
private void OnEnable() {
if (Instance == null) Instance = GetWindow<MainWindow>();
}
private static void Init(String initForm = null) {
MainWindow mainWindow = GetWindow<MainWindow>();
Instance = mainWindow;
mainWindow.InitializeInstance(initForm);
mainWindow.Show();
}
private void InitializeInstance(String initForm) {
auxPanel = CreateInstance<AuxPanel>().Initialize();
}
private void OnGUI() {
auxPanel.Draw();
}
}
辅助面板:
public class AuxPanel : ScriptableObject {
public Rect DrawRect = new Rect(50, 20, 140, 140);
[SerializeField]
public ElementWithSubscribing myElement { get; set; }
public UnityAction<Vector2> PositionChange = delegate { };
public AuxPanel Initialize() {
myElement = new ElementWithSubscribing(Vector2.zero, this);
return this;
}
public void Draw() {
GUI.Label(DrawRect, "", "GroupBox");
myElement.Draw();
// fire event
PositionChange(DrawRect.position);
}
}
ElementSubscriber:
[Serializable]
public class ElementWithSubscribing {
public Rect DrawRect = new Rect(0, 0, 100, 50);
public ElementWithSubscribing() { }
public ElementWithSubscribing(Vector2 position) { }
public ElementWithSubscribing(Vector2 position, AuxPanel auxPanel) {
auxPanel.PositionChange += UpdatePosition;
}
protected void UpdatePosition(Vector2 designerPosition) {
Debug.Log("event works!");
DrawRect.position = designerPosition;
}
public void Draw() {
GUI.Button(DrawRect, "MyElement");
}
}
保存代码后-ElementWithSubscribing
失去对auxPanel.PositionChange
的订阅。
如何保存活动?还是编译后如何还原? 在此类以及其他课程中,我都有很多事件,这就是为什么暂时不将事件重新附加到某些辅助对象的原因。
P.S。有时在编译之后,上面的代码给了我2个窗口。
答案 0 :(得分:0)
结果很简单
Unity 重新编译脚本时,它将对数据进行序列化和反序列化。因此,在反序列化之后,它将根据保存的序列化数据创建实例,并使用保存的值填充对象。
Unity 创建MonoBehaviour
/ ScriptableObject
派生类的实例时,它将调用默认构造函数来创建托管对象。就我而言,它是public ElementWithSubscribing() { }
。这就是事件不再起作用的原因。