Unity中Time.timeScale失效:GameControlScript计时结束后游戏仍运行
问题分析与解决方案
你的问题根源在于两个脚本同时修改Time.timeScale导致状态冲突:当GameControlScript触发游戏结束并设置Time.timeScale = 0后,PauseMenuScript的Update方法会因为paused仍为false,立刻将Time.timeScale重新设为1,让游戏逻辑继续在后台运行。
修复步骤
1. 让暂停脚本感知游戏结束状态
在PauseMenuScript中添加对游戏结束状态的判断,避免在游戏结束时覆盖时间缩放设置:
首先,在PauseMenuScript中引用GameControlScript(记得在Inspector面板中拖入对应的脚本实例):
using UnityEngine; public class PauseMenuScript : MonoBehaviour { public GUISkin myskin; public string levelToLoad; public bool paused = false; public AudioSource MenuClickSound; // 引用游戏控制脚本 public GameControlScript gameControl; private void Start() { Time.timeScale = 1; } private void Update() { // 游戏结束时,强制保持时间停止,不处理暂停逻辑 if (gameControl.isGameOver) { Time.timeScale = 0; return; } if (Input.GetKeyDown(KeyCode.Escape)) { paused = !paused; } Time.timeScale = paused ? 0 : 1; } private void OnGUI() { GUI.skin = myskin; if (paused) { GUI.Box(new Rect(Screen.width/4, Screen.height/4, Screen.width/2, Screen.height/2), "PAUSED"); if (GUI.Button(new Rect(Screen.width/4+10, Screen.height/4+Screen.height/10+10, Screen.width/2-20, Screen.height/10), "RESUME")){ MenuClickSound.Play(); paused = false; } if (GUI.Button(new Rect(Screen.width/4+10, Screen.height/4+2*Screen.height/10+10, Screen.width/2-20, Screen.height/10), "RESTART")){ MenuClickSound.Play(); Application.LoadLevel(Application.loadedLevel); } if (GUI.Button(new Rect(Screen.width/4+10, Screen.height/4+3*Screen.height/10+10, Screen.width/2-20, Screen.height/10), "MAIN MENU")){ MenuClickSound.Play(); Application.LoadLevel(levelToLoad); } } } }
2. 优化游戏控制脚本逻辑(可选)
修正注释错误,并确保游戏结束音效不受时间缩放影响(避免音效变慢):
using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; public class GameControlScript : MonoBehaviour { public float timeRemaining = 10f; public float timeExtension = 3f; public float timeDeduction = 2f; private float totalTimeElapsed = 0f; private float score = 0f; public bool isGameOver = false; public AudioSource GameOverSound; public Text ScoreBoard; public Text FinalScore; public Text GameTimeLeft; public GameObject GameOverPanel; void Start(){ Time.timeScale = 1; // 确保游戏结束音效不受时间缩放影响 if (GameOverSound != null) { GameOverSound.ignoreListenerPause = true; } } void Update () { if(isGameOver) { // 游戏结束时直接返回,不执行后续逻辑 return; } totalTimeElapsed += Time.deltaTime; score = totalTimeElapsed * 100; timeRemaining -= Time.deltaTime; GameTimeLeft.text = "TIME LEFT: " + ((int)timeRemaining).ToString(); ScoreBoard.text = "SCORE: " + ((int)score).ToString(); if (timeRemaining <= 0) { Time.timeScale = 0; GameOverPanel.SetActive(true); FinalScore.text = "YOUR SCORE: " + ((int)score).ToString(); isGameOver = true; GameOverSound.Play(); } } }
额外建议
- 尽量让单个脚本负责全局时间缩放的管理,避免多个脚本同时修改
Time.timeScale,减少类似冲突问题。 - 如果项目中有依赖时间的协程,游戏结束时记得用
StopAllCoroutines()或标记位停止所有未完成的协程。
内容的提问来源于stack exchange,提问作者Noor ul ain Arain
相关产品推荐
相关产品推荐

