Unity 简易的UI背景昼夜轮替效果

在UI背景上实现一个简易的有光影照射的昼夜轮替效果,往往比一个死板的UI背景看起来更加形象生动,比较传统的方式是多图轮流替换的序列帧动画,不过要达到整个UI背景大图的所有地方都产生光影效果,那么务必每张图都是全屏大图,这样的话资源浪费又过于严重了;高端点的话,可以用shader来实现,不过本文会以一种更简单的方式实现这种效果。

主要的思路是为UI背景图片指定一个材质,新建一个默认材质就可以了,让它可以接收光照,然后在指定的位置加入灯光并适当调节,就可以达到很好的光影效果了。


首先在场景中创建一个点光源作为夜晚的月亮,创建一个方向光作为白天的阳光,然后变化这两个灯光的强度以达到昼夜轮替效果,代码如下:

//夜晚灯光
    private Light NightLight;
    //白天灯光
    private Light DayLight;
    //昼夜轮替速度
    public float _Speed = 0.2f;
    //一天的时间
    public int _Time = 3;
    //昼夜轮替方向
    private int _Direction = -1;
    //开启昼夜轮替的时间流逝
    private bool _IsTimeLapse = false;

    void Start () {
        NightLight = GlobalManager._Login.FindChild("夜晚灯光").GetComponent<Light>();
        DayLight = GlobalManager._Login.FindChild("白天灯光").GetComponent<Light>();
        //初始一天时间结束后昼夜轮替开始
        StartCoroutine(GlobalManager._Tool.DelayToInvokeDo(delegate() {
            _IsTimeLapse = true;
        }, _Time));
    }
    void Update () {
        if (GlobalManager._Login.gameObject.activeSelf)
        {
            //开启昼夜轮替
            if (_IsTimeLapse)
            {
                //白天状态
                if (DayLight.gameObject.activeSelf)
                {
                    //通过修改灯光强度以体现时间流逝的效果
                    DayLight.intensity += Time.deltaTime * _Speed * _Direction;
                    //白天灯光强度为0,标示着白天结束
                    if (DayLight.intensity <= 0 && _Direction < 0)
                    {
                        //进入夜晚
                        DayLight.gameObject.SetActive(false);
                        NightLight.gameObject.SetActive(true);
                        _Direction *= -1;
                        return;
                    }
                    //白天持续中
                    if (DayLight.intensity >= 1 && _Direction > 0)
                    {
                        _Direction *= -1;
                        _IsTimeLapse = false;
                        //一天时间结束后再开启时间流逝
                        StartCoroutine(GlobalManager._Tool.DelayToInvokeDo(delegate () {
                            _IsTimeLapse = true;
                        }, _Time));
                        return;
                    }
                }
                //夜晚状态
                if (NightLight.gameObject.activeSelf)
                {
                    //通过修改灯光强度以体现时间流逝的效果
                    NightLight.intensity += Time.deltaTime * _Speed * _Direction;
                    //夜晚灯光强度为0,标示着夜晚结束
                    if (NightLight.intensity <= 0 && _Direction < 0)
                    {
                        //进入白天
                        DayLight.gameObject.SetActive(true);
                        NightLight.gameObject.SetActive(false);
                        _Direction *= -1;
                        return;
                    }
                    //夜晚持续中
                    if (NightLight.intensity >= 1 && _Direction > 0)
                    {
                        _Direction *= -1;
                        _IsTimeLapse = false;
                        //一天时间结束后再开启时间流逝
                        StartCoroutine(GlobalManager._Tool.DelayToInvokeDo(delegate () {
                            _IsTimeLapse = true;
                        }, _Time));
                        return;
                    }
                }
            }
        }
	}

DelayToInvokeDo是一个延时执行函数,参照我的另一篇博客

我这里随便找了一张图片,可以看到效果图还是不错的。

白天(阳光最强时):


黄昏(阳光变弱):


夜晚(窗顶上的那个是月亮):



大笑大笑大笑

原文地址:https://www.cnblogs.com/liang123/p/6325870.html