C# 关于通过协同程序暂停if语句的问题
我刚刚开始学习如何在Unity中编程。在过去的两到三周里,我每天都在尝试编写一些代码。我被一个简单的脚本卡住了。该脚本如下所示:C# 关于通过协同程序暂停if语句的问题,c#,unity3d,scripting,coroutine,C#,Unity3d,Scripting,Coroutine,我刚刚开始学习如何在Unity中编程。在过去的两到三周里,我每天都在尝试编写一些代码。我被一个简单的脚本卡住了。该脚本如下所示: `using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerControllerX : MonoBehaviour { public GameObject dogPrefab; public float timeW
`using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControllerX : MonoBehaviour
{
public GameObject dogPrefab;
public float timeWaited = 0.5f;
public void Start()
{
}
// Update is called once per frame
void Update()
{
// On spacebar press, send dog
if (Input.GetKeyDown(KeyCode.Space))
{
StartCoroutine(MyCoroutine());
}
}
private IEnumerator MyCoroutine()
{
Instantiate(dogPrefab, transform.position, dogPrefab.transform.rotation);
yield return new WaitForSeconds(1f);
Debug.Log("Waited 0.5 seconds!");
}
} `
我希望在按下空格键之间有0.5秒的休息时间(这会产生一只狗)。我假设这不起作用,因为当按下空格键时,协同程序只是从一开始就播放。然而,我想不出一个办法来解决这个问题。任何建议都将不胜感激 我不相信时间。首先,时间就是这样工作的。草案内容如下: 此帧开始时的时间(只读)。这是比赛开始后的秒数 Time.Time是应用程序已运行的时间量(以秒为单位)。它是只读的 协同程序中的if语句正在检查
Time.Time
,因此它将始终高于0.5,并且狗将始终繁殖
虽然这是一种技术含量较低的方法,但为了解决这个问题,我会在协程的开始和结束处设置一个变量,这样您就可以根据这个变量检查另一个if语句。这还意味着您可以将此检查放在输入.GetKeyDown()
检查旁边,而不必同时运行多个协程
这意味着您的脚本主体将如下所示:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControllerX : MonoBehaviour
{
public GameObject dogPrefab;
public float timeWaited = 0.5f;
public void Start()
{
}
// Update is called once per frame
void Update()
{
// On spacebar press, send dog
if (Input.GetKeyDown(KeyCode.Space) && Time.time >= timeWaited)
{
SpawnDog();
timeWaited = Time.time + timeWaited;
}
}
private void SpawnDog()
{
Instantiate(dogPrefab, transform.position, dogPrefab.transform.rotation);
Debug.Log("Waited 0.5 seconds!");
}
} `
公共游戏对象狗预制;
布尔等待=假;
无效更新()
{
if(Input.GetKeyDown(KeyCode.Space)和&!Waiting)
{
start例程(MyCoroutine());
}否则
{
Debug.Log(“等待”);
}
}
IEnumerator MyCoroutine()
{
等待=真;
实例化(DogPrefact、transform.position、DogPrefact.transform.rotation);
收益率返回新的WaitForSeconds(0.5f);
Log(“等待0.5秒!”);
等待=错误;
}
(CoolBots已经在评论中提到了这一点,但我无法发表评论,所以我只想把它放在评论中。我还有一个坏习惯,就是使用很多协同程序,所以他们说这可能没有必要,但我个人会这样做。)你不需要协同程序来做这件事。您只需使用
timeWaited
变量,每次按下按钮,您就可以生成狗,并将变量与游戏开始以来经过的时间和等待时间相加
大概是这样的:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControllerX : MonoBehaviour
{
public GameObject dogPrefab;
public float timeWaited = 0.5f;
public void Start()
{
}
// Update is called once per frame
void Update()
{
// On spacebar press, send dog
if (Input.GetKeyDown(KeyCode.Space) && Time.time >= timeWaited)
{
SpawnDog();
timeWaited = Time.time + timeWaited;
}
}
private void SpawnDog()
{
Instantiate(dogPrefab, transform.position, dogPrefab.transform.rotation);
Debug.Log("Waited 0.5 seconds!");
}
} `
每次按下空格键时,您的代码都会启动一个新的协同程序。即使从技术上讲,您在每个协同路由实例中等待了0.5秒,但这并不阻止启动新的协同路由。因此,您几乎是正确的-协同程序从顶部重新启动-它的一个新实例-不是同一个实例。另外,如果(Time.Time>=timewait)语句在前几帧之后总是
true
,则返回游戏开始后的总秒数。()
相反,让我们使用一种标准的方法来解决这个问题——累加器值,每帧递增Time.deltaTime
。()
步骤0:定义等待时间
你的代码中已经有了这个-它被称为timeWaited
。为了清楚起见,我将在这里重命名它。此值应该是脚本的全局值(以统一术语表示)-这是MonoBehavior派生类中的类字段:
两个棋子之间的浮动最小时间=0.5f;
步骤1:累加器变量
您的代码中没有这个变量,所以我在这里介绍它。此值应该是脚本的全局值(以统一术语表示)-这是MonoBehavior派生类中的类字段:
float elapsedTimeSinceSpacebarLastPressed=0;//请随意缩短名称,哈哈!
步骤2:在每帧上累积Time.deltaTime
现在,Unity游戏引擎(实际上是所有游戏引擎)跟踪每帧之间经过的时间。这在游戏开发中是一个非常重要的概念,因为它允许对象的平滑移动,而不管运行一帧的时间是长是短——因为我们知道从上一帧开始经过的时间,我们可以使用它来计算对象的位置,一个单位应该前进多少,等等。在我们的例子中,我们只是使用这个值来获得所需的时间点-在您的情况下为0.5秒,由minimumtimebetwendogspawns
变量表示
那么,我们如何以及在哪里累积经过的时间呢?简单-只需将其添加到更新中即可:
void Update()
{
elapsedTimeSinceSpacebarLastPressed+=Time.deltaTime;
}
第三步:检查是否是时候生一只新狗了!
那么,当上次按下空格键时,我们如何处理此延时?到目前为止,它一直在增长。。。我们需要检查它是否达到了感兴趣的值-在我们的例子中,minimumTimeBetweenDogSpawns
,但只有在按下空格键的情况下。让我们在Update
中添加一个if
语句来实现这一点。我将从第2步展开Update
:
void Update()
{
elapsedTimeSinceSpacebarLastPressed+=Time.deltaTime;
if(Input.GetKeyDown(KeyCode.Space)
&&ElapsedTimesincespacebarlast pressed>=两次典当之间的最小时间)
{
//做点什么!生一只狗!一起跑!玩个球!
elapsedTimeSinceSpacebarLastPressed=0;//…但不要忘记重置累加器!
}
}
你听懂最后一句话了吗?非常重要-重置蓄能器这将重新启动该过程,允许我们繁殖更多的狗,但不能在达到minimumtimebetwendogspawns
指定的值之前
笔记
- 从技术上讲,协同程序是不必要的,但可能很有用-假设你想做一些耗时的任务-比如说,狗的产卵动画大约需要半秒钟,这将是产卵之间延迟的一个很好的原因
- 与关于t的一些评论相反