Unity IENumerator 给出意外的符号错误和错误“不能是迭代器块,因为 'void' 不是迭代器接口类型。”

Unity IENumerator giving Unexpected symbol error and error 'cannot be an iterator block because 'void' is not an iterator interface type.'

我正在尝试在 Unity 中制作平台跳跃游戏,当您死亡时,游戏应该通过文本显示游戏,然后等待 3 秒。但我得到这些错误:

error CS1525: Unexpected symbol `(', expecting `,', `;', or `='
error CS1525: Unexpected symbol `IEnumerator'

我的代码是:

using UnityEngine;
using System;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Collections;

public class PlayerController : MonoBehaviour
{

public float speed = 1700.0f;
public GameObject Player;
public Text TheText;

void Start()
{
    TheText.text = "";
}

void FixedUpdate()
{
    float moveHorizontal = Input.GetAxis("Horizontal");
    float moveVertical = Input.GetAxis("Vertical");

    Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);

    GetComponent<Rigidbody>().AddForce(movement * speed * Time.deltaTime);

    IEnumerator Wait1()
     { 
        if (Player.transform.position.y < -100.59)
        {
            TheText.text = "You Lost. Try Again!!";
            yield return new WaitForSeconds(5);
            SceneManager.LoadScene(SceneManager.GetActiveScene().name);

        }
    }
    IEnumerator Wait2()
    {
        if (Player.transform.position.y > 210)
        {
            TheText.text = "You Lost. Try Again!!";
            yield return new WaitForSeconds(5);
            SceneManager.LoadScene(SceneManager.GetActiveScene().name);
        }
    }

 theres 4 more of those, they're all the same

我希望它在重新启动游戏之前等待,但我遇到了这些错误。 void fixedupdate();语句给出如下错误

cannot be an iterator block because 'void' is not an iterator interface type. 

您可能必须像这样更改代码:基本上关闭 FixedUpdate 方法并将 IEnumerator Wait() 作为单独的方法。

void FixedUpdate()
{
 float moveHorizontal = Input.GetAxis("Horizontal");
 float moveVertical = Input.GetAxis("Vertical");

 Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);

 GetComponent<Rigidbody>().AddForce(movement * speed * Time.deltaTime);
}

IEnumerator Wait1()
{ 
    if (Player.transform.position.y < -100.59)
    {
        TheText.text = "You Lost. Try Again!!";
        yield return new WaitForSeconds(5);
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }
}
IEnumerator Wait2()
{
    if (Player.transform.position.y > 210)
    {
        TheText.text = "You Lost. Try Again!!";
        yield return new WaitForSeconds(5);
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }
}

您正在尝试使用版本 7 中引入的 C# 功能,在此代码中称为 local functions。不幸的是,Unity 仍然使用 C# v6,这意味着您需要将这些函数移到 FixedUpdate 方法之外。例如:

void FixedUpdate()
{
    //snip
}

IEnumerator Wait1()
{
    //snip
}

IEnumerator Wait2()
{
    //snip
}

IEnumerators 应该在 class 范围内声明,而不是函数范围,然后用 StartCoroutine()

触发

例如

public class ExampleClass : MonoBehaviour
{
    // In this example we show how to invoke a coroutine and
    // continue executing the function in parallel.

    private IEnumerator coroutine;

    void Start()
    {
        // - After 0 seconds, prints "Starting 0.0"
        // - After 0 seconds, prints "Before WaitAndPrint Finishes 0.0"
        // - After 2 seconds, prints "WaitAndPrint 2.0"
        print("Starting " + Time.time);

        // Start function WaitAndPrint as a coroutine.

        coroutine = WaitAndPrint(2.0f);
        StartCoroutine(coroutine);

        print("Before WaitAndPrint Finishes " + Time.time);
    }

    // every 2 seconds perform the print()
    private IEnumerator WaitAndPrint(float waitTime)
    {
        while (true)
        {
            yield return new WaitForSeconds(waitTime);
            print("WaitAndPrint " + Time.time);
        }
    }
}

来源:https://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html

请注意,IEnumerator 是在 class 中定义的,而不是在 Update() 函数中定义的。

你在触发协程时也应该小心,因为你可以很容易地同时触发多个协程,这在这里并不理想(例如,你可以有 3 或 4 个协程试图加载同时关卡,这将导致关卡被加载 3 或 4 次,从而给玩家带来巨大的延迟以及潜在的不良副作用)

Asside:IEnumerators 与 Coroutines 不同,Coroutines 是 Unity 的一项功能,允许代码 运行 并行(但不是线程化的)并且它们使用 IEnumerators(一种 C#)功能来工作。

IEnumerators 是一个 C# 特性,除了协程之外还有许多功能,主要用于遍历自定义容器(数组、列表等)

请注意此处的术语,因为它们是两个非常不同(但相关)的事物。

您的代码使用了局部函数,即在另一个函数中声明的函数。要使用该功能,您必须升级到 Unity 2018.3 并确保 Player Settings -> Other Settings 中的 Scripting Runtime VersionApi Compatibility Level 都设置为 .NET 4.x.你的代码应该可以工作了。