オブジェクトを浮遊させるスクリプト

先日のゼミで紹介したゲームUIのアニメーションを設定するために、フワフワと空中を移動するようなアニメーションが設定できるスクリプトを作成しました。卒業制作について、一度もブログで触れていないので紹介します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FloatingMaker : MonoBehaviour
{
    [Header("浮遊オブジェクトの振れ幅、スピード")]
    public float amplitude;
    public float amplitudeR;
    public float speed;

    private Vector3 firstPos;
    private float firstRotateZ;
    private int seedX, seedY, seedR;

    void Start()
    {
        //RandomRangeで指定する値は適当でよい。ただし、seedXとseedYは動きの重複を避けるために別々の値を指定する
        seedX = Random.Range(0, 49);
        seedY = Random.Range(50, 100);
        seedR = Random.Range(0, 100);
        firstPos = transform.position;
        firstRotateZ = transform.rotation.z;
    }

    void Update()
    {
        FloatObject();
    }

    private void FloatObject()
    {
        //PerlinNoiseは0~1の値をとるため、0.5で除算して-0.5~0.5の値をとるようにし、動作の偏りを避ける
        float NoiseValueX = amplitude * (Mathf.PerlinNoise(seedX, Time.time * speed) - 0.5f);
        float NoiseValueY = amplitude * (Mathf.PerlinNoise(Time.time * speed, seedY) - 0.5f);
        float NoiseValueR = amplitudeR * (Mathf.PerlinNoise(Time.time * speed, seedR) - 0.5f);

        transform.position = new Vector2(firstPos.x + NoiseValueX, firstPos.y + NoiseValueY);
        transform.rotation = Quaternion.Euler(0, 0, firstRotateZ + NoiseValueR);
    }
}

使用言語はC#です。上から順番に解説します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

まず、この部分はほとんど関係ありません。Unity側で用意されている最低限の機能を使うためのコードです。

    [Header("浮遊オブジェクトの振れ幅、スピード")]
    public float amplitude;
    public float amplitudeR;
    public float speed;

    private Vector3 firstPos;
    private float firstRotateZ;
    private int seedX, seedY, seedR;

このpublicという部分では、浮遊アニメーションのパラメータ設定を行うために必要な項目を宣言しています。privateの部分はパラメータではなく、機能を実装するために参照しなければならない情報の項目です。

    void Start()
    {
        //RandomRangeで指定する値は適当でよい。ただし、seedXとseedYは動きの重複を避けるために別々の値を指定する
        seedX = Random.Range(0, 49);
        seedY = Random.Range(50, 100);
        seedR = Random.Range(0, 100);
        firstPos = transform.position;
        firstRotateZ = transform.rotation.z;
    }

void Startはカッコ内の命令が一度だけ実行される関数です。この関数を用いて下準備を行います。今回の機能を実装するにあたって、パーリンノイズというシステムを用います。これは、連続性のある乱数をX、Y座標上に生成するシステムです。何を言っているかわからねぇと思った方はリンク先を覗いてみてください。乱数生成の基準となる座標が欲しいので、seedX、seedY、seedRに適当な値を代入しています。この3つの値は被らなければ適当でいいです。firstPosとfirstRotateZには、対象となるオブジェクトの座標情報を代入しています。

    void Update()
    {
        FloatObject();
    }

void Updateではvoid Startと異なり、カッコ内の処理が1フレームに1回呼び出されます。60fpsのパソコンであれば、1秒で60回命令が実行されます。今回はFloatObjectという命令を呼び出しています。そのまんまですね。

    private void FloatObject()
    {
        //PerlinNoiseは0~1の値をとるため、0.5で除算して-0.5~0.5の値をとるようにし、動作の偏りを避ける
        float NoiseValueX = amplitude * (Mathf.PerlinNoise(seedX, Time.time * speed) - 0.5f);
        float NoiseValueY = amplitude * (Mathf.PerlinNoise(Time.time * speed, seedY) - 0.5f);
        float NoiseValueR = amplitudeR * (Mathf.PerlinNoise(Time.time * speed, seedR) - 0.5f);

        transform.position = new Vector2(firstPos.x + NoiseValueX, firstPos.y + NoiseValueY);
        transform.rotation = Quaternion.Euler(0, 0, firstRotateZ + NoiseValueR);
    }

こちらがFloatObjectの中身です。NoiseValueX、NoiseValueY、NoiseValueRにはパーリンノイズで得た値を格納しています。この値は-0.5~0.5の間を、時間経過によって少しずつ変化するようになっています。そして、得た値をオブジェクトの初期座標に足し合わせることで、ランダムかつユラユラとした座標移動と傾きの変更を可能にしています。

プログラミングが苦手な方には何が書いてあるのか分からないかもしれませんが、私も何を書いているのか分からなくなってきました。