【问题标题】:Coroutine not working from inside an instantiated object协程不能从实例化对象内部工作
【发布时间】:2021-04-29 12:06:37
【问题描述】:

我正在创建一些由许多不同矩形组成的线。线条和矩形都是由代码创建的。 我用矩形的顶点做一些逻辑,并在我的实例化矩形中更新该信息。这真的很好用。

然后在每个矩形上我有 2 个脚本,一个存储数据,另一个存储协程,以在线条和矩形移动位置后满足某些条件时使矩形闪烁或停止闪烁。

它不起作用,它可能必须使用其他一些外部脚本甚至字典或列表来完成,但由于我是协程的新手,我想知道是否可以通过简单地从每个实例化对象中做到这一点在游戏过程中检查这些 bool 和 int 变量。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class rectanguloAnim : MonoBehaviour{
rectangulo rect; //script containing data from this rectangle

Color32 colOrig;
Material material;
IEnumerator currentFlashCoroutine;



void Start()
{
    rect = GetComponent<rectangulo>();
    colOrig = GetComponent<rectangulo>().colorOriginal;
    material = GetComponent<Renderer>().material;
}


void Update()
{
    // this bool and int change when the line and rect are interacted with
    if (rect.isIntermediate == true || rect.activeDirection != 0)
    {
        if (currentFlashCoroutine != null)
        {
            StopCoroutine(currentFlashCoroutine);
        }

        currentFlashCoroutine = ChangeColor(material, colOrig, Color.white);
        StartCoroutine(currentFlashCoroutine);
    }
    else
    {
        if (currentFlashCoroutine != null)
        {
            StopCoroutine(currentFlashCoroutine);
        }
    }


}

IEnumerator ChangeColor(Material toChange, Color32 startColor, Color32 endColor)
{
    float t = 0;
    float colorDuration = Random.Range(2.49f, 6f);

    while (t < colorDuration)
    {
        float timeDuration = Random.Range(.55f, .95f);
        if (t > timeDuration)
        {
            t = 0;
        }

        t += Time.deltaTime;
        toChange.color = Color.Lerp(startColor, endColor, t / colorDuration);
        yield return null;
    }
}

}

【问题讨论】:

    标签: c# unity3d instantiation coroutine


    【解决方案1】:

    我认为你更应该做你的领域

    private Coroutine currentFlashCoroutine;
    

    然后使用

    currentcurrentFlashCoroutine = StartCoroutine(ChangeColor(material, colOrig, Color.white);
    

    然后做

    if(currentFlashCoroutine != null)
    {
        StopCoroutine (currentFlashCoroutine);
        currentFlashCoroutine = null;
    }
    

    顺便说一句,您也可以使用StopAllCoroutines,因为在您的用例中,无论如何您似乎在课堂上只有一个例程;)


    这里的第二个问题是,只要条件为真,您每一帧都会停止和开始一个新的例程。

    你宁愿做类似的事情

    void Update()
    {
        // this bool and int change when the line and rect are interacted with
        if (rect.isIntermediate || rect.activeDirection != 0)
        {
            // only start a new routine if there is not already one running
            if(currentFlashCoroutine == null)
            {
                currentFlashCoroutine = StartCoroutine(ChangeColor(material, colOrig, Color.white);
            }
        }
        else
        {
            if(currentFlashCoroutine != null)
            {
                StopCoroutine (currentFlashCoroutine);
                currentFlashCoroutine = null;
            }
        }
    }
    
    IEnumerator ChangeColor(Material toChange, Color32 startColor, Color32 endColor)
    {
        var t = 0f;
        var colorDuration = Random.Range(2.49f, 6f);
    
        while (t < colorDuration)
        {
            var timeDuration = Random.Range(.55f, .95f);
            if (t > timeDuration)
            {
                t = 0;
            }
    
            t += Time.deltaTime;
            toChange.color = Color.Lerp(startColor, endColor, t / colorDuration);
            yield return null;
        }
    
        currentFlashRoutine = null;
    }
    

    【讨论】:

    • 我已经尝试重写这些行,但协程仍然没有为任何对象启动。我怀疑尝试从实例化对象运行协程可能是一个问题,但仍然不太了解协程。
    • 如果您的条件为真,这应该可以工作..您是否尝试过调试,如果达到该行?
    • 是的,这会正确记录条件: if (rect.esIntermedio == true || rect.activoDireccion != 0) { Debug.Log(rect.esIntermedio.ToString() + ":" + rect.activoDirection); if (currentFlashCoroutine != null) { StopCoroutine(currentFlashCoroutine); } [其余代码]
    • 再次,如果您的条件符合预期,我在代码中看不到为什么这不起作用......条件保持多久?也许它会在下一帧立即停止,例如?
    • 它们只有在我拖动一行矩形并再次检查顶点时才会改变。当我拖动一条线时,标志正在正确更改,但协程没有。我读到在更新方法中启动协程不是一个好习惯,这就是问题所在。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-06
    • 2016-10-02
    • 2021-06-05
    • 1970-01-01
    • 2011-12-15
    • 1970-01-01
    相关资源
    最近更新 更多