ふとUnityでオブジェクトをランダムかつ滑らかに回転させたくなったのでやってみました。
#概要
こんな感じでランダムかつ滑らかにオブジェクトを回転させます。
シンプレックスノイズを使って実現していきます。
#実装
using UnityEngine;
using Unity.Mathematics;
using static Unity.Mathematics.math;
public class SimplexNoiseRotation : MonoBehaviour
{
[SerializeField] float speed;
float speedOffset;
void Start()
{
speedOffset = UnityEngine.Random.Range(0f, 1000f);
SetRotation();
}
void Update()
{
speedOffset += speed * Time.deltaTime;
SetRotation();
}
void SetRotation()
{
Transform trans = this.gameObject.transform;
float x = noise.snoise(float2(0f, speedOffset));
float y = noise.snoise(float2(64f, speedOffset));
float z = noise.snoise(float2(128f, speedOffset));
float w = noise.snoise(float2(192f, speedOffset));
trans.rotation = new Quaternion(x, y, z, w);
}
}
ランダムかつ滑らかに回転させるには、時間に対して滑らかに変化する乱数が必要です。そのような乱数にはパーリンノイズやシンプレックスノイズがありますが、ここではより高性能(らしい)シンプレックスノイズの方を使っていきます。Unityにはシンプレックスノイズが既に実装されており、Unity.Mathematics.noise.snoiseから利用できます。noise.snoiseはstruct float2、struct float3、struct float4のいずれも引数に取ることができます。またこの記事によるとnoise.snoiseの返り値は-1.0から1.0の間です。
そしてシンプレックスノイズをどのように回転に反映させるかが重要ですが、ここでは単純にtransform.rotationの各成分にnoise.snoiseの値を代入しています。noise.snoiseの引数をわずかに変更してやればnoise.snoiseは滑らかに変化するので、transform.rotationも滑らかに変化します。noise.snoiseの第一引数の値はとりあえず異なる値を適当に入れています。