我正在尝试在 Unity 项目中实现冷却时间,虽然这段代码似乎有意义,但它不起作用。发布的代码是一个全面的基本运动脚本。
我尝试用 a 做某事cooldown -=time.deltatime
,但这似乎不起作用。我已经尝试了多种方法,但似乎没有一个有效。
代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MovementScript : MonoBehaviour
{
public float cooldown = 0;
public float actualcooldown = 3f;
public bool isCooldown = false;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.R))
{
GetComponent<Renderer>().material.color = Color.red;
}
if (Input.GetKey(KeyCode.G))
{
GetComponent<Renderer>().material.color = Color.green;
}
if (Input.GetKey(KeyCode.B))
{
GetComponent<Renderer>().material.color = Color.blue;
}
if (Input.GetKey(KeyCode.D))
{
transform.Translate(6f * Time.deltaTime, 0, 0);
}
if (Input.GetKey(KeyCode.A))
{
transform.Translate(-6f * Time.deltaTime, 0, 0);
}
if (Input.GetKeyDown(KeyCode.Space) && cooldown <= 0) {
transform.Translate(0f, 20f * Time.deltaTime, 0f);
isCooldown = true;
while (isCooldown == true)
{
coolDownhappening();
}
}
}
public void coolDownhappening()
{
cooldown = actualcooldown;
cooldown -= Time.deltaTime;
if (cooldown <= 0)
{
cooldown = 0;
}
}
}
You do
while (isCooldown == true)
{
coolDownhappening();
}
But you never change isCoolddown
任何地方!
正如您在评论中已经提到的那样not想要使用while
in the Update
根本没有方法,至少在这个用例中不是!这将在给定的冷却时间内冻结整个主线程 - 或者在您的情况下永远冻结!
您的代码中还有很多其他问题,因此让我们逐步进行:
-
Input.GetKey
是真的每一帧当他们按下指定的键时。然而,它没有任何意义,只会导致不必要的开销,只要按下按钮就重复将材质颜色设置为相同的值。您想做的就是应用一次。
&右箭头;而是使用Input.GetKeyDown
对于这些!
-
GetComponent
是一个相当昂贵的电话。你应该not重复使用GetComponent<Renderer>()
而是存储参考once并稍后重新使用它
// most efficient is always to already reference this via the Inspector
[SerializeField] private Renderer _renderer;
// alternatively get it on runtime
private void Awake()
{
if(!_renderer) _rednerer = GetComponent<Renderer>();
}
然后稍后使用
private void Update()
{
if(Input.GetKeyDown(KeyCode.R))
{
_renderer.material.color = Color.red;
}
...
}
-
你的移动部分实际上没问题。为了使其更具可读性,我实际上宁愿做类似的事情
if (Input.GetKey(KeyCode.D))
{
transform.Translate(Vector3.right * 6f * Time.deltaTime);
}
else if (Input.GetKey(KeyCode.D))
{
transform.Translate(Vector3.left * 6f * Time.deltaTime);
}
还请注意else
这里。当然取决于您的需求,但通常您想要相反的按钮。
-
最后说实话:你实际上想要一个有冷却时间的跳跃方法。
首先,你以相反的方式做了:Input.GetKeyDown
仅被准确地调用once即在按键按下时的帧中。所以你的物体会“跳跃”20 * 1/FPS
对于 60 FPS 来说总是大约0.33
。您可能更想在多个帧上向上移动一定距离。达到一定高度后,激活冷却时间。
正如评论一中提到的can这样做在Update
使用计时器,但这通常会使代码有点混乱。而是使用协程:
private bool _canJump;
private void Update()
{
...
// _canJump is cheaper to check so check it first
if (_canJump && Input.GetKeyDown(KeyCode.Space))
{
StartCoroutine(JumpRoutine());
}
}
private IEnumerator JumpRoutine()
{
// avoid concurrent routines
if(!_canJump) yield break;
// disable jumping
_canJump = false;
// Now it really depends on what you actually want to do
// and how your object should move now
// you might e.g. want something like
var jumpedHeight = 0f;
while(jumpedHeight < 20f)
{
var jumpThisFrame = Vector3.up * 6f * Time.deltaTime;
transform.Translate(jumpThisFrame);
// important now! yield tells Unity to "pause" here,
// render this frame, and continue from here int he next frame
// without the yield statements this would again freeze your game until
// the exit condition is fulfilled!
yield return null;
}
// After reaching the target height this waits for 3 seconds but keeps on rendering meanwhile
yield return new WaitForSeconds(actualcooldown);
// after the cooldown allow next jump
_canJump = true;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)