首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么我在一次又一次启动协程时得到MissingReferenceException异常?

为什么我在一次又一次启动协程时得到MissingReferenceException异常?
EN

Stack Overflow用户
提问于 2021-08-15 18:43:13
回答 1查看 43关注 0票数 0
代码语言:javascript
运行
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GenerateWalls : MonoBehaviour
{
    public GameObject gameObjectToRaise;
    public float duration;
    public Vector3 raiseAmount;
    public bool go = false;
    public Color[] colors = new Color[4];
    public bool randomColors = false;

    private GameObject objtoraise;
    private GameObject[] walls;
    private bool scaleOver = false;

    private void Start()
    {
        Init();

        ColorWalls();

        // The z Axis must be minimum 1 or any value above 0 could be also 0.1f
        // but it's better to keep it minimum as 1 by default.
        if (raiseAmount.z < 1)
        {
            raiseAmount.z = 1f;
        }

        if (go)
        {
            StartCoroutine(ScaleOverSeconds(objtoraise, new Vector3(raiseAmount.x, raiseAmount.y,
                raiseAmount.z), duration));
        }
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.R))
        {
            //if (scaleOver)
            //{
            if (objtoraise != null)
            {
                if (raiseAmount.z < 1)
                {
                    raiseAmount.z = 1f;
                }


                Destroy(objtoraise);

                Init();

                ColorWalls();

                StartCoroutine(ScaleOverSeconds(objtoraise, new Vector3(raiseAmount.x, raiseAmount.y,
                    raiseAmount.z), duration));

                scaleOver = false;
                //}
            }
        }
    }

    private void Init()
    {
        objtoraise = Instantiate(gameObjectToRaise);
        objtoraise.name = "Walls";

        walls = GameObject.FindGameObjectsWithTag("Wall");
    }

    public IEnumerator ScaleOverSeconds(GameObject objectToScale, Vector3 scaleTo, float seconds)
    {
        float elapsedTime = 0;
        Vector3 startingScale = objectToScale.transform.localScale;
        while (elapsedTime < seconds)
        {
            objectToScale.transform.localScale = Vector3.Lerp(startingScale, scaleTo, (elapsedTime / seconds));
            elapsedTime += Time.deltaTime;
            yield return new WaitForEndOfFrame();
        }

        objectToScale.transform.localScale = scaleTo;

        scaleOver = true;
    }

    private void ColorWalls()
    {
        for (int i = 0; i < walls.Length; i++)
        {
            if (randomColors)
            {
                walls[i].transform.GetChild(0).GetComponent<Renderer>().material.color
                    = GetRandomColour32();
            }
            else
            {
                walls[i].transform.GetChild(0).GetComponent<Renderer>().material.color = colors[i];
            }
        }
    }

    private Color32 GetRandomColour32()
    {
        //using Color32
        return new Color32(
          (byte)UnityEngine.Random.Range(0, 255), //Red
          (byte)UnityEngine.Random.Range(0, 255), //Green
          (byte)UnityEngine.Random.Range(0, 255), //Blue
          255 //Alpha (transparency)
        );
    }
}

在Update()中,当我按下R键时,它正在销毁实例化的对象,然后再次实例化,并再次启动协程。问题是,当我连续两次按下R键后,编辑器中出现了MissingReferenceException exception:

MissingReferenceException:'GameObject‘类型的对象已被销毁,但您仍在尝试访问它。您的脚本应该检查它是否为空,或者您不应该销毁该对象。GenerateWalls+d__12.MoveNext () (见Assets/Scripts/GenerateWalls.cs:81)

第81行是:

代码语言:javascript
运行
复制
objectToScale.transform.localScale = Vector3.Lerp(startingScale, scaleTo, (elapsedTime / seconds));

我们的目标是能够在每次按下R键的时候再次生成墙,它应该停止当前的协程并重新开始。

也许问题是它在协程的中间,因为旧的协程还没有停止,所以对象在中间丢失了,因为我销毁了它?

那么我应该如何做才能一次又一次地按R键,它就会一遍又一遍地启动协程呢?不是启动多个协程,而是每次重新启动协程。

EN

回答 1

Stack Overflow用户

发布于 2021-08-15 18:45:58

解决方案是在更新()中添加: StopCoroutine

这不是解决方案。我以为停止协程也会停止while循环,但它没有,似乎检查while循环中的null就解决了这个问题:

代码语言:javascript
运行
复制
public IEnumerator ScaleOverSeconds(GameObject objectToScale, Vector3 scaleTo, float seconds)
    {
        if (objectToScale != null)
        {
            float elapsedTime = 0;
            Vector3 startingScale = objectToScale.transform.localScale;
            while (elapsedTime < seconds)
            {
                if (objectToScale == null)
                {
                    yield return null;
                }
                else
                {
                    objectToScale.transform.localScale = Vector3.Lerp(startingScale, scaleTo, (elapsedTime / seconds));
                    elapsedTime += Time.deltaTime;
                    yield return new WaitForEndOfFrame();
                }
            }

            objectToScale.transform.localScale = scaleTo;

            scaleOver = true;
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68794426

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档