Unity跨脚本访问PauseButton的firstTimePause变量恒为false问题
问题场景
相关脚本代码
- 挂载到游戏对象上的
PauseButton脚本代码如下:
public class PauseButton : MonoBehaviour { public bool firstTimePause; private bool checkIfPause; public void Awake() { firstTimePause = false; } public virtual void PauseButtonAction() { StartCoroutine(PauseButtonCo()); } protected virtual IEnumerator PauseButtonCo() { yield return null; checkIfPause = GameObject.Find("SomeObject").GetComponent<GameManager>().Paused; if (firstTimePause == false && this.gameObject.name == "ResumeBackground" && checkIfPause == true) { firstTimePause = true; Debug.Log("This is getting printed"); } } }
- 用于读取
firstTimePause字段的StopWatchTimer脚本代码如下:
public class StopWatchTimer : MonoBehaviour { public Text textTime; private PauseButton pauseButtonScript; public GameObject pauseButtonObject; void Start() { pauseButtonScript = pauseButtonObject.GetComponent<PauseButton>(); } void Update() { pauseButtonScript = pauseButtonObject.GetComponent<PauseButton>(); Debug.Log(pauseButtonScript.firstTimePause); // 该值始终为false,即使PauseButton类中已完成赋值 if (pauseButtonScript.firstTimePause == true) { // 执行业务逻辑 } } }
异常表现
- 触发暂停逻辑后,控制台可以正常打印
This is getting printed日志,说明firstTimePause = true的代码行已经被执行 - 但
StopWatchTimer中读取到的firstTimePause值始终为false,无法进入后续业务分支 - 移除
PauseButtonCo中的if判断、直接给firstTimePause赋值为true时,功能可以正常运行 - 挂载
GameManager组件的SomeObject对象参考截图:
问题根因
该问题是典型的Unity脚本实例引用不匹配问题,核心逻辑如下:
- 如果
PauseButton脚本仅挂载在你最初提到的名为PauseButton的游戏对象上,判断条件this.gameObject.name == "ResumeBackground"永远无法满足,不可能打印出目标日志。 - 日志能正常打印,证明实际执行协程、完成
firstTimePause赋值的脚本实例,挂载在名为ResumeBackground的游戏对象上——也就是说场景中至少存在两个挂载了PauseButton脚本(或其子类)的对象。 StopWatchTimer中序列化赋值的pauseButtonObject是名为PauseButton的游戏对象,拿到的是该对象上的脚本实例,这个实例从未触发过firstTimePause = true的赋值逻辑,因此读取到的值永远是初始值false。- 移除if判断直接赋值时,只要触发的是
PauseButton对象上的脚本实例的对应方法,该实例的字段就会被正常修改,StopWatchTimer自然能读到正确值,这也进一步印证了引用不匹配的判断。
修复方案
- 第一步:在Hierarchy面板全局搜索
PauseButton脚本(含继承自它的子类)的挂载情况,确认ResumeBackground对象上确实存在该脚本实例。 - 第二步:根据业务需求修正引用:
- 如果需要读取的是
ResumeBackground对象上的firstTimePause值,直接将StopWatchTimer组件面板上的pauseButtonObject字段拖拽赋值为ResumeBackground对象即可。 - 如果
firstTimePause是全局唯一的暂停状态标识,建议将其改为静态字段:public static bool firstTimePause;,所有脚本直接通过PauseButton.firstTimePause访问,从根源避免实例引用错误。
- 如果需要读取的是
- 额外优化:删除
Update方法中重复的GetComponent<PauseButton>()调用,Start中拿到的脚本引用可以直接缓存复用,每帧重复获取组件会产生不必要的性能开销。
内容的提问来源于stack exchange,提问作者inter cretasyo
相关产品推荐
相关产品推荐

