Help us understand the problem. What is going on with this article?

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

  
  
  
この記事は

『プログラミング完全未経験から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上手いことしてなんとかならないんでしょうか。
誰かやってみてください。私はやりません。

OKsaiyowa
備忘録として学んだことを記録します。 あやふやな箇所が多いですが、そんなときはビシッと指摘いただけますと幸いです。
https://www.wantedly.com/users/98233916
unity-game-dev-guild
趣味・仕事問わずUnityでゲームを作っている開発者のみで構成されるオンラインコミュニティです。Unityでゲームを開発・運用するにあたって必要なあらゆる知見を共有することを目的とします。
https://unity-game-dev-guild.github.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした