While 循环定时器与一个不工作 Unity 3D 的 bool
While loop timer with a bool that doesnt work Unity 3D
使用 C#,我尝试每 3 秒发射一颗子弹,所以这是我的工作流程:
- 按下开火按钮
- 仅当 bool fireAgain 为真时才触发
- set bool fireAgain = false
- 开始计时
- 计时器完成 = bool fireAgain = true
调试时似乎一切正常,但当我测试时,我仍然可以每秒发射 10 发子弹。所以不知何故,它根本不关心 bool FireAgain 是否为假,并且无论如何都会射击,即使根据调试 bool fireAgain 在那一刻是假的。
public void Update()
{
//If LEFT MouseButton is pressed, cast yer spells.
if (fireAgain == true && Input.GetMouseButtonDown(0))
{
StartCoroutine("LoopRotation");
fireAgain = false;
Debug.Log(fireAgain);
Debug.Log("1 should be FALSE");
}
while (fireAgain == false && timer < bulletTime)
{
fireAgain = false;
timer += Time.deltaTime;
Debug.Log(timer);
Debug.Log(bulletTime);
Debug.Log(fireAgain);
Debug.Log("2");
} if (timer >= bulletTime)
{
fireAgain = true;
timer = 0;
//Debug.Log("Timer is finished");
//Debug.Log(timer);
Debug.Log(fireAgain);
Debug.Log("3 should be true");
这里是协程的代码:
IEnumerator LoopRotation()
{
pivot.transform.Rotate(triggerAngle,0,0);
GameObject bullet = ObjectPooler.SharedInstance.GetPooledObject();
if (bullet != null) {
bullet.transform.position = SSpawn.transform.position;
bullet.transform.rotation = SSpawn.transform.rotation;
bullet.SetActive(true);
}
yield return new WaitForSeconds(.1f);
pivot.transform.rotation = Quaternion.Slerp(transform.rotation, originalRotationValue, Time.deltaTime * rotationResetSpeed);
StopCoroutine("LoopRotation");
}
Enumerator LoopRotation 最初只是将武器向前旋转几度然后向后旋转,所以当你施法时它看起来像个怪人,但现在它还有射击功能,因为它会产生子弹。
您在 Update
中有一个 while
循环 => 这个循环将在 一个单帧 中完全 运行 => “立即”将增加 timer
直到它足够大 => “立即”将再次将您的 bool 标志设置为 true
!
您更愿意做的是例如
public void Update()
{
//If LEFT MouseButton is pressed, cast yer spells.
if (fireAgain && Input.GetMouseButtonDown(0))
{
StartCoroutine(LoopRotation());
fireAgain = false;
timer = 0;
Debug.Log(fireAgain);
Debug.Log("1 should be FALSE");
}
else if(timer < bulletTime)
{
// Only increase this ONCE per frame
timer += Time.deltaTime;
Debug.Log(timer);
Debug.Log(bulletTime);
Debug.Log(fireAgain);
Debug.Log("2");
if(timer >= bulletTime)
{
fireAgain = true;
timer = 0;
//Debug.Log("Timer is finished");
//Debug.Log(timer);
Debug.Log(fireAgain);
Debug.Log("3 should be true");
}
}
}
作为替代方案,您可以使用 Invoke
并完全跳过 Update
中的计时器:
public void Update()
{
//If LEFT MouseButton is pressed, cast yer spells.
if (fireAgain && Input.GetMouseButtonDown(0))
{
StartCoroutine(LoopRotation());
fireAgain = false;
Invoke (nameof(AllowFireAgain), bulletTme);
}
}
private void AllowFireAgain()
{
fireAgain = true;
}
请注意,您的协程对我来说意义不大。你只旋转了一次,而且旋转的量很小。
最后的StopCoroutine
不用了
另请注意:为了调试良好,但稍后您应该避免在构建的应用程序中的每一帧都使用 Debug.Log
运行。即使用户看不到它,日志仍会创建到播放器日志文件中并导致大量开销。
使用 C#,我尝试每 3 秒发射一颗子弹,所以这是我的工作流程:
- 按下开火按钮
- 仅当 bool fireAgain 为真时才触发
- set bool fireAgain = false
- 开始计时
- 计时器完成 = bool fireAgain = true
调试时似乎一切正常,但当我测试时,我仍然可以每秒发射 10 发子弹。所以不知何故,它根本不关心 bool FireAgain 是否为假,并且无论如何都会射击,即使根据调试 bool fireAgain 在那一刻是假的。
public void Update()
{
//If LEFT MouseButton is pressed, cast yer spells.
if (fireAgain == true && Input.GetMouseButtonDown(0))
{
StartCoroutine("LoopRotation");
fireAgain = false;
Debug.Log(fireAgain);
Debug.Log("1 should be FALSE");
}
while (fireAgain == false && timer < bulletTime)
{
fireAgain = false;
timer += Time.deltaTime;
Debug.Log(timer);
Debug.Log(bulletTime);
Debug.Log(fireAgain);
Debug.Log("2");
} if (timer >= bulletTime)
{
fireAgain = true;
timer = 0;
//Debug.Log("Timer is finished");
//Debug.Log(timer);
Debug.Log(fireAgain);
Debug.Log("3 should be true");
这里是协程的代码:
IEnumerator LoopRotation()
{
pivot.transform.Rotate(triggerAngle,0,0);
GameObject bullet = ObjectPooler.SharedInstance.GetPooledObject();
if (bullet != null) {
bullet.transform.position = SSpawn.transform.position;
bullet.transform.rotation = SSpawn.transform.rotation;
bullet.SetActive(true);
}
yield return new WaitForSeconds(.1f);
pivot.transform.rotation = Quaternion.Slerp(transform.rotation, originalRotationValue, Time.deltaTime * rotationResetSpeed);
StopCoroutine("LoopRotation");
}
Enumerator LoopRotation 最初只是将武器向前旋转几度然后向后旋转,所以当你施法时它看起来像个怪人,但现在它还有射击功能,因为它会产生子弹。
您在 Update
中有一个 while
循环 => 这个循环将在 一个单帧 中完全 运行 => “立即”将增加 timer
直到它足够大 => “立即”将再次将您的 bool 标志设置为 true
!
您更愿意做的是例如
public void Update()
{
//If LEFT MouseButton is pressed, cast yer spells.
if (fireAgain && Input.GetMouseButtonDown(0))
{
StartCoroutine(LoopRotation());
fireAgain = false;
timer = 0;
Debug.Log(fireAgain);
Debug.Log("1 should be FALSE");
}
else if(timer < bulletTime)
{
// Only increase this ONCE per frame
timer += Time.deltaTime;
Debug.Log(timer);
Debug.Log(bulletTime);
Debug.Log(fireAgain);
Debug.Log("2");
if(timer >= bulletTime)
{
fireAgain = true;
timer = 0;
//Debug.Log("Timer is finished");
//Debug.Log(timer);
Debug.Log(fireAgain);
Debug.Log("3 should be true");
}
}
}
作为替代方案,您可以使用 Invoke
并完全跳过 Update
中的计时器:
public void Update()
{
//If LEFT MouseButton is pressed, cast yer spells.
if (fireAgain && Input.GetMouseButtonDown(0))
{
StartCoroutine(LoopRotation());
fireAgain = false;
Invoke (nameof(AllowFireAgain), bulletTme);
}
}
private void AllowFireAgain()
{
fireAgain = true;
}
请注意,您的协程对我来说意义不大。你只旋转了一次,而且旋转的量很小。
最后的StopCoroutine
不用了
另请注意:为了调试良好,但稍后您应该避免在构建的应用程序中的每一帧都使用 Debug.Log
运行。即使用户看不到它,日志仍会创建到播放器日志文件中并导致大量开销。