Unity中PopUp实例化后委托引用为空的问题求助
问题解决:Unity PopUp实例化后外部回调丢失
问题原因
Unity序列化系统不支持委托和事件的序列化:
- 你给预制体
PopUp设置的callBackAction委托字段,在调用Instantiate创建新实例时,不会被复制到新对象中,新实例的该字段会保持预制体的初始值(null)。 - 若直接在预制体的
SetCallBackAction中给CallBack事件添加订阅,实例化后的新对象的CallBack事件是全新的,不会继承预制体上的订阅记录。
解决方案
把外部回调与PopUp预制体、数据一起存入PopUpPair,而非存在PopUp对象本身。实例化PopUp后,再从PopUpPair中取出回调添加到实例的事件中。
修改后的代码
PopUpPair类
public class PopUpPair { private PopUp popUpPrefab; private object data; private PopUp.ContinueCallBack externalCallback; public PopUp PopUpPrefab => popUpPrefab; public object Data => data; public PopUp.ContinueCallBack ExternalCallback => externalCallback; public void Create<T>(PopUp prefab, T value, PopUp.ContinueCallBack callback) where T : class { popUpPrefab = prefab; data = value; externalCallback = callback; } }
PopUpManager类
public void AddPopUpToQueue<T>(PopUp popUpPrefab, T data, PopUp.ContinueCallBack callBack) { var _pair = new PopUpPair(); // 将回调与预制体、数据一起存入Pair,不再修改预制体本身 _pair.Create<T>(popUpPrefab, data, callBack); popUpQueue.Enqueue(_pair); } public void ShowNextPopUp() { if (popUpQueue.Count == 0) return; var _popUpPair = popUpQueue.Dequeue(); var _popUp = Instantiate(_popUpPair.PopUpPrefab, transform); // 添加内置的ShowNextPopUp回调 _popUp.CallBack += ShowNextPopUp; // 添加外部传入的回调(判空避免空引用) if (_popUpPair.ExternalCallback != null) { _popUp.CallBack += _popUpPair.ExternalCallback; } if (_popUpPair.Data != null) _popUp.FillData(_popUpPair.Data); }
PopUp类(简化)
移除不需要的委托存储字段和方法:
public delegate void ContinueCallBack(); public event ContinueCallBack CallBack; // 移除以下冗余代码: // private ContinueCallBack callBackAction; // public ContinueCallBack CallBackAction => callBackAction; // public void SetCallBackAction(ContinueCallBack action) {...}
内容的提问来源于stack exchange,提问作者Kureyş Alp Kılıç
相关产品推荐
相关产品推荐

