如何在Unity中编写代码实现精灵之间的淡入淡出过渡效果?

3

我有4张PNG格式的动画图片,想让它们按照1-2-3-4-2-1的顺序,在半秒内播放,并且具备透明度渐变效果。

我的代码应该实现当父级对象生成时,第一帧立即出现,并在1/12秒内变成透明状态,同时第二帧变成不透明状态,以此类推,直到最后一帧完成其透明-不透明-透明的循环。

这可能不是最有效率的方法,但我已经创建了一个预制体,其中包含一个空对象和6个精灵帧,每个精灵都分配了单独的脚本。

以下是前三个脚本的示例:

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

public class Frame1 : MonoBehaviour
{
    private SpriteRenderer thisSprite;
    private Color alpha;
    private float timer;
    // Start is called before the first frame update
    void Start()
    {
        alpha.a = 255;
        thisSprite.GetComponent<SpriteRenderer>().color = alpha;
    }

    // Update is called once per frame
    void Update()
    {
        timer = timer + Time.deltaTime;
        alpha.a -= timer * 3060;
        thisSprite.GetComponent<SpriteRenderer>().color = alpha;
        if (timer >= 1/12)
        {
            Destroy(gameObject);
        }

    }
}

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

public class Frame2 : MonoBehaviour
{
    private SpriteRenderer thisSprite;
    private Color alpha;
    private float timer;
    private int direction;
    // Start is called before the first frame update
    void Start()
    {
        alpha.a = 0;
        thisSprite.GetComponent<SpriteRenderer>().color = alpha;
    }

    // Update is called once per frame
    void Update()
    {
        if (direction == 0)
        {
            timer = timer + Time.deltaTime;
            alpha.a += timer * 3060;
            thisSprite.GetComponent<SpriteRenderer>().color = alpha;
            if (timer >= 1/12)
            {
                direction = 1;
            }
        }
        if (direction == 1)
        {
            timer = timer - Time.deltaTime;
            alpha.a += timer * 3060;
            thisSprite.GetComponent<SpriteRenderer>().color = alpha;
            if (timer >= 1/6)
            {
                Destroy(gameObject);
            }
        }

    }
}

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

public class Frame3 : MonoBehaviour
{
    private SpriteRenderer thisSprite;
    private Color alpha;
    private float timer;
    private int direction;
    // Start is called before the first frame update
    void Start()
    {
        alpha.a = 0;
        thisSprite.GetComponent<SpriteRenderer>().color = alpha;
        timer -= 1 / 12;
    }

    // Update is called once per frame
    void Update()
    {
        if (direction == 0)
        {
            timer = timer + Time.deltaTime;
            alpha.a += timer * 3060;
            thisSprite.GetComponent<SpriteRenderer>().color = alpha;
            if (timer >= 1 / 12)
            {
                direction = 1;
            }
        }
        if (direction == 1)
        {
            timer = timer - Time.deltaTime;
            alpha.a += timer * 3060;
            thisSprite.GetComponent<SpriteRenderer>().color = alpha;
            if (timer >= 1 / 6)
            {
                Destroy(gameObject);
            }
        }

    }
}

它们似乎在生成时就全部可见,而且它们不会消失或被摧毁。问题出在哪里呢?

谢谢。


你需要使用完全不同的方法来完成这个任务。使用Sprite表创建一个能够完美模拟这些动画的动画效果。将该动画放入Animator控制器中,将其附加到对象上并且要保证该对象只有一个脚本 which starts the animation (使用Animator Controller conditions设置它的触发器)。我现在没有时间给出完整的答案,但如果没有人回答,稍后我会提供答案。 - Eric
我会检查一下你当前回答中的方法是否理解...但是我的方法有什么问题吗?假设我有一组不同的对象,我想让它们的 alpha 值随时间变化而变化。你怎么告诉它们这样做呢?从我所了解的来看,写的那些行应该修改对象的 alpha 值。 - TLSO
这种方法对我来说似乎非常奇怪,我从未使用过类似的东西,因此我无法回答 - 相反,我可以指向最佳实践 :) 想象一下,如果您有很多精灵,并且您想以不同的方式对它们进行动画处理。 精灵表和动画将是正确的选择。 这就是为什么我没有发布答案的原因,我不知道如何解决您的问题,而是可以解释正确的做法 - 也许有人会回答 :) - Eric
哦,等等。如果我理解正确,你的意思是让我将淡入PNG动画化?我想避免这样做,因为这会创建更多的PNG数据,我认为这是不必要的。我正在动画化的帧相当高分辨率,因此制作30个(以60fps的1/2)来动画化4个关键帧似乎效率低下。 - TLSO
但是你提到了事先创建额外的PNG帧以进行转换,对吗? - TLSO
显示剩余3条评论
1个回答

0
如评论所建议,使用动画是一个可行的替代方案。然而,您的代码不起作用,因为alpha接受的值范围是0到1,而不是0到255。 因此,只需调整逻辑,从1逐渐减少到0,您就应该看到淡出过渡效果。

我最终理解了,第一个问题实际上是我没有正确表达GetComponent部分,因此它没有与脚本持有的对象交互,但现在出现了一些问题,尽管精灵现在会显示和消失,但时间不正确。它们只存在了几分之一秒,我不明白为什么。 - TLSO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接