LoginSignup
9
11

More than 3 years have passed since last update.

【Unity(C#)】Skyboxをスクリプトで操作(切り替え、回転)する方法

Last updated at Posted at 2019-03-03

  
  
  
この記事は

『プログラミング完全未経験からUnityでの開発現場に迎え入れてもらえた世界一の幸せ者』

の記事です。そのつもりでお読みください。

スクリプトでSkyboxを切り替える

今回使わせていただいたフリーアセット→お気に入りです!いつもお世話になってます!

public Material sky;

//切り替えたいタイミングでこれを書く
RenderSettings.skybox = sky;

はい、これだけらしいです。

やっていることとしては、Lighting Settings
LightingWindow.png
Skybox Materialを変更しているだけです。
SkyboxMaterial.png

実際にテストしてみます。

public Material sky;

    void Update()
    {
        //キー押してない間はreturn
        if (Input.anyKey == false)
        {
            return;
        }


        //テスト用 Change
        if (Input.GetKeyDown(KeyCode.C))
        {
            //切り替えたいタイミングでこれを書く
            RenderSettings.skybox = sky;
        }
    }

GifCapture-201903021531068329.gif

いけました。

Skyboxを回転させる

SkyboxRotationDattime.png
Materiaを見るとRotationという項目があるのでそこをスクリプトでいじるだけです。

    //回転スピード
    [Range(0.01f,0.1f)]
    public float rotateSpeed;

    public Material sky;

    float rotationRepeatValue;

    void Update()
    {

        rotationRepeatValue = Mathf.Repeat(sky.GetFloat("_Rotation") + rotateSpeed , 360f);

        sky.SetFloat("_Rotation",rotationRepeatValue);

        //キー押してない間はreturn
        if (Input.anyKey == false)
        {
            return;
        }


        //テスト用 Change
        if (Input.GetKeyDown(KeyCode.C))
        {
            //切り替えたいタイミングでこれを書く
            RenderSettings.skybox = sky;
        }
    }

Mathf.Repeat

Mathf.Repeatは第一引数と第二引数の剰余(割った余り)を返します。
なのでMathf.Repeat(sky.GetFloat("_Rotation") + rotateSpeed , 360f)
仮にsky.GetFloat("_Rotation")は0rotateSpeedは0.1とすると

1フレーム目 → 0.1 % 360 → 0.1
2フレーム目 → 0.2 % 360 → 0.2
3フレーム目 → 0.3 % 360 → 0.3
      ・
      ・
      ・
3599フレーム目 → 359.9 % 360 → 359.9
3600フレーム目 → 360.0 % 360 → 0
3600フレーム目 → 360.1 % 360 → 0.1
      ・
      ・
      ・

みたいな感じで永遠に繰り返してくれます。
GifCapture-201903031705189567.gif

回転の方向を変えたい

今はY軸を中心に回転しているので、真上の雲にあまり動きはないです。
GifCapture-201903031709247690.gif
この画像は動きがわかり易いように大げさに動かしていますので、
もう少しゆっくりな回転速度に調節すればそこまで違和感を感じることはないです。

しかし、回転の方向を変えてあげれば本来の雲の流れが再現できるのでは?と思い試してみました。

ビルトインシェーダー

Unityには組み込み済みのシェーダが山ほどあります。
今回利用したSkyboxにもそのうちの1つが使われています。

ですが、それを利用するにはビルトインシェーダーというものを使用しなければなりません。

自分の使用しているUnityのバージョンに対応しているビルトインシェーダーをダウンロードします。
ビルトインシェーダー.png

Zipを解凍して
DefaultResourcesExtraSkybox-Cubed.shader
を開きます。

既存のShaderと表示名が被るので
変更します。

回転について書かれた部分も変えてプロジェクトに保存します。

//ここを変更↓
Shader "Skybox/MyCubeMap" {
Properties {
    _Tint ("Tint Color", Color) = (.5, .5, .5, .5)
    [Gamma] _Exposure ("Exposure", Range(0, 8)) = 1.0
    _Rotation ("Rotation", Range(0, 360)) = 0
    [NoScaleOffset] _Tex ("Cubemap   (HDR)", Cube) = "grey" {}
}

SubShader {
    Tags { "Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox" }
    Cull Off ZWrite Off

    Pass {

        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #pragma target 2.0

        #include "UnityCG.cginc"

        samplerCUBE _Tex;
        half4 _Tex_HDR;
        half4 _Tint;
        half _Exposure;
        float _Rotation;

        float3 RotateAroundYInDegrees (float3 vertex, float degrees)
        {
            float alpha = degrees * UNITY_PI / 180.0;
            float sina, cosa;
            sincos(alpha, sina, cosa);
            float2x2 m = float2x2(cosa, -sina, sina, cosa);
                                             //ここを変更↓
            return float3(mul(m, vertex.xz), vertex.y).zxy;
        }

        struct appdata_t {
            float4 vertex : POSITION;
            UNITY_VERTEX_INPUT_INSTANCE_ID
        };

        struct v2f {
            float4 vertex : SV_POSITION;
            float3 texcoord : TEXCOORD0;
            UNITY_VERTEX_OUTPUT_STEREO
        };

        v2f vert (appdata_t v)
        {
            v2f o;
            UNITY_SETUP_INSTANCE_ID(v);
            UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
            float3 rotated = RotateAroundYInDegrees(v.vertex, _Rotation);
            o.vertex = UnityObjectToClipPos(rotated);
            o.texcoord = v.vertex.xyz;
            return o;
        }

        fixed4 frag (v2f i) : SV_Target
        {
            half4 tex = texCUBE (_Tex, i.texcoord);
            half3 c = DecodeHDR (tex, _Tex_HDR);
            c = c * _Tint.rgb * unity_ColorSpaceDouble.rgb;
            c *= _Exposure;
            return half4(c, 1);
        }
        ENDCG
    }
}

Mycubemap.png

これで設定完了です。

GifCapture-201903031810402775.gif
うん、まあそうなりますよね。

なんかTexture上手いことしてなんとかならないんでしょうか。
誰かやってみてください。私はやりません。

9
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
11