【问题标题】:Unity IENumerator giving Unexpected symbol error and error 'cannot be an iterator block because 'void' is not an iterator interface type.'Unity IENumerator 给出意外符号错误和错误“不能是迭代器块,因为 'void' 不是迭代器接口类型。”
【发布时间】:2019-06-04 19:51:52
【问题描述】:

我正在尝试在 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. 

【问题讨论】:

  • 或许指出错误与哪些代码行有关?

标签: c# unity3d ienumerator


【解决方案1】:

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

void FixedUpdate()
{
    //snip
}

IEnumerator Wait1()
{
    //snip
}

IEnumerator Wait2()
{
    //snip
}

【讨论】:

  • Unity 在 Unity 2018.3 中升级到 Roselyn,因此如果您的 Unity 是最新的,您现在可以使用本地函数。
  • @Piflik 啊,很高兴知道谢谢。我从未真正使用过 Unity,所以这类信息很有帮助。也为您的回答 +1。
【解决方案2】:

您可能必须像这样更改您的代码:基本上关闭 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);
    }
}

【讨论】:

    【解决方案3】:

    IEnumerators 应该在类范围内声明,而不是在函数范围内,然后用 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 是在类中定义的,而不是在 Update() 函数中。

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

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

    IEnumerators 是一个 C# 特性,它具有除 Coroutines 之外的许多功能,主要用于迭代自定义容器(数组、列表等)

    请注意这里的术语,因为它们是两个非常不同(尽管相关)的东西。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2019-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-10
        相关资源
        最近更新 更多