Unity C#计时器碰撞后无法停止问题求助(附相关脚本)
问题分析与解决方案
我帮你排查了代码里的问题,核心原因是你在碰撞时错误地给飞船新增了一个HUD组件,而不是引用已经挂载在HUD Canvas上的Timer脚本实例。这就导致你调用的StopGameTimer()根本不是控制当前运行计时器的那个方法,自然停不下来。
具体修复步骤
1. 修正Ship.cs中的组件引用
首先,把Ship.cs里的hud变量类型改成Timer(因为你的计时器逻辑写在Timer.cs里),然后在Start()方法中正确获取HUD Canvas上的Timer组件,而不是自己新增组件。
修改后的Ship.cs关键代码:
// 把变量类型改成Timer,匹配你的计时器脚本 Timer timer; [SerializeField] public GameObject prefabBullet; Bullet script; // 其他变量保持不变... void Start() { // 找到HUD Canvas上的Timer组件(请确保你的Canvas对象名称是"HUD Canvas") timer = GameObject.Find("HUD Canvas").GetComponent<Timer>(); rb2D = GetComponent<Rigidbody2D>(); }
2. 修复碰撞处理逻辑
在OnCollisionEnter2D方法里,删掉新增HUD组件的错误代码,直接调用正确的Timer实例的停止方法:
void OnCollisionEnter2D(Collision2D coll) { if (coll.gameObject.CompareTag("Asteroid")) { // 调用正确的Timer实例的停止方法 timer.StopGameTimer(); Destroy(gameObject); } }
3. (可选)优化Timer.cs的计时逻辑
你原来用elapsedSeconds += Time.deltaTime累加计时的方式,虽然能工作,但用Time.time - startTime的方式会更准确,避免帧累积误差。修改后的Timer.cs:
[SerializeField] public Text scoreText; float startTime; public const string scorePrefix = "Timer: "; bool gameTimerIsRunning = true; void Start() { gameTimerIsRunning = true; startTime = Time.time; scoreText.text = scorePrefix + "0"; } void Update() { if (gameTimerIsRunning) { float elapsedSeconds = Time.time - startTime; int timer = (int)elapsedSeconds; scoreText.text = scorePrefix + timer.ToString(); } } public void StopGameTimer() { gameTimerIsRunning = false; scoreText.text = "Sorry !!"; Debug.Log("StopGameTimer Is called Succesfully."); }
为什么原来的代码无效?
你原来在OnCollisionEnter2D里写的hud = gameObject.AddComponent<HUD>();,会在飞船对象上创建一个全新的HUD组件,这个组件和你挂载在HUD Canvas上的Timer没有任何关联。所以你调用hud.StopGameTimer()时,只是让这个新组件的计时开关关闭,而原来的计时器依然在HUD Canvas上正常运行,自然不会停止。
按照上面的步骤修改后,碰撞时就能正确找到并停止原来的计时器了。
内容的提问来源于stack exchange,提问作者Mehul Trivedi
相关产品推荐
相关产品推荐

