简体   繁体   English

Unity5:有没有想法在没有协程的情况下编写代码FadeIn / Out?

[英]Unity5 : Is there any idea to write code FadeIn/Out without Coroutine?

I'm thinking to make FadeIn/Out effect by C#. 我正在考虑使用C#进行FadeIn / Out效果。

// so, If there's a code like this : //因此,如果有这样的代码:

    float targetAlpha = 0.7f;
    Color targetColor = new Color();

    public void FadeIn() {
    if(color.a < targetAlpha) { color.a += Time.deltaTime; }
    sprite.color = targetColor;
    }

1) I don't want to put FadeIn() in Update() because I don't use this FadeIn() function often. 1)我不想将FadeIn()放在Update()中,因为我不经常使用此FadeIn()函数。

2) I don't want to use Coroutine because StartCoroutine() makes garbage. 2)我不想使用Coroutine,因为StartCoroutine()会产生垃圾。 I will set active on/off this object very often. 我会经常打开/关闭此对象。

3) Animator... There's no way, right? 3)动画师...没有办法,对吧?

So I'm going to make 1 event, which will always work on Update(), and then I will put everything in that event. 因此,我将创建1个事件,该事件将始终在Update()上运行,然后将所有内容放入该事件中。 (add when OnEnable(), remove when OnDisable()) (在OnEnable()时添加,在OnDisable()时删除)

Is there a better solution? 有更好的解决方案吗?

If you don't want to put it in update because it won't be used often, maybe you can consider a state machine approach. 如果由于不经常使用而不希望将其更新,则可以考虑使用状态机方法。 I would only consider this if performance really is more important than readability. 如果性能确实比可读性更重要,我只会考虑这一点。 Because this approach will add a lot of additional code. 因为这种方法会添加很多其他代码。

For simplicity the code below is more verbose than it has to be. 为了简单起见,下面的代码比必须的更为冗长。

public interface IState
{
    void Update();
}

public class FadeInState : IState
{
    private readonly float targetAlpha;
    private readonly Sprite sprite;
    private readonly Action onComplete;

    public FadeInState(Sprite sprite, float targetAlpha, Action onComplete)
    {
        this.targetAlpha = targetAlpha;
        this.sprite = sprite;
        this.onComplete = onComplete;
    }

    public void Update()
    {
        // Your fade-in code
        if (sprite.color.a < targetAlpha)
        {
            Color tmp = sprite.color;
            tmp.a += Time.deltaTime;
            sprite.color = tmp;
        }
        else
        {
            this.onComplete.Invoke();
        }
    }
}

public class FadeOutState : IState
{
    private readonly float targetAlpha;
    private readonly Sprite sprite;
    private readonly Action onComplete;

    public FadeOutState(Sprite sprite, float targetAlpha, Action onComplete)
    {
        this.targetAlpha = targetAlpha;
        this.sprite = sprite;
        this.onComplete = onComplete;
    }

    public void Update()
    {
        // Your fade-out code
        if (sprite.color.a > targetAlpha)
        {
            Color tmp = sprite.color;
            tmp.a -= Time.deltaTime;
            sprite.color = tmp;
        }
        else
        {
            this.onComplete.Invoke();
        }
    }
}

public class DoNothingState : IState
{
    public void Update()
    {
        // Do nothing
    }
}

public class YourClass : MonoBehaviour
{
    private IState currentState;

    void Awake()
    {
        this.currentState = new DoNothingState();
    }

    void Update()
    {
        this.currentState.Update();
    }

    public void FadeIn(Sprite sprite, float targetAlpha)
    {
        this.currentState = new FadeInState(sprite, targetAlpha,
            () =>
            {
                this.currentState = new DoNothingState();
            });
    }

    public void FadeOut(Sprite sprite, float targetAlpha)
    {
        this.currentState = new FadeOutState(sprite, targetAlpha,
            () =>
            {
                this.currentState = new DoNothingState();
            });
    }
}

Initially your class is in the DoNothing state. 最初你的类在DoNothing状态。 So update will effectively do nothing. 因此,更新实际上不会执行任何操作。

If someone calls FadeIn , your FadeInState will do your fading logic as if it were in the MonoBehaviour.Update() . 如果有人调用FadeIn ,则您的FadeInState将像在MonoBehaviour.Update()那样执行衰落逻辑。

The state takes an Action in the constructor that is executed when it is finished. 状态在构造函数中接受一个Action,该Action在完成时执行。 This way you can control what happens after the animation completes from within YourClass . 这样,您可以从YourClass控制动画完成后的操作。 In the example I just set the state to DoNothing but you can probably disable the gameObject. 在示例中,我只是将状态设置为DoNothing但您可能可以禁用gameObject。

If you go with this approach and you start using it for other things, you should just look into some better StateMachine implementations. 如果采用这种方法,并开始将其用于其他用途,则应该研究一些更好的StateMachine实现。 Otherwise you will eventually end up with tons of state classes. 否则,您最终将获得大量的州级课程。 This one is decent. 一个体面的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM