Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 关于通过协同程序暂停if语句的问题_C#_Unity3d_Scripting_Coroutine - Fatal编程技术网

C# 关于通过协同程序暂停if语句的问题

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

我刚刚开始学习如何在Unity中编程。在过去的两到三周里,我每天都在尝试编写一些代码。我被一个简单的脚本卡住了。该脚本如下所示:

`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的一些评论相反