Unity报错:MonoBehaviour构造函数中调用Load不被允许
问题分析
报错的核心原因是Unity禁止在MonoBehaviour的构造函数或字段初始化阶段调用Resources.Load。你的代码里,Dialogue类在初始化voicesA数组时直接访问MyAssets.instances,而MyAssets的静态属性getter里调用了Resources.Load,触发了Unity的限制。另外MyAssets的getter还存在递归错误:return instances会无限调用自身,应该返回_i。
修复步骤
1. 修正MyAssets的单例实现
把实例化逻辑从静态属性getter中调整,同时修复递归问题,推荐更稳妥的单例写法:
public class MyAssets : MonoBehaviour { private static MyAssets _i; public static MyAssets instances { get { if (_i == null) { // 确保Resources文件夹下存在名为"MyAssets"的预制体 GameObject assetObj = Resources.Load<GameObject>("MyAssets"); _i = Instantiate(assetObj).GetComponent<MyAssets>(); // 可选:让实例不随场景销毁 DontDestroyOnLoad(_i.gameObject); } return _i; // 修复递归问题,返回实例变量而非属性本身 } } public AudioClip a0; // 可选:如果场景中已放置MyAssets实例,用Awake初始化单例避免重复创建 private void Awake() { if (_i == null) { _i = this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } }
2. 修改Dialogue类,延迟初始化数组
将voicesA的初始化从字段定义阶段移到Awake或Start方法中,避开构造阶段的限制:
public class Dialogue : MonoBehaviour { public AudioClip[] voicesA; // 先声明数组,不做初始化 private void Awake() { // 在Awake阶段完成数组初始化 voicesA = new AudioClip[] { MyAssets.instances.a0 }; } }
额外注意
- 确认
MyAssets预制体确实放在Resources文件夹下,否则Resources.Load会返回null。 - 如果项目场景中已经存在
MyAssets实例,优先使用Awake初始化单例的方式,避免重复实例化对象。
内容的提问来源于stack exchange,提问作者Joshua Wagner
相关产品推荐
相关产品推荐

