【问题标题】:Can i use IEnumerator as Update func?我可以使用 IEnumerator 作为更新函数吗?
【发布时间】:2019-08-17 07:11:04
【问题描述】:

我有一些结构,如对象 - 4 个子对象 - 每个孩子还有 2 个孩子。我希望为每个子对象更改其颜色的 alpha。

我创建了应该更改 alpha 的 IEnumarator,但是当我测试它时它只会更改为 0.8,而不是 0,而且我还想按时间更改它,例如平滑 2 秒,但它发生得很快

imageComponents = gameObject.GetComponentsInChildren<Image>();
textComponents = gameObject.GetComponentsInChildren<Text>();    

IEnumerator HideAllBoosters(Transform _object)
    {
        foreach (Image image in imageComponents)
        {
            Color _color = image.GetComponent<Image>().color;
            _color = new Color(_color.r, _color.g, _color.b, 0);
            image.GetComponent<Image>().color = Color.Lerp(image.color, _color, 10 * Time.deltaTime);
        }
        foreach (Text text in textComponents)
        {
            Color _color = text.GetComponent<Text>().color;
            _color = new Color(_color.r, _color.g, _color.b, 0);
            text.GetComponent<Text>().color = Color.Lerp(text.color, _color, 10 * Time.deltaTime);
        }
        yield return null;
    } 

Idk 如何正确地做到这一点,mb 我应该在 Update 中为每个对象更改颜色,但我不确定它是否有利于清晰和简单的代码,所以我要求的是 - 我可以为每个对象使用另一个 IEnumerator 吗?一个更新,比如:

    foreach (Image image in imageComponents)
    {
         StartCourutine(changeAlpha(image));
    }

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    错误在于将10 * Time.deltaTime 作为Lerp(Vector3 a, Vector3 b, float t);t 值传递

    如果您查看documentationLerp()

    当 t = 0 时返回 a。当 t = 1 时返回 b。当 t = 0.5 时,返回 a 和 b 之间的中间点。

    这意味着为了让您的 alpha 有一个漂亮的淡入淡出,Lerp()t 值应该是一个从 1 到 0(或者如果你想淡入,则为 0 到 1)的值。一定时间。现在你传入10 * Time.deltaTime,这将始终是相同的值,基于帧率。 (在这种情况下,大约为 0.8)。

    要解决此问题,您需要 t 是一个在 0 和 1 之间缓慢增加/减少(取决于您想要淡入还是淡出)的值。一种方法是将您的逻辑封装在一个 while 循环中。

    float speed = 0.01f; 
    float time = 0;
    while ( time < 1)
    {
        time += speed;
        //Rest of code
    }
    

    这将在每次循环运行时将time 的值增加speed(在本例中为 0.01),在本例中为 100 次迭代 (0.01 * 100 = 1)。

    我们现在可以将此time 值作为t 值应用到Lerp() 方法中,以使其平滑过渡

    image.color = Color.Lerp(image.color, _color, time);
    

    如果您希望淡入淡出花费更多或更少的时间,只需增加或减少 speed 中的值。

    整个实现看起来像这样(请注意,我还做了一些优化,稍后会介绍)

    ​​>
    public float speed = 0.01f; //The speed at which the fade happens
    
    private Image[] imageComponents;
    private Text[] textComponents;
    
    void Start()
    {
        imageComponents = gameObject.GetComponentsInChildren<Image>(); //Cache the images so we don't have to find them every time
        textComponents = gameObject.GetComponentsInChildren<Text>(); //Cache the texts
    
        StartCoroutine(HideAllBoosters());//Start the Coroutine
    }
    
    IEnumerator HideAllBoosters()
    {
        float t = 0; //Start value for our loop
        while (t < 1) // 1 indicates the max value of t at which the loop stops. In this case after 100 iterations since the speed is 0.01
        {
            t += speed;
    
            foreach (Image image in imageComponents)
            {
                Color _color = image.color;
                _color = new Color(_color.r, _color.g, _color.b, 0);
                image.color = Color.Lerp(image.color, _color, t); //t dictates how far in the interpolation we are.
            }
            foreach (Text text in textComponents)
            {
                Color _color = text.color;
                _color = new Color(_color.r, _color.g, _color.b, 0);
                text.color = Color.Lerp(text.color, _color, t);
            }
            yield return null;
        }
    }
    

    我所做的优化: 循环通过imageComponentstextComponents 的数组已经是ImageText 类型。这意味着当您在 foreach() 循环中循环它们时,Image imageText text 已经属于它们各自的类型,并且已经持有对其组件的引用。这意味着您的.GetComponent&lt;Image&gt;().GetComponent&lt;Text&gt;() 调用是不必要的。

    例如:

    Color _color = image.GetComponent<Image>().color;
    

    相同
    Color _color = image.color;
    

    我还删除了HideAllBoosters 所需的Transform _object 参数,因为该方法似乎根本没有使用它。可能是您稍后在此问题范围之外的函数中的某处使用了此值。如果是这种情况,您当然需要包含它。

    【讨论】:

      猜你喜欢
      • 2020-02-09
      • 1970-01-01
      • 1970-01-01
      • 2015-03-10
      • 2023-03-16
      • 2020-11-29
      • 1970-01-01
      • 2013-09-20
      • 1970-01-01
      相关资源
      最近更新 更多