【Unity】現在時刻によってSkyBoxの色を変化させる

# 概要
時間によって空の色を自由に変えます。
パーティクルのColor Over Lifetimeのように時間で変化するカラーをアニメーションカーブで再現しました。
# 結果
![ezgif.com-optimize.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534178/94d56fcf-4542-0296-7cf9-1087e6d8994a.gif)

# サンプルコード
```C#:DynamicSky.cs
using UnityEngine;
using System;

public class DynamicSky : MonoBehaviour
{
    [SerializeField]
    private AnimationCurve Curve_R, Curve_G, Curve_B;

    void Start()
    {
        DateTime now = DateTime.Now;
        float val = (now.Hour * 60f + now.Minute) / (24 * 60);
        Color col = new Color(Curve_R.Evaluate(val), Curve_G.Evaluate(val), Curve_B.Evaluate(val));
        
        Material mat = new Material(RenderSettings.skybox);
        mat.SetColor("_Tint", col);
        RenderSettings.skybox = mat;
    }
}
```
結果のgifと違いstart時にだけ実行されます
##解説
```C#
    DateTime now = DateTime.Now;
    float val = (now.Hour * 60f + now.Minute) / (24 * 60);
```
時間を取得し０時からの進行度を割り出します。

```C#
    Color col = new Color(Curve_R.Evaluate(val), Curve_G.Evaluate(val), Curve_B.Evaluate(val));
```
時間に対応する色を返します。

```C#
    Material mat = new Material(RenderSettings.skybox);
    mat.SetColor("_Tint", col);
    RenderSettings.skybox = mat;
```
スカイボックスに色を設定します。
これはシェーダーがSkybox/Cubemapの場合で、デフォルトのスカイボックスでは"_Tint"の部分が"_SkyTint"となります。
また注意点として、

```C#
    RenderSettings.skybox.SetColor("_Tint", col);
```
のようにすると直接プロジェクトのマテリアルを書き換えてしまうので、新しく作ったものを差し替えてます。
# カーブの設定
以下を目安に設定すると現実に近くなると思います。
valが時間の進行、R、G、Bがそれぞれの値です。

|val|R  |G  |B  |
|----|---|---|---|
|0|0|0.1|0.17|
|0.16|0|0.1|0.17|
|0.28|0.38|0.41|0.41|
|0.5|0.5|0.5|0.5|
|0.7|0.5|0.45|0.4|
|0.8|0.1|0.15|0.2|
|1|0|0.1|0.17|
<img width="981" alt="スクリーンショット 2020-02-17 17.45.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534178/77b9789d-5b76-e5b2-fb1e-ec276eda309e.png">

## 追記
カーブは手動で編集せずスクリプトから設定することもできます。

```C#

        Keyframe[] frames_R = new Keyframe[7];
        Keyframe[] frames_G = new Keyframe[7];
        Keyframe[] frames_B = new Keyframe[7];

        frames_R[0] = new Keyframe(0f,0f,0f,0f);
        frames_R[1] = new Keyframe(0.16f,0f,0f,3f);
        frames_R[2] = new Keyframe(0.28f,0.38f,3f,1f);
        frames_R[3] = new Keyframe(0.5f,0.5f,0.2f,0.05f);
        frames_R[4] = new Keyframe(0.7f,0.5f,-0.05f,-3f);
        frames_R[5] = new Keyframe(0.8f,0.1f,-3f,-1f);
        frames_R[6] = new Keyframe(1f,0f,-0.1f,0f);

        frames_G[0] = new Keyframe(0f,0.1f,0,0);
        frames_G[1] = new Keyframe(0.16f,0.1f,0f,3f);
        frames_G[2] = new Keyframe(0.28f,0.42f,3f,1f);
        frames_G[3] = new Keyframe(0.5f,0.5f,0.1f,-0.05f);
        frames_G[4] = new Keyframe(0.7f,0.45f,-0.5f,-3f);
        frames_G[5] = new Keyframe(0.8f,0.15f,-3f,-0.8f);
        frames_G[6] = new Keyframe(1f,0.1f,-0.1f,0f);

        frames_B[0] = new Keyframe(0f,0.17f,0f,0f);
        frames_B[1] = new Keyframe(0.16f,0.17f,0f,3f);
        frames_B[2] = new Keyframe(0.28f,0.41f,2.5f,1f);
        frames_B[3] = new Keyframe(0.5f,0.5f,0.1f,-0.07f);
        frames_B[4] = new Keyframe(0.7f,0.4f,-0.7f,-3f);
        frames_B[5] = new Keyframe(0.8f,0.2f,-3f,-0.5f);
        frames_B[6] = new Keyframe(1f,0.17f,-0.1f,0f);

        // カーブにキーフレームを設定する
        Curve_R = new AnimationCurve(frames_R);
        Curve_G = new AnimationCurve(frames_G);
        Curve_B = new AnimationCurve(frames_B);
```


# 終わりに
回転なども加えればより現実に近い挙動にできそうですね。