Unity报错:MonoBehaviour构造函数调用Find,已在Start中调用仍报错
GameObject.Find 调用报错排查与解决 错误信息
UnityException: Find 不允许从 MonoBehaviour 构造函数(或实例字段初始化器)中调用,请改为在 Awake 或 Start 中调用。调用来自 MonoBehaviour 'CombatStateMachine'。
请查看 Unity 手册中的“Script Serialization”页面了解更多详情。
CombatStateMachine..ctor () (at Assets/Scripts/BattleStuff/CombatStateMachine.cs:25)
代码情况
你提供的代码显示Find调用确实在Start方法内:
//using Microsoft.Win32; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class CombatStateMachine : MonoBehaviour { public phase currentPhase; bool playerCanAct; int currentRound; public GameObject playerPartyObj; public GameObject enemyPartyObj; private Queue<string> sentences; // Start is called before the first frame update void Start() { currentPhase = phase.start; playerCanAct = false; currentRound = 0; sentences = new Queue<string>(); playerPartyObj = GameObject.Find("PlayerParty"); enemyPartyObj = GameObject.Find("EnemyParty"); StartCoroutine(SetupBattle()); } //More code that isn't really relevant AFAICT }
你已尝试的方案
- 注释
Start中的Find并移至类体 - 在
Start中重新定义对象 - 给
GameObject声明添加[Serializable](提示类型不支持)
问题根源与解决方法
报错指向构造函数/字段初始化阶段调用了Find,但你贴出的代码无此问题,大概率是以下隐藏情况:
1. phase枚举存在违规逻辑
你声明了public phase currentPhase;,如果phase枚举的构造函数或其内部字段的初始化逻辑中间接调用了GameObject.Find,就会触发错误——因为类的字段初始化是在构造函数阶段执行的,currentPhase作为类级字段,初始化时的违规操作会被判定为构造函数内的调用。
- 排查方法:暂时将
public phase currentPhase;替换为public int currentPhase;测试,若报错消失,直接重构phase枚举的逻辑,移除其中涉及Find或其他Unity API的初始化代码。
2. Unity 编译缓存残留
即使你修改了代码,Unity的编译缓存可能保留了旧的违规逻辑(比如之前你曾在字段声明时直接写public GameObject playerPartyObj = GameObject.Find("xxx");)。
- 解决方法:删除项目根目录下的
Library文件夹,重启Unity并重新编译项目。
3. 脚本被重复挂载或存在同名脚本
场景中若有多个对象挂载了CombatStateMachine,或者存在同名的其他脚本,可能某个实例的字段初始化存在违规调用。
- 排查方法:在Hierarchy面板中搜索
CombatStateMachine,检查所有挂载该脚本的对象,确认它们的字段初始化逻辑无问题;同时检查项目中是否有同名脚本文件,避免命名冲突。
4. SetupBattle协程的隐藏问题
虽然你认为其他代码无关,但StartCoroutine(SetupBattle());调用的协程中,如果在第一个yield语句之前调用了GameObject.Find,也可能被判定为构造函数阶段的调用(协程启动时的同步执行部分)。
- 排查方法:检查
SetupBattle协程的开头逻辑,确保所有Find调用都在yield之后执行。
内容的提问来源于stack exchange,提问作者HalfTangible

