うら干物書き

ゲームを作りたい!

【Unity】霧のかかった人生とFog

 気が付けば2017年が終わっていました。
 2018年は明るい年にしたいものです。
 ですが年が明けたところで、僕の人生はがかかったかのように見通しがよくありません。
 これはよくありません。
 この霧を何とかするためには、UnityのFogを扱えるようになる必要があります。
 なぜですかって?

 昔の偉い人はこう言ったものです。
 人生で起こることは、すべて、プログラムの上でも起こる と。


この記事にはUnity2017.3.0f3を使用しています。

先人の知恵を拝借する

 UnityにおけるFogは今まで僕は使ったことはないけれど、別に目新しい機能でもないですし、誰かしらが記事に纏めてくれているに違いない!
 それを見ながら勉強すれば、ちょちょいのちょいで霧を扱えるようになるはずだ!
 さあ、ググって偉大なる先人の方々の知識をお借りしましょう。

f:id:urahimono:20180101154521p:plain

 ……。
 なんか書いてることが各自でちょっとずつ違うんだけど……。
 そういえば、近所の噂でUnityのバージョンによってFogの設定方法が違うとかなんとか聞いたことがあるなぁ。
 確かに各記事の日付は結構バラバラだ。
 むむむ、どの記事を見ていけばいいのだろうか。

 日付的に新しそうな、かめくめ先生の記事を参考にさせてもらおう。
gametukurikata.com

 ふむふむ、なるほど。
 Lighting ウインドウから設定ができるようですな。
docs.unity3d.com

 とりあえずFogがどれぐらいの距離にかかっているかを判断できるシーンを作ってみたよ。
f:id:urahimono:20180101154538p:plain

 このシーンにFogをかけていきましょう。

 えーと、Fogのかけ方にはいろいろあるみたいですな。
 試してみます。

Linear

フォグの密度は距離に応じて直線的に増加します。

 設定する値がわかりやすそうなモードですね。
 いろいろ試してみましょう。

0 ~ 50
f:id:urahimono:20180101154558p:plain

25 ~ 50
f:id:urahimono:20180101154617p:plain

49 ~ 50
f:id:urahimono:20180101154628p:plain

0 ~ 25
f:id:urahimono:20180101154640p:plain

0 ~ 0.1
f:id:urahimono:20180101154653p:plain

Expenetial

フォグの密度は距離に応じて指数関数的に増加します。

 出たよ指数……。
 よくわからんのだよ指数。
 いや、数学の授業で指数の内容があったことは聞いているんだよ。
 ただ、ちょうどたまたま指数の授業のときに限って、道に困っている妊婦さんを見かけてしまうんだ。
 若いころの僕は困っている人を見かけたら、手を差し伸べてしまうんだよ。
 そう、僕は数学より人助けを優先する騎士道精神溢れる人物だから、指数がわからないのは仕方のないことなんだよ。

 というわけで指数はよくわからんけど、適当に値を設定してみてどう変化するのかみてみよう。
 設定できる値は0~1までみたいだね。

0
f:id:urahimono:20180101154722p:plain

0.1
f:id:urahimono:20180101154733p:plain

0.2
f:id:urahimono:20180101154749p:plain

0.5
f:id:urahimono:20180101154758p:plain

・Expenetial Squared

フォグの密度は、距離に応じた指数関数的な増加よりもより速く増加します。

 もう一度言うが、僕は指数がわからん。
 さっき話した通り、指数の授業の時に限って僕の左手に封印した鬼の力が暴走し始め、封印の術式を組みなおさなきゃいけなかったんだ。
 鬼の力が暴走してしまえば、世界は滅亡の危機に瀕してしまう。
 とても数学の授業を受けている余裕はなかったから、指数がわからないのは仕方のないことなんだよ。

 というわけで、同じ値を設定したときのExpenetialExpenetial Squaredの違いだけを見ていこう。

0.1
f:id:urahimono:20180101154830p:plain

0.2
f:id:urahimono:20180101154843p:plain

スクリプトでも霧を制御する

 エディタ上でFogを設定するやり方は、かめくめ先生のおかげで出来るようになったぞ!
 ただ、スクリプトからFogの設定はできないものだろうか。
 調べたところ、RenderSettingsクラスのプロパティをいじることでスクリプトから設定できそうだ。

docs.unity3d.com

 Fogに関係するプロパティとエディタ上のパラメータの関係は以下の通りだ。

  • RenderSettings.fog
  • RenderSettings.fogColor
  • RenderSettings.fogMode
  • RenderSettings.fogStartDistance
  • RenderSettings.fogEndDistance
  • RenderSettings.fogDensity

f:id:urahimono:20180101154913p:plain

マルチシーン時にはどうなるの

 Fogを扱っていくうえで気になることが出てきた。
 このFogの設定は、ライトマップなどと同様、シーンに紐づいていそうだ。
 ということは、マルチシーン時はどうなるのだろうか。

 先ほどまで使っていたScene Aとは別に、シーン上にはなにもなくFogの設定だけをしたScene Bを用意してみた。
f:id:urahimono:20180101154929p:plain

 この二つシーンをHierarchy上に配置してみよう。
f:id:urahimono:20180101154944p:plain

 見る限りアクティブなシーンのFog設定をみているような気がする。
 以下のスクリプトを使って、アクティブなシーンが切り替わるようにして挙動を確認してみよう。

GameController.cs

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Collections;

public class GameController : MonoBehaviour
{
    [SerializeField]
    private Text    m_textUI = null;


    private IEnumerator Start()
    {
        int sceneIndex = 0;

        while( true )
        {
            yield return new WaitForSeconds( 1.0f );

            sceneIndex = ( sceneIndex + 1 ) % SceneManager.sceneCount;

            var scene  = SceneManager.GetSceneAt( sceneIndex );
            SceneManager.SetActiveScene( scene );
            m_textUI.text   = scene.name;
        }
    }

} // class GameController

f:id:urahimono:20180101155015g:plain

 アクティブなシーンが切り替わるたびに、Fogの設定が切り替わっていることが確認できる。

昔はあったけど今はないもの

 Fogがだいぶ扱えるようになってきた気がする。
 かめくめ先生の記事には、Global Fogというものの説明も書いてあった。
 それも使ってみたい。

 えーと、どうやらStandardAssetsをインポートする必要があるようだ。
 早速試してみよう。

f:id:urahimono:20180101155032p:plain

 Global Fogのファイルがなさそうなんだけど。
 むむむ、どういうことだ。
 ドキュメントみてみよう。

f:id:urahimono:20180101155056p:plain

 Unity5時代のドキュメントにはGlobal Fogの記事があるが、Unity2017にはない!
 最新の英語版のドキュメントを見てもなさそうだ。

 なんということだ、僕ではグローバルな人物にはなれないというのか……。
 今年も波瀾万丈な都市になりそうだ。