100日チャレンジ『100日で50弾!』第9回、スウェイショットです。発射した弾をゆらゆら揺らしましょう。パーリンノイズというのがあります(パーリンは考案者の名前)。これを用います。
例えば地形など、急に高くなったり低くなったり、というのはあまりありませんよね。つまりランダムに地形を作るなら、地面の座標が(x, y)のとき、x,yが少しだけ変化したら高さも少しだけ変化して欲しいわけです。普通に乱数を使うと難しそうです。今回の弾の軌道も、直線や放物線など本来の軌道からランダムにゆらゆらさせるとき、揺らす量に単純な乱数は使えません。少し時間が経っただけなら揺らす量も小さくする、これを実現するのがパーリンノイズです。
UnityにMathf.PerlinNoise(x, y)という関数があります。これはランダムな値(0~1)を返します。x, yは単なる引数であって、特に地面の上の座標というわけではありません。このx, yが少し変化すると得られる値(乱数)が少し変化します。xだけ、yだけが変化しても同様です。これを使います。
時刻t = 0で弾を発射し、直線に沿って移動させます。これをランダムにゆらゆらさせるのですが、このときt = 0 での揺れは0でないとおかしいです(発射点ですでに揺れているはずがない)。引数を両方0にしたらどうかな、と見てみると……Mathf.PerlinNoise(0, 0)の値は0ではありませんでした。そこで、次のように工夫します。
float x = Mathf.PerlinNoise(t + 40, 10) - Mathf.PerlinNoise(40, 10);
float y = Mathf.PerlinNoise(10, t + 40) - Mathf.PerlinNoise(10, 40);
「40」、「10」は適当に決めました。これなら t = 0 で値は0になります。ズレの量を上の式で計算し、もとの軌道のx, yに加えればゆらゆらするはずです! なお、弾によって40,10の値は変えないとまるっきり同じに「ランダムに」変化してしまい、面白くありません。弾を生成するたびに単なる乱数で値を決めればOKです。そうして実行した結果が次のgifです。

動画では画面の向こう側がz軸正の向きです。だからz = -vt とすれば弾は画面手前に向かって等速で近づくようになります(vはv = 20など、正の値)。上下左右方向へは上の2本の式を使って本来の軌道からずらせばよいのです。
パーリンノイズは、存在自体は知っていたけれど利用したことはありませんでした。使い方も分かったし、これからはゲーム製作に取り入れます。
では今回はここまで!