C# 如何降低Unity2D中的实例化频率
我试着像这样降低放炮频率:C# 如何降低Unity2D中的实例化频率,c#,unity3d,C#,Unity3d,我试着像这样降低放炮频率: public class createShot : MonoBehaviour { public GameObject shot; void Update() { StartCoroutine("Shot"); } IEnumerator Shot() { if (Input.GetKey("space")) { Instantiate(sho
public class createShot : MonoBehaviour {
public GameObject shot;
void Update()
{
StartCoroutine("Shot");
}
IEnumerator Shot()
{
if (Input.GetKey("space"))
{
Instantiate(shot, transform.position, transform.rotation);
yield return new WaitForSeconds(1f);
}
}
}
float elapsedTime;
[SerializeField]
float targetTime = 1f;
void Update()
{
elapsedTime += Time.deltaTime;
if(elapsedTime >= targetTime && Input.GetKey(KeyCode.Space))
{
elapsedTime = 0;
Instantiate(shot, transform.position, transform.rotation);
}
}
但它在不到一秒钟的时间里不断地发送大量的垃圾邮件。。。有人能帮忙吗?这是Unity5中的一个2D项目也许你想要更像这样的东西:
public class createShot : MonoBehaviour {
public GameObject shot;
void Update()
{
StartCoroutine("Shot");
}
IEnumerator Shot()
{
if (Input.GetKey("space"))
{
Instantiate(shot, transform.position, transform.rotation);
yield return new WaitForSeconds(1f);
}
}
}
float elapsedTime;
[SerializeField]
float targetTime = 1f;
void Update()
{
elapsedTime += Time.deltaTime;
if(elapsedTime >= targetTime && Input.GetKey(KeyCode.Space))
{
elapsedTime = 0;
Instantiate(shot, transform.position, transform.rotation);
}
}
这将增加计时器elapsedTime
,并检查它是否超过targetTime
我还鼓励您尽可能停止使用字符串。在调用方法或请求诸如GetKey中的键之类的内容时不要使用它们。它们会产生垃圾并减慢您的软件速度。也许您想要更像这样的东西:
public class createShot : MonoBehaviour {
public GameObject shot;
void Update()
{
StartCoroutine("Shot");
}
IEnumerator Shot()
{
if (Input.GetKey("space"))
{
Instantiate(shot, transform.position, transform.rotation);
yield return new WaitForSeconds(1f);
}
}
}
float elapsedTime;
[SerializeField]
float targetTime = 1f;
void Update()
{
elapsedTime += Time.deltaTime;
if(elapsedTime >= targetTime && Input.GetKey(KeyCode.Space))
{
elapsedTime = 0;
Instantiate(shot, transform.position, transform.rotation);
}
}
这将增加计时器elapsedTime
,并检查它是否超过targetTime
我还鼓励您尽可能停止使用字符串。在调用方法或请求诸如GetKey中的键之类的内容时不要使用它们。它们会产生垃圾并降低软件的运行速度。或者。。。
使用与已经编写的代码完全相同的代码,我们可以进行一些轻微的调整,使事情正常工作
public class createShot : MonoBehaviour {
public GameObject shot;
void Start() //create the coroutine once
{
StartCoroutine("Shot");
}
IEnumerator Shot()
{
while(true) { //do this forever!
//This is what makes it loop and what allows the WaitForSeconds() do its job
if (Input.GetKey("space"))
{
Instantiate(shot, transform.position, transform.rotation);
yield return new WaitForSeconds(1f);
}
else {
yield return null; //wait 1 frame instead
}
}
}
}
另一方面,您应该始终使用大写字母开头来命名类,例如,CreateShot
而不是CreateShot
或者。。。
使用与已经编写的代码完全相同的代码,我们可以进行一些轻微的调整,使事情正常工作
public class createShot : MonoBehaviour {
public GameObject shot;
void Start() //create the coroutine once
{
StartCoroutine("Shot");
}
IEnumerator Shot()
{
while(true) { //do this forever!
//This is what makes it loop and what allows the WaitForSeconds() do its job
if (Input.GetKey("space"))
{
Instantiate(shot, transform.position, transform.rotation);
yield return new WaitForSeconds(1f);
}
else {
yield return null; //wait 1 frame instead
}
}
}
}
另一方面,你应该总是用大写字母开头命名你的类,例如,
CreateShot
而不是CreateShot
你正在开始一个新的Coroutine
每一帧-这绝对不是你应该做的。很可能你想让你的协同程序设置一个布尔值(isOnCooldown
或类似的东西),然后在你拍摄完之后才开始协同程序是的,我想要一些类似于冷却的东西,但我昨天在Unity上开始了,哈哈。如何正确设置此冷却时间?我这样做的时候,我认为WaitForSeconds会“停止”每个帧的更新,正如我已经说过的,它有一个布尔值,当设置为true
时,它会阻止shot
的实例化,并且在冷却结束后让你的协同程序设置为false
,你不应该命名你的类createShot
。这听起来更像是一个方法名。你应该把你的班级命名为名词ShotCreator
会更好。你正在开始一个新的Coroutine
每一帧-这绝对不是你应该做的。很可能你想让你的协同程序设置一个布尔值(isOnCooldown
或类似的东西),然后在你拍摄完之后才开始协同程序是的,我想要一些类似于冷却的东西,但我昨天在Unity上开始了,哈哈。如何正确设置此冷却时间?我这样做的时候,我认为WaitForSeconds会“停止”每个帧的更新,正如我已经说过的,它有一个布尔值,当设置为true
时,它会阻止shot
的实例化,并且在冷却结束后让你的协同程序设置为false
,你不应该命名你的类createShot
。这听起来更像是一个方法名。你应该把你的班级命名为名词<代码>ShotCreator会更好。正是我需要的!我只是减少了一点targetTime e的工作非常完美。谢谢您还可以在targetTime
上面添加一个[SerializeField]-属性,然后您可以在inspector中设置它。这正是我需要的!我只是减少了一点targetTime e的工作非常完美。谢谢您还可以在targetTime
上面添加一个[SerializeField]-属性,然后您可以在inspector中设置它。因此,基本上,WaitForSeconds只在循环内工作?@IgorHenriques否,它是什么导致函数暂停执行一段时间(暂停由yield
负责,您在yield时返回的内容决定了持续时间:null为下一帧,其他对象每一帧“计算”一次,直到它们“返回true”,请参阅)。由于您的原始代码在yield
之后没有行,因此没有什么可执行的。在我的代码中,有while
循环。如果您有IEnumerator Shot(){yield return new WaitForSeconds(1f);Debug.Log(“Shot!”;}
相反,您会发现Log语句将在Shot()之后一秒钟出现
被调用,即使没有循环。你可以想象像线程一样的协同程序,其中start例程()
创建一个子任务,所有生成的行为都像Thread.sleep()
,但一切仍然是同步的,并在主线程上运行。这仍然是常见的危险“修改时要小心”,但如果两个不同的代码段在同一个CPU周期内访问同一对象,则不会产生真正的竞争条件。因此,基本上,WaitForSeconds仅在循环内工作?@IgorHenriques否,它会导致函数暂停执行一段时间吗(暂停由yield
负责,您在yield时返回的内容决定了持续时间:null为下一帧,其他对象每一帧“计算”一次,直到它们“返回true”,请参阅)。由于您的原始代码在yield
之后没有行,因此没有什么可执行的。在我的代码中,有while
循环。如果您有IEnumerator Shot(){yield return new WaitForSeconds(1f);Debug.Log(“Shot!”;}
相反,您会发现Log语句将在Shot()之后一秒钟出现
被调用,即使没有循环。你可以想象像线程一样的协同例程,startcroutine()
创建一个子任务,所有产生的行为都像Thread.sleep()
,但一切仍然是同步的,并在主线程上运行。仍然存在通常的危险“修改时要小心,“但是,当两个不同的代码段在相同的CPU周期内访问同一对象时,不能造成真正的竞争条件。