布尔状态未能阻止功能重复
State of bool failing to prevent function from repeating
由于某种原因无法追踪到它,它应该很简单,但我遗漏了一些东西。在 PreCountdownTimer()
中,我从 GameManager.cs
中获得两个 bool 属性,将它们分配给 _userActive
和 _preCountdownActive
,然后在 Update()
[ 中查找更改=43=]。当 _userActive = false && _preCountdownActive = false
它开始 StartPreCountTimer()
并设置 _preCountdownActive
为真。
一旦发生这种情况,Update()
将无法再根据条件调用 StartPreCountTimer()
声明...但它仍然如此。这导致我的计时器在每一帧都被一遍又一遍地调用,从而阻止它倒计时。我在这里做错了什么阻止 _preCountdownActive
布尔停止 Update
触发 StartPreCountTimer()
?
PreCountdownTimer.cs
using System.Collections;
using UnityEngine;
public class PreCountdownTimer : MonoBehaviour {
public bool ShowRestartDialog { get; set; }
private IEnumerator counter;
private bool _startPrecount;
private float _preCountdownInterval;
private bool _preCountdownActive = false;
private bool _userActive = false;
private float _timerLength;
void Start()
{
_timerLength = GameManager.Instance.PreCountdownLength;
}
void Update()
{
_userActive = GameManager.Instance.UserActive;
if (!_userActive && !_preCountdownActive)
StartPreCountTimer(_timerLength);
else if (_userActive && _preCountdownActive)
StopPreCountTimer();
Debug.Log("The state of preCountdownActive is: " + _preCountdownActive);
}
void StartPreCountTimer(float length)
{
_preCountdownActive = true;
counter = RunTimer(length);
StartCoroutine(counter);
}
void StopPreCountTimer()
{
_preCountdownActive = false;
StopCoroutine(counter);
}
IEnumerator RunTimer(float seconds)
{
float s = seconds;
while (s > 0)
{
yield return new WaitForSeconds(_preCountdownInterval);
s -= _preCountdownInterval;
Debug.Log("PreCount: " + s);
}
if (s == 0)
{
_preCountdownActive = false;
ShowRestartDialog = true;
}
}
}
GameManager.cs
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public static GameManager Instance = null; // create singleton
public Object introScene;
public bool UserActive { get; set; }
public bool OnIntroScreen { get; set; }
public GameObject preCountdownTimerPrefab;
private GameObject _preCountdownTimerInstance;
public float PreCountdownLength { get; protected set; }
public float PreCountdownInterval { get; protected set; }
private float _checkMousePositionTimingInterval = 1.0f;
private Vector3 _currentMousePosition;
private Vector3 _prevMousePosition;
private Scene _currentScene;
void Awake()
{
if (Instance == null)
Instance = this;
else if (Instance != null)
Destroy(gameObject);
DontDestroyOnLoad(gameObject);
}
void OnEnable()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
_currentScene = scene;
}
void Start()
{
PreCountdownLength = 5.0f;
PreCountdownInterval = 1.0f;
OnIntroScreen = true;
UserActive = false;
_prevMousePosition = Input.mousePosition;
InvokeRepeating("LastMousePosition", 0, _checkMousePositionTimingInterval);
}
void Update()
{
_currentMousePosition = Input.mousePosition;
if (_currentScene.name != introScene.name)
{
OnIntroScreen = false;
if (_currentMousePosition != _prevMousePosition)
UserActive = true;
else
UserActive = false;
}
else if (_currentScene.name == introScene.name)
OnIntroScreen = true;
if (!UserActive && !OnIntroScreen)
if (_preCountdownTimerInstance == null)
_preCountdownTimerInstance = Instantiate(preCountdownTimerPrefab);
else if (UserActive)
if (_preCountdownTimerInstance != null)
Destroy(_preCountdownTimerInstance);
}
void LastMousePosition()
{
_prevMousePosition = Input.mousePosition;
}
}
我通过直接访问属性解决了这个问题,而不是将 属性 值保存到局部变量并访问局部变量。希望这是一个正确的方法?
using System.Collections;
using UnityEngine;
public class PreCountdownTimer : MonoBehaviour {
private IEnumerator counter;
void Update()
{
if (!GameManager.Instance.UserActive && !GameManager.Instance.PreCountdownActive)
StartPreCountTimer(GameManager.Instance.PreCountdownLength);
else if (GameManager.Instance.UserActive && GameManager.Instance.PreCountdownActive)
StopPreCountTimer();
}
void StartPreCountTimer(float length)
{
GameManager.Instance.PreCountdownActive = true;
counter = RunTimer(length);
StartCoroutine(counter);
}
void StopPreCountTimer()
{
GameManager.Instance.PreCountdownActive = false;
StopCoroutine(counter);
}
IEnumerator RunTimer(float seconds)
{
float s = seconds;
while (s > 0)
{
yield return new WaitForSeconds(GameManager.Instance.PreCountdownInterval);
s -= GameManager.Instance.PreCountdownInterval;
Debug.Log("PreCount: " + s);
}
if (s == 0)
{
GameManager.Instance.PreCountdownActive = false;
}
}
}
由于某种原因无法追踪到它,它应该很简单,但我遗漏了一些东西。在 PreCountdownTimer()
中,我从 GameManager.cs
中获得两个 bool 属性,将它们分配给 _userActive
和 _preCountdownActive
,然后在 Update()
[ 中查找更改=43=]。当 _userActive = false && _preCountdownActive = false
它开始 StartPreCountTimer()
并设置 _preCountdownActive
为真。
一旦发生这种情况,Update()
将无法再根据条件调用 StartPreCountTimer()
声明...但它仍然如此。这导致我的计时器在每一帧都被一遍又一遍地调用,从而阻止它倒计时。我在这里做错了什么阻止 _preCountdownActive
布尔停止 Update
触发 StartPreCountTimer()
?
PreCountdownTimer.cs
using System.Collections;
using UnityEngine;
public class PreCountdownTimer : MonoBehaviour {
public bool ShowRestartDialog { get; set; }
private IEnumerator counter;
private bool _startPrecount;
private float _preCountdownInterval;
private bool _preCountdownActive = false;
private bool _userActive = false;
private float _timerLength;
void Start()
{
_timerLength = GameManager.Instance.PreCountdownLength;
}
void Update()
{
_userActive = GameManager.Instance.UserActive;
if (!_userActive && !_preCountdownActive)
StartPreCountTimer(_timerLength);
else if (_userActive && _preCountdownActive)
StopPreCountTimer();
Debug.Log("The state of preCountdownActive is: " + _preCountdownActive);
}
void StartPreCountTimer(float length)
{
_preCountdownActive = true;
counter = RunTimer(length);
StartCoroutine(counter);
}
void StopPreCountTimer()
{
_preCountdownActive = false;
StopCoroutine(counter);
}
IEnumerator RunTimer(float seconds)
{
float s = seconds;
while (s > 0)
{
yield return new WaitForSeconds(_preCountdownInterval);
s -= _preCountdownInterval;
Debug.Log("PreCount: " + s);
}
if (s == 0)
{
_preCountdownActive = false;
ShowRestartDialog = true;
}
}
}
GameManager.cs
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public static GameManager Instance = null; // create singleton
public Object introScene;
public bool UserActive { get; set; }
public bool OnIntroScreen { get; set; }
public GameObject preCountdownTimerPrefab;
private GameObject _preCountdownTimerInstance;
public float PreCountdownLength { get; protected set; }
public float PreCountdownInterval { get; protected set; }
private float _checkMousePositionTimingInterval = 1.0f;
private Vector3 _currentMousePosition;
private Vector3 _prevMousePosition;
private Scene _currentScene;
void Awake()
{
if (Instance == null)
Instance = this;
else if (Instance != null)
Destroy(gameObject);
DontDestroyOnLoad(gameObject);
}
void OnEnable()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
_currentScene = scene;
}
void Start()
{
PreCountdownLength = 5.0f;
PreCountdownInterval = 1.0f;
OnIntroScreen = true;
UserActive = false;
_prevMousePosition = Input.mousePosition;
InvokeRepeating("LastMousePosition", 0, _checkMousePositionTimingInterval);
}
void Update()
{
_currentMousePosition = Input.mousePosition;
if (_currentScene.name != introScene.name)
{
OnIntroScreen = false;
if (_currentMousePosition != _prevMousePosition)
UserActive = true;
else
UserActive = false;
}
else if (_currentScene.name == introScene.name)
OnIntroScreen = true;
if (!UserActive && !OnIntroScreen)
if (_preCountdownTimerInstance == null)
_preCountdownTimerInstance = Instantiate(preCountdownTimerPrefab);
else if (UserActive)
if (_preCountdownTimerInstance != null)
Destroy(_preCountdownTimerInstance);
}
void LastMousePosition()
{
_prevMousePosition = Input.mousePosition;
}
}
我通过直接访问属性解决了这个问题,而不是将 属性 值保存到局部变量并访问局部变量。希望这是一个正确的方法?
using System.Collections;
using UnityEngine;
public class PreCountdownTimer : MonoBehaviour {
private IEnumerator counter;
void Update()
{
if (!GameManager.Instance.UserActive && !GameManager.Instance.PreCountdownActive)
StartPreCountTimer(GameManager.Instance.PreCountdownLength);
else if (GameManager.Instance.UserActive && GameManager.Instance.PreCountdownActive)
StopPreCountTimer();
}
void StartPreCountTimer(float length)
{
GameManager.Instance.PreCountdownActive = true;
counter = RunTimer(length);
StartCoroutine(counter);
}
void StopPreCountTimer()
{
GameManager.Instance.PreCountdownActive = false;
StopCoroutine(counter);
}
IEnumerator RunTimer(float seconds)
{
float s = seconds;
while (s > 0)
{
yield return new WaitForSeconds(GameManager.Instance.PreCountdownInterval);
s -= GameManager.Instance.PreCountdownInterval;
Debug.Log("PreCount: " + s);
}
if (s == 0)
{
GameManager.Instance.PreCountdownActive = false;
}
}
}