【问题标题】:Unity: ArgumentException: Value does not fall within the expected rangeUnity:ArgumentException:值不在预期范围内
【发布时间】:2017-09-29 10:23:09
【问题描述】:

我在 Unity 中使用 Coroutine 时遇到了一个奇怪的问题。修改前,我的代码如下:

IEnumerator Destory()
{
    yield return new WaitForSeconds(destoryDelay);
    yield return StartCoroutine(Timer.Start(0.5f, false, gameManager.EnableBtnSummon));
    GameObject.Destroy(this.gameObject);
}

Time.Start()是我自己写的一个实用程序,用于延迟调用。

public static IEnumerator Start(float duration, bool repeat, Action callback)
{
    do
    {
        yield return new WaitForSeconds(duration);                
        if (callback != null)
            callback();
    } while (repeat);
}

因为Time.Start()包含WaitForSeconds(),所以我决定将上面的代码修改如下:

IEnumerator Destory()
{
    //yield return new WaitForSeconds(destoryDelay);
    yield return StartCoroutine(Timer.Start(destoryDelay+0.5f, false, gameManager.EnableBtnSummon));
    GameObject.Destroy(this.gameObject);
}

很遗憾,控制台报错:

ArgumentException: 值不在预期范围内。

gameManager.EnableBtnSummon只是一个Action处理游戏逻辑。调试后,我确保在此函数运行之前发生错误。但我会展示它以获得更多线索。

public void EnableBtnSummon()
{
    //will not reach this!
    print("Enable Button Summon");
    //if detecting monster, change relative sprite of monster medal
    if (currentMonsterIndex != -1)
    {
        Image captureMonsterSprite = monsterMedalList.transform.GetChild(currentMonsterIndex).GetComponent<Image>();
        captureMonsterSprite.sprite = mosnterExplicitMedalList[currentMonsterIndex];

        Image gameOverMonsterSprite = gameOverMonsterList.transform.GetChild(currentMonsterIndex).GetComponent<Image>();
        gameOverMonsterSprite.sprite = mosnterExplicitMedalList[currentMonsterIndex];

        currentMonsterIndex = -1;
        captureMonsterCount++;
    }

    if (captureMonsterCount == monsterIndexDictionary.Count) return;

    var summonAnimator = btnSummon.GetComponent<Animator>();
    summonAnimator.SetBool("isSearch", false);

    btnSummon.enabled = true;
    btnExit.enabled = true;

    fogParticleSystem.Play();
}

我看不懂,谁能告诉我会发生什么?谢谢...

【问题讨论】:

  • 尝试格式化您问题中的代码。另外,你从哪里得到这个错误? gameManager 是如何声明的?
  • 如果你能隔离你的论点来看看是哪一个导致了问题,那就太好了。您应该将每个变量声明为局部变量,然后在发送它们之前调用Debug.Log 来验证它们的值。
  • 感谢cmets和修改,我是第一次使用StackOverflow,所以可能有歧义。
  • 欢迎来到 SO。您可以使用@username 回复特定用户。我问gameManagerEnableBtnSummon 是如何声明的。如果你不介意展示这一点,那就太棒了。也许发布课程本身......。这些是说明发生了什么所必需的。
  • @Programmer 再次感谢!我已经更新了我的问题,但我认为 gameManager 无关紧要,因为即使在调用 Action 之前就发生了错误。

标签: c# unity3d


【解决方案1】:

例外:

ArgumentException: 值不在预期范围内。

发生在这行代码上:

yield return StartCoroutine(MoveTowards.Start(destoryDelay + 0.5f, false, gameManager.EnableBtnSummon));

正如问题的标题所说,这与StartCoroutine 无关。问题的根源是MoveTowards.Start协程函数。传递给它的第三个参数(Action callback)是问题所在。

问题是您将null 传递给MoveTowards.Start 函数的第三个参数。由于您将gameManager.EnableBtnSummon 传递给第三个参数,这意味着gameManager 变量是null

您可以通过在该代码行之前添加Debug.Log(gameManager) 来验证这一点。控制台选项卡中的输出应为“null”。

修复:

初始化gameManager变量:

GameObject 命名为您的GameManager 脚本附加到“ManagerObj”,然后使用下面的简单代码初始化gameManager 变量。

GameManager gameManager;

void Awake()
{
    gameManager = GameObject.Find("ManagerObj").GetComponent<GameManager>();
}

注意:

Start 函数重命名为其他名称,因为 Unity 内置了名为“Start”和“Awake”的函数。您需要将名称更改为其他名称,但这不是问题。

【讨论】:

  • 你是对的,这个问题已经解决了!我在Start()中初始化了gameManager,所以CoroutineDestroy()启动时可能没有初始化。这就是为什么在删除第一个 WaitForSeconds 时发生异常的原因。相反,在Awake() 中初始化gameManager 更好。
  • 很高兴我能提供帮助。您还需要将 Destroy 函数重命名为其他名称,因为有一个名为 Destroy 的 Unity 函数。
猜你喜欢
  • 2011-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
相关资源
最近更新 更多