C#实现回合间等待且不阻塞脚本其余功能的技术问询
Hey there! I see you're running into a classic Unity thread-blocking issue—your current Stopwatch loop is hogging the main thread, which is why your restart button needs a double-click to register (the first click gets swallowed while the loop chugs away). Let's fix this with non-blocking approaches that keep your UI responsive while still adding that smooth turn transition delay.
Option 1: Use Unity Coroutines (Recommended)
Coroutines are Unity's built-in tool for handling delayed actions without blocking the main thread. They pause execution at yield statements, letting the engine keep processing UI input, game updates, and other tasks in the meantime.
First, replace your blocking timer code with a coroutine:
// Call this method when you need to start the turn transition wait StartCoroutine(HandleTurnTransitionWait()); // The coroutine that manages the delay private IEnumerator HandleTurnTransitionWait() { int timeBetweenTurns = 400; // Wait for the specified milliseconds without blocking the thread yield return new WaitForSeconds(timeBetweenTurns / 1000f); // Convert ms to seconds // Once the wait is done, switch to the next player SwitchToNextPlayer(); }
To handle restarts properly (so the AI doesn't finish its turn after the restart button is clicked), track the running coroutine and stop it when restart is triggered:
private Coroutine _activeTurnWaitCoroutine; // Update your coroutine start code to store a reference _activeTurnWaitCoroutine = StartCoroutine(HandleTurnTransitionWait()); // Your restart button click handler public void OnRestartButtonClicked() { // Stop the active wait coroutine if it's running if (_activeTurnWaitCoroutine != null) { StopCoroutine(_activeTurnWaitCoroutine); _activeTurnWaitCoroutine = null; } // Run your restart logic immediately RestartGame(); }
Option 2: Frame-Based Timing with Update()
If you prefer not to use coroutines, you can track the wait duration in the Update() method, which runs every frame without blocking the main thread.
private float _waitStartTime; private bool _isWaitingForTurnTransition = false; private const float TurnWaitDuration = 0.4f; // 400ms converted to seconds // Call this to start the turn transition wait private void StartTurnTransitionWait() { _waitStartTime = Time.time; _isWaitingForTurnTransition = true; } void Update() { if (_isWaitingForTurnTransition) { // Check if the wait duration has passed if (Time.time - _waitStartTime >= TurnWaitDuration) { _isWaitingForTurnTransition = false; // Switch to the next player SwitchToNextPlayer(); } } } // Restart button handler public void OnRestartButtonClicked() { // Cancel the wait immediately _isWaitingForTurnTransition = false; RestartGame(); }
Why This Works
Both approaches let the main thread keep processing UI events (like button clicks) while waiting for the turn transition delay. No more blocked input, so your restart button will work on the first click, and the AI won't continue its turn after restart is triggered.
内容的提问来源于stack exchange,提问作者Sander Koldenhof

