LoginSignup
0
2

More than 3 years have passed since last update.

【Unity】楽曲に合わせて〇〇するスクリプト

Posted at

こんにちはっ🌟八ツ橋まろんです

個人バーチャルYouTuberとして、UnityのTimeline機能を使って、3Dモデルを使ったオリジナルのミュージックビデオを制作しています。

楽曲のリズムに合わせてパーティクルを出したり演出を入れたりしているのですが、Timelineの時間軸はフレーム単位(60フレーム/秒)なので、「100bpmの楽曲だから60/100 = 0.6秒 = 36フレームごとにパーティクルをEnableにして、、、」とか、「155bpmだと割り切れないから〇回に1回だけ1フレーム減らして、、、」なんて作業は、正直しんどいのでやっていられません。

なので、『最初の1回だけ指定したら残りは同じ時間サイクルで動作をしてくれるスクリプト』を書きました🌟(小難しくない簡単なスクリプトです)

使用例:一定間隔でハートが鼓動を打つ
qiia.gif

BpmAction.cs
using System.Collections;
using UnityEngine;


public class BpmAction : MonoBehaviour
{
    public int bpm;

    enum Coef
    {
        quarter,
        half,
        x1,
        x2
    }

    [SerializeField]
    Coef coef;

    [Header("Events")]
    public OnBPM onBPM;

    float BpmCoef()
    {
        switch (coef)
        {
            case Coef.quarter:
                return 0.25f;
            case Coef.half:
                return 0.5f;
            case Coef.x1:
                return 1f;
            case Coef.x2:
                return 2f;
        }
        return 1f;
    }

    [SerializeField]
    bool IsBpmAction;
    float time;

    private void Update()
    {
        if (IsBpmAction)
        {
            time += Time.deltaTime;
            if(time >= 60f / (bpm * BpmCoef()))
            {
                time -= 60f / (bpm * BpmCoef());
                Action();
            }
        }
    }

    void Action()
    {
        onBPM.Invoke();
    }
    [System.Serializable]
    public class OnBPM : UnityEngine.Events.UnityEvent
    {

    }
    public void BpmActionStart()
    {
        IsBpmAction = true;
        Action();
    }
    public void BpmActionStop()
    {
        IsBpmAction = false;
        time = 0;
    }
    public void SetNewBpm(int i)
    {
        BpmActionStop();
        bpm = i;
    }
}

【ポイント】
以下の記述によって、uGUIのボタンのように、イベント登録ができるのでとっても便利です。覚えておきましょう。私も今回初めて知りました。(下の画像の赤枠部分が追加される)

冒頭のハートの例では、ハートのAnimatorにSetTrigger("Beat")をして鼓動させています。

    [Header("Events")]
    public OnBPM onBPM;

    [System.Serializable]
    public class OnBPM : UnityEngine.Events.UnityEvent
    {

    }

無題 (復元済み).png

また、時間の計測は、コルーチンを使わず、Update関数内でTime.deltatimeを毎フレーム足しています。

通常、〇〇時間後に起動する処理ではコルーチンをよく使いますが、更新はフレーム毎にしか行われないので、例えば「1.00秒の設定に対して1.01秒経った→1.00秒を越えているのでカウントを0にする」という処理では、毎回0.01秒遅いアクションになり、積もり積もって時間差が目立ってしまいます。そのため、「Updateで毎回Time.deltatimeを足す→1.01秒になったのでカウントを1.00秒引いて0.01秒から再スタート」とすることで正確な時間計測をしています。
(コルーチンでのやり方あったら教えてほしいです。よくわからんかった。)

【使い方】
・BPMに楽曲のBPMを入れてください。

・Unity2019以降:Timeline上にSignal Trackを追加し、最初の1回目の位置にSignalを置いてBpmActionStart()関数を呼んでやればOKです💡終わるときはBpmActionStop()関数を呼んでください。

・Unity2018以前:TimelineにSignal機能がないため、追加でAnimatorを付けて、TimelineにAnimation Trackを追加して、IsBpmActionをtrueにすればOKです💡終わるときはfalseにしてください。

・Coefは係数です。x1で毎ビート毎に、x2で2倍、halfで2回に1回、quarterで4回に1回です。

以上、「楽曲に合わせて〇〇するスクリプト」でしたっ🌟またね

八ツ橋まろん

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2