我正在使用 Unity 3D,但是,這些資訊應該與解決這個問題無關,因為核心問題是 System.Delegate(我想讓你知道,因為我將鏈接到一些 Unity 檔案進行澄清)。
我有一個具有自定義更新功能的自定義視窗DirectorUpdate。無論用戶/視窗在做什么,我都需要此功能來運行每個編輯器更新。
為了在每次編輯器更新時呼叫它,我將我的方法與 Delegate EditorApplication.update結合起來:
protected void OnEnable()
{
// If I do the below, base EditorApplication.update won't be called anymore.
// EditorApplication.update = this.DirectorUpdate;
// So I need to do this:
EditorApplication.update = (EditorApplication.CallbackFunction)System.Delegate.Combine(new EditorApplication.CallbackFunction(this.DirectorUpdate), EditorApplication.update);
... // Other stuff
}
請注意,這是在視窗的OnEnable內完成的。
問題是 OnEnable 可以在單次運行期間多次呼叫(例如,關閉視窗然后在單個編輯器會話期間重新打開視窗時)導致
EditorApplication.update = (EditorApplication.CallbackFunction)System.Delegate.Combine(new EditorApplication.CallbackFunction(this.DirectorUpdate), EditorApplication.update);
被多次呼叫,這意味著我的更新方法(this.DirectorUpdate)最終會在每次更新時被多次呼叫,這會導致一些嚴重的錯誤。
所以, 問題是我如何檢查EditorApplication.update我的方法是否已經“內置”了。(在里面,我當然是說它已經System.Delegate.Combine(d)到了代表那里。)
我知道可能還有其他解決方案,例如在視窗關閉時將 EditorApplication.update 恢復到之前的狀態,但這并不能說明所有情況(例如,在視窗重繪 等期間也會呼叫 OnEnable)和該錯誤將持續存在。(另外,如果另一個視窗在此視窗打開時與 EditorApplication.update 連接怎么辦?)因此,最好的解決方案是檢查 EditorApplication.update 是否已經在 Delegate.Combine-ing 之前呼叫了此方法。
uj5u.com熱心網友回復:
我想你走了復雜的路;)
訂閱和退訂事件和委托很簡單,只要使用運營商 =和-=像
protected void OnEnable()
{
// You can substract your callback even though it wasn't added so far
// This makes sure it is definitely only added once (for this instance)
EditorApplication.update -= DirectorUpdate;
// This basically internally does such a Combine for you
EditorApplication.update = DirectorUpdate;
... // Other stuff
}
private void OnDisable()
{
// Remove the callback once not needed anymore
EditorApplication.update -= DirectorUpdate;
}
通過這種方式,您還可以打開此視窗的多個實體,并且它們都將單獨接收回呼。
順便說一句,如果這實際上是關于EditorWindow然后 afaik 你不應該使用OnEnabled但你寧愿使用Awake
在新視窗打開時呼叫。
和OnDestroy。
uj5u.com熱心網友回復:
我不熟悉是什么System.Delegate.Combine(d),但您可以考慮而不是啟用/禁用您的視窗,每次銷毀和實體化它,并將您的代碼移動到Start或Awake以便每個視窗“激活”只呼叫一次。
最后但并非最不重要的一點是,在 中使用強大的布林值,OnDisable以便您可以在組件被禁用時處理組合執行。像這樣:
bool omgIWasDisabled;
protected void OnEnable()
{
if (!omgIWasDisabled) {
EditorApplication.update = (EditorApplication.CallbackFunction)System.Delegate.Combine(new EditorApplication.CallbackFunction(this.DirectorUpdate), EditorApplication.update);
}
... // Other stuff
}
void OnDisable() {
omgIWasDisabled = true;
}
希望其中任何一個都能奏效。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/385955.html
