Unityで太陽を作り夜にする方法メモ。ゲーム内時間経過で太陽を動かし昼夜サイクルを作る

Unity 太陽作り方 昼夜サイクル ゲーム内時間 3Dゲームの作り方
※記事内に広告が含まれています。

バーチャル3Dクリエイター神部まゆみです(*^_^*)

この記事はUnityで太陽を作り夜にしたり昼にしたりするサイクルを作った記事です。

動作確認した最新バージョンは Unity 6000.3.1 です。

●PRスペース●
■PR■

現在、Unityアセットストアで毎日日替わりでアセットが無料配布されています。(2025/12/31 まで)。

A Free Asset Every Day | Unity Assets Store

ページに記載されているクーポンコードを決済画面で入力すれば0円になりますが、記載の日程は時差で日本より遅れてるっぽいので注意。

〇まゆみマート|BOOTH

BOOTHでVRoidテクスチャやVRChat向けオブジェクトなどを販売しています。いいねしてくれると励みになります(*^-^*)

やりたいこと:シーン内に太陽を作りゲーム内時間に沿って移動させ、昼夜サイクルを作りたい

太陽っていうかディレクショナルライトが太陽になる感じかな?

シーンの中心を元にディレクショナルライトを回転させればそれっぽくなるんじゃないかと思う。

ChatGPTパイセンに聞いてみる

彼に聞けばたちどころに解決してくれるに違いない…。

Unity 太陽作り方 昼夜サイクル ゲーム内時間
神部まゆみ
神部まゆみ

Unityでゲーム開発をしています。シーン内で時間経過で日が昇り夜になり朝になり…というサイクルを作りたいです。これって太陽となるライトを動かして作る感じなんでしょうか?これを作る場合ゲーム内の時間も作る必要があると思いますが、その作り方も教えてください。

ChatGPT
ChatGPT

いいテーマですね。日夜サイクルは“世界が生きてる感”を一気に出せるやつなので、作りがいあります。
結論から言うと 「太陽役のDirectional Lightを回す」+「ゲーム内時間を自前で管理する」 のが王道です。

① 日夜サイクルの基本的な考え方

はい、その理解で合ってます 👍
Unityでは普通、太陽=Directional Light です。

  • X軸(または任意の軸)で回転させる
  • 昼:上から照らす
  • 夕方:斜め
  • 夜:地面の下に行く(光が当たらない)

これだけで「日が昇って沈む」動きは作れます。


② ゲーム内時間の作り方(超重要)

現実時間とは切り離して、ゲーム用の時間を作ります。

例:

  • 1日 = 24時間
  • ゲーム内1時間 = 現実の10秒
    → 1日 = 240秒(4分)

シンプルな時間管理スクリプト例

using UnityEngine;

public class GameTime : MonoBehaviour
{
    // ゲーム内の現在時刻(0〜24)
    public float currentTime = 6f; // 朝6時スタート
    public float dayLengthInSeconds = 240f; // 1日が240秒

    void Update()
    {
        float timeSpeed = 24f / dayLengthInSeconds;
        currentTime += Time.deltaTime * timeSpeed;

        if (currentTime >= 24f)
        {
            currentTime -= 24f;
        }
    }
}

これで

  • currentTime0〜24 をぐるぐる回る
  • 「今何時か」をゲーム全体で使えるようになります

③ 時間と太陽の回転をつなぐ

次に、この時間を使って太陽を回します。

using UnityEngine;

public class SunController : MonoBehaviour
{
    public Light sunLight;
    public GameTime gameTime;

    void Update()
    {
        // 0時 → -90度、12時 → 90度、24時 → 270度
        float sunAngle = (gameTime.currentTime / 24f) * 360f - 90f;
        sunLight.transform.rotation = Quaternion.Euler(sunAngle, 170f, 0f);
    }
}

これで

  • 朝:太陽が昇る
  • 昼:真上
  • 夜:地面の下

という動きになります。


④ 夜っぽさを出す(ここからが楽しい)

1. 太陽の強さを時間で変える

sunLight.intensity = Mathf.Clamp01(
    Mathf.Cos((gameTime.currentTime - 12f) / 24f * Mathf.PI * 2f)
);

→ 夜は暗く、昼は明るく。


2. 環境光(Ambient Light)も変える

RenderSettings.ambientIntensity = Mathf.Lerp(0.2f, 1.0f, sunLight.intensity);

3. 夜用ライト(月)

  • もう1つDirectional Lightを作って「月」にする
  • 夜だけ有効化すると雰囲気アップ 🌙

⑤ よくある設計のコツ

  • 時間管理は1か所にまとめる
    → NPC、イベント、UI時計全部が同じ時間を見る
  • float時間(6.5 = 6時30分)で持つと楽
  • 「朝になったらイベント発火」なども簡単になる

⑥ 最初はここまでできれば十分

最初のゴールとしては👇でOKです。

  • Directional Lightを回す
  • ゲーム内時間を作る
  • 明るさが昼夜で変わる

そこから

  • 季節
  • 天気
  • 夜だけ出る敵
    …みたいにどんどん拡張できます。

そこまで難しくなさそうかなぁ。

まぁやってみます。

実際に実装してみる

本当に動くか実装してみます。

GameTime.csを作る

プロジェクトフォルダでGameTime.csってスクリプトを作り、これをコピペします。

using UnityEngine;

public class GameTime : MonoBehaviour
{
    // ゲーム内の現在時刻(0〜24)
    public float currentTime = 6f; // 朝6時スタート
    public float dayLengthInSeconds = 240f; // 1日が240秒

    void Update()
    {
        float timeSpeed = 24f / dayLengthInSeconds;
        currentTime += Time.deltaTime * timeSpeed;

        if (currentTime >= 24f)
        {
            currentTime -= 24f;
        }
    }
}

Unity 太陽作り方 昼夜サイクル ゲーム内時間

SunController.csを作る

これもコピペして作ります。

using UnityEngine;

public class SunController : MonoBehaviour
{
    public Light sunLight;
    public GameTime gameTime;

    void Update()
    {
        // 0時 → -90度、12時 → 90度、24時 → 270度
        float sunAngle = (gameTime.currentTime / 24f) * 360f - 90f;
        sunLight.transform.rotation = Quaternion.Euler(sunAngle, 170f, 0f);
    }
}

Unity 太陽作り方 昼夜サイクル ゲーム内時間

空のオブジェクトを作り、GameTimeとSunControllerをアタッチして設定

SunControllerコンポーネントにディレクショナルライト、GameTimeコンポーネントを指定します。

これで動いた!

これだけでちゃんと動きました!

ディレクショナルライト動かすだけでそれっぽくなるのか…。

しかし日没後も照らされてるのは気になるか…

日が沈んだ後も横から照らされてしまってる感じなのでここは気になるかな…。

Unity 太陽作り方 昼夜サイクル ゲーム内時間

ChatGPT氏の言うように日没後は太陽役のディレクショナルライトは光を弱くして、代わりに月でうっすら青く照らすみたいにすると良いかな?

月も追加して改良してみる

青っぽい感じの月を追加して夜だけ出るようにし、時間帯によって太陽と月の光を調節するとそれっぽくなると思います。

Unity 太陽作り方 昼夜サイクル ゲーム内時間

SunController.csを書き換える

以下のように書き換えます。

using UnityEngine;

public class SunController : MonoBehaviour
{
    public Light sunLight;
    public Light moonLight;
    public GameTime gameTime;

    [Header("Intensity")]
    public float sunMaxIntensity = 1.2f;
    public float moonMaxIntensity = 0.3f;

    [Header("Ambient")]
    public float dayAmbient = 1.0f;
    public float nightAmbient = 0.2f;

    void Update()
    {
        float time01 = gameTime.currentTime / 24f; // 0〜1

        // ===== 太陽の回転 =====
        float sunAngle = time01 * 360f - 90f;
        sunLight.transform.rotation = Quaternion.Euler(sunAngle, 170f, 0f);

        // ===== 太陽の明るさ =====
        float sunIntensity = Mathf.Clamp01(
            Mathf.Cos((gameTime.currentTime - 12f) / 24f * Mathf.PI * 2f)
        );
        sunLight.intensity = sunIntensity * sunMaxIntensity;

        // ===== 月の回転(太陽の反対側) =====
        moonLight.transform.rotation = Quaternion.Euler(sunAngle + 180f, 170f, 0f);

        // ===== 月の明るさ(夜だけ) =====
        float moonIntensity = 1f - sunIntensity;
        moonLight.intensity = moonIntensity * moonMaxIntensity;

        // ===== 環境光 =====
        RenderSettings.ambientIntensity =
            Mathf.Lerp(nightAmbient, dayAmbient, sunIntensity);
    }
}

月のディレクショナルライトを追加して青っぽくする

色は #AFCBFF くらいの薄い青で影なしにする。

これで良くなった!

おお、これで夜も昼も実装できましたね(*^_^*)

月はスカイボックスに描くか、丸いオブジェクトをEmissionで発光させるしかないっぽい?

しかしディレクショナルライトだけで表現する場合、夜は暗くすることで表現しているから、月自体は見えないっぽい。

なぜなら明るくすると昼になってしまい太陽のディレクショナルライトと同じになってしまうから。

ChatGPT氏に聞いてみたけどスカイボックスに描くか、丸いオブジェクトをEmissionで発光させる感じかな…。

Unity 太陽作り方 昼夜サイクル ゲーム内時間
Unity 太陽作り方 昼夜サイクル ゲーム内時間

方法Aでやってみたけど、月の位置がおかしくなってハマった(^_^;)

まぁとりあえずここまでできたから後でやるか…。

おわりに

案外手軽に実装できて良かった。

空の表現は雲とかも配置したいし、その時に月なども配置してみたいかな?

また何かあれば追記します(*^_^*)

タイトルとURLをコピーしました