環境
- Unity5.5
- DOTween
最近そういう処理が必要になったので調べてみたら、そんなに難しくなかったので書きました。
skybox対応の背景を切り替えるシェーダーを書きました pic.twitter.com/7EASBkudVN
— UKS*KUZ (@superDebu12) 2017年4月6日
Shader側のPropertyには
- skyboxに必要な各方向のTexture6枚を2パターン
- ブレンド値 : _blend
を定義します。
_blendの値を見てTextureをガッチャンコさせます。
BlendSkybox.shader
Shader "Skybox/Blend" {
Properties {
_Tint ("Tint Color", Color) = (.5, .5, .5, .5)
_Blend ("Blend", Range(0.0,1.0)) = 0.5
_FrontTex ("Front (+Z)", 2D) = "white" {}
_BackTex ("Back (-Z)", 2D) = "white" {}
_LeftTex ("Left (+X)", 2D) = "white" {}
_RightTex ("Right (-X)", 2D) = "white" {}
_UpTex ("Up (+Y)", 2D) = "white" {}
_DownTex ("Down (-Y)", 2D) = "white" {}
_FrontTex2("2 Front (+Z)", 2D) = "white" {}
_BackTex2("2 Back (-Z)", 2D) = "white" {}
_LeftTex2("2 Left (+X)", 2D) = "white" {}
_RightTex2("2 Right (-X)", 2D) = "white" {}
_UpTex2("2 Up (+Y)", 2D) = "white" {}
_DownTex2("2 Down (-Y)", 2D) = "white" {}
}
SubShader {
Tags { "Queue" = "Background" }
Cull Off
Fog { Mode Off }
Lighting Off
Color [_Tint]
Pass {
SetTexture [_FrontTex] { combine texture }
SetTexture [_FrontTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
}
Pass {
SetTexture [_BackTex] { combine texture }
SetTexture [_BackTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
}
Pass {
SetTexture [_LeftTex] { combine texture }
SetTexture [_LeftTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
}
Pass {
SetTexture [_RightTex] { combine texture }
SetTexture [_RightTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
}
Pass {
SetTexture [_UpTex] { combine texture }
SetTexture [_UpTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
}
Pass {
SetTexture [_DownTex] { combine texture }
SetTexture [_DownTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
}
}
Fallback "Skybox/6 Sided", 1
}
# Script側
Script側では_blendの値をDoTweenで動かしてます。
CustomSkyBox.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class CustomSkyBox : MonoBehaviour {
[SerializeField]
private Light directionalLight;
[SerializeField]
private Material material;
private bool isBlendComplete;
private float _blend;
[SerializeField]
private float blendDuration;
void Awake()
{
_blend = 0.0f;
directionalLight.intensity = 0.0f;
}
void Start()
{
StartCoroutine (gameLogic());
}
IEnumerator gameLogic()
{
bool toggle = true;
while (true) {
yield return new WaitForSeconds (5.0f);
yield return StartCoroutine(CO_BlendSkyBoxTexture (toggle));
toggle = !toggle;
}
}
public IEnumerator CO_BlendSkyBoxTexture(bool toggle)
{
isBlendComplete = true;
float startValue = toggle ? 0.0f : 1.0f;
float endValue = toggle ? 1.0f : 0.0f;
DOTween.To (blend => _blend = blend, startValue, endValue, blendDuration)
.OnComplete (() => {
isBlendComplete = false;
});
yield return new WaitWhile (() => isBlendComplete == true);
}
void Update()
{
UpdateMaterial ();
}
void UpdateMaterial()
{
directionalLight.intensity = (1.0f - _blend) * 8.0f;
material.SetFloat ("_Blend", _blend);
}
}
すごい適当な解説
skyboxはmaterialに設定された6つのTextureを見て背景に描画してるっぽい(詳しいことは調べてない)ので、そのTextureに対して遷移先のTextureをブレンドしてやれば実装出来た。