Unity 中背景时间环与灯光的配合

Unity 中背景时间环与灯光的配合

1. 效果描述

假设有一背景时间环以一定的速度转动来表达昼夜变化。而想用灯光来配合时间环的转动,来将昼夜变化更加自然的体现出来。

灯光主要可以通过以下两个方面来体现时间的变化:

  • 光照强度
    • 正午时光照强度最强
    • 午夜时光照强度最弱
  • 光照颜色
    • 正午时光照颜色为橘黄色
    • 午夜时光照颜色为暗蓝色

光照的变化应当是随着背景时间环而渐变的。

表现如下图所示:
正午时:
在这里插入图片描述

午夜时:
在这里插入图片描述

2. 解决思路

背景时间环是一直在转动的,可以根据当前的转动角度来决定灯光的强度与颜色属性。
分析可得以下映射表:

时间 角度a 灯光强度s 灯光颜色c
正午 1.5 255,244,214
午夜 -180° 0.25 144,259,204

可以看出输入值是角度,输出值是灯光强度与灯光颜色,而这两个输出值都是在一定范围内周期性变化。
由此可想到使用三角函数公式。

灯光强度公式如下:
s = 0.625 c o s ( a ) + 0.65 s=0.625cos(a)+0.65 s=0.625cos(a)+0.65

因为开始旋转角度为0时是正午,灯光强度为最大值1.5,所以使用cos函数
其中振幅A = 0.625 是根据(1.5-0.25)/2得到的。

3. 代码实现

时间环控制代码如下:

public class TimeRingController : MonoBehaviour
{
    public LightController LC;
    public Vector3 playSpeed;
    private bool isDayTime;
    private bool isPlaying;

    public bool IsDayTime { get => isDayTime; set => setTime(value); }
    public bool IsPlaying { get => isPlaying; set => isPlaying = value; }

    void Start()
    {
        LC = GameObject.Find("Light").GetComponent<LightController>();
        isDayTime = true;
        isPlaying = false;
    }
    //转动时间环函数
    private void FixedUpdate()
    {
        if (isPlaying)
        {
            transform.Rotate(playSpeed, Space.Self);
            //根据当前角度设置灯光属性
            LC.setTimeByAngle(transform.rotation.eulerAngles.z);
        }
            
    }
    private void setTime(bool isDayTime)
    {
        this.isDayTime = isDayTime;
        if (isDayTime)
        {
            transform.rotation = Quaternion.Euler(new Vector3(0, 0, 0));
            LC.setTime(true);
        }
        else
        {
            transform.rotation = Quaternion.Euler(new Vector3(0, 180, 0));
            LC.setTime(false);
        }
            
    }
}

灯光控制代码如下:

using UnityEngine;

public class LightController : MonoBehaviour
{
    private Light theLight;
    public float maxInstensity;
    public float minInstensity;
    public Color dayTimeColor;
    public Color nightTimeColor;
    public float speed;

    private void Start()
    {
        theLight = gameObject.GetComponent<Light>();
    }
    //三角函数的实现
    private float trigonometric(float min, float max,float angle)
    {
        float rad = angle * Mathf.Deg2Rad;
        float A = (max - min) / 2.0f;
        float fai = min + A;
        return A * Mathf.Cos(rad) + fai;
    }
    //根据角度转换灯光属性
    public void setTimeByAngle(float angle)
    {
        theLight.intensity = trigonometric(minInstensity,maxInstensity,angle);
        if(100<angle && angle<200)
            theLight.color = nightTimeColor;
        else
            theLight.color = dayTimeColor;
    }
    public void setTime(bool isDayTime)
    {
        if (isDayTime)
        {
            theLight.intensity = maxInstensity;
            theLight.color = dayTimeColor;
        }
        else
        {
            theLight.intensity = minInstensity;
            theLight.color = nightTimeColor;
        }
    }
}

4. 需要注意的点

  • GameObject的transform.rotation属性是四元数,得转换为欧拉角然后再转换为弧度制才能使用

  • 2D精灵是无法对3D的灯光有反应的
    因为2D精灵使用的是默认的2D图片材质
    想要让3D灯光在2D精灵图片上有效果,需要自定义材质
    如下图所示:
    在这里插入图片描述

    其中渲染模式(RenderingMode)要设置为:Cutout,其它设置根据需求进行更改。

猜你喜欢

转载自blog.csdn.net/qq_44705559/article/details/120228899