本日はMRDLのSurfacesを勉強していきます。
前回は[HandMenu]とシーンの遷移の仕組みを見ていきました。
今回はHandMenu内の[ShaderTimeUpdater]オブジェクトを見ていきます。
〇ShaderTimeUpdater
‘‘‘ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information.
using UnityEngine;
namespace Microsoft.MRDL { [ExecuteInEditMode] public class ShaderTimeUpdater : MonoBehaviour { private void Update() { unloopedTime += Time.deltaTime;
if (unloopedTime >= repeatInterval)
{
loopedTime = Mathf.Repeat(unloopedTime, repeatInterval);
float blendAmount = repeatBlendCurve.Evaluate((unloopedTime - repeatInterval) / repeatBlendTime);
if (blendAmount >= 1)
{
unloopedTime = 0;
}
noiseTime = Mathf.Lerp(unloopedTime, loopedTime, blendAmount);
}
else
{
noiseTime = unloopedTime;
}
noiseTime = Mathf.Repeat(noiseTime, repeatInterval);
Shader.SetGlobalFloat("_NoiseTime", noiseTime);
}
[SerializeField]
private float repeatInterval = 600f;
[SerializeField]
private float repeatBlendTime = 20f;
[SerializeField]
private AnimationCurve repeatBlendCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f);
private float unloopedTime;
private float loopedTime;
private float noiseTime;
}
} ‘‘‘
[ShaderTimeUpdater]コンポーネントは[ExecuteInEditMode]の属性によってEditor上でUpdate関数が実行されます。
unloopedTime += Time.deltaTime; if (unloopedTime >= repeatInterval) { loopedTime = Mathf.Repeat(unloopedTime, repeatInterval); float blendAmount = repeatBlendCurve.Evaluate((unloopedTime - repeatInterval) / repeatBlendTime); if (blendAmount >= 1) { unloopedTime = 0; } noiseTime = Mathf.Lerp(unloopedTime, loopedTime, blendAmount); } else { noiseTime = unloopedTime; } noiseTime = Mathf.Repeat(noiseTime, repeatInterval); Shader.SetGlobalFloat("_NoiseTime", noiseTime);
Update関数内ではUnityEditor上の時間経過を取得しており、If分によりデフォルト値で600の[repeatInterval]が経過した場合とそうではない場合で処理が分けられています。
そうではない場合は[noiseTime]がそのまま経過時間になります。
loopedTime = Mathf.Repeat(unloopedTime, repeatInterval); float blendAmount = repeatBlendCurve.Evaluate((unloopedTime - repeatInterval) / repeatBlendTime); if (blendAmount >= 1) { unloopedTime = 0; } noiseTime = Mathf.Lerp(unloopedTime, loopedTime, blendAmount);
時間が経過した場合、 loopedTime つまりif文の中は600秒経過後に処理が走ります。
loopedTime = Mathf.Repeat(unloopedTime, repeatInterval);
Mathf.Repeat(time t , float f);
はtがfになるとその間をループする関数です。
[blendAmount]はアタッチされている[animationCurve]の[repeatBlendCurve]に設定されているunloopedTime(経過時間) - repeatInterval(リピート時間(600))=つまりループ後の経過時間の横軸から縦軸が返されます。
if (blendAmount >= 1) { unloopedTime = 0; }
この値が1より大きい場合 つまりデフォルト値の場合1200秒より大きい場合unloopedTimeは一度0に戻されます。
ここまでは時間経過によるループの処理でした。
noiseTime = Mathf.Lerp(unloopedTime, loopedTime, blendAmount);
最後に[noiseTime]にunloopedtime、loopedTime,blendAmountによる値が入ります。
これはデフォルトの場合600から0に下がっていく値を示します。
Shader.SetGlobalFloat("_NoiseTime", noiseTime);
最後に[Shader.SetGlobalFloat()]ですべてのShaderに対して[_NoiseTime]の変数にnoiseTimeを代入しています。
今後このShaderも中身を見ながらnoiseTimeのやっていることを見ていきます。