0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

VRCでオーディオビジュアライザー的なのを作りたい人へ

Posted at

Udonsharpを使って音源の波形を取得して、ゲーム内の物体に反映させてみよう

正直初回のやつは簡単すぎたと思います。そして味気なさすぎたと思います。
なので今回は簡易的でもいいので実際にオーディオビジュアライザーを作ってみましょう!

ここから完全にC#が絡んできます。
ただ、すべてのスクリプトはほぼコピペで完結させます。
なのでC#ができない方も諦めずにがんばってください。

Q.そもそもUdonって?

A.VRCでもなんか複雑なことができるようになるやつ

以上。それくらいの認識でいいです。
筆者はUdonsharpしか触ってないのでUdonとかよくわかりません。

1.VisualStudioの導入

ここからDLして導入してください。
メモ帳などでもコーディングはできなくはないですが、VisualStudioのほうが効率はいいです。
Visual studio Communityは個人で使用する場合は無料なので、こちらを使用しましょう。
30日使用後にサインインが必要になるので、アカウント登録したくない人はメモ帳アプリで頑張りましょう。
※※そもそも全部コピペでいいよって人はここから先のコーディングも全てメモ帳で完結します。

C#.PNG
Visual studioをインストールする際は赤枠の場所にチェックを入れてインストールしてください。

2.Udonsharpのダウンロード

以下のページよりダウンロードを行ってください。

aaa.png
2022/06現在、赤枠の位置で最新版のページに飛べます。

aaasa.png
クリック後に画像のようなページへと遷移するので、赤枠のunitypackageをダウンロードしてください。

3.音源のダウンロード

今回は 魔王魂 様のシャイニングスターを使用させてもらいます。

形式は今回はMP3を使用します
これでファイルの準備は完了です。

4.プロジェクトへの音源をインポートと音源の設置

プロジェクトは前回作成したものを使いましょう。
前回の記事を見てない方はとりあえずPlane1枚とVRCWorldがHierarchyに入っているプロジェクトを作ったらOKです。
aaasa.png
プロジェクトを開いたら、このあたりにドラッグ&ドロップします。
ファイルが増えてきたらフォルダで整理したほうがいいですが、それはもっと凝ったワールドを作るときでいいです。

image.png
こんな感じの表示になったらOKです。

次は音源を再生できるようにします。
hoga.png
Hierarchy(左のウィンドウのPlaneのすぐ下辺り)を右クリックして、Audio→Audio Sourceを選択してください。
hoga1.png
AudioSourceがHierarchy上に作成できたら、画像のような画面になると思います。
なっていない人はHierarchy上のAudio Sourceをクリックして選択状態にして、右側ウィンドウの左上の赤枠部分「Inspector」をクリックしてこの画面を表示してください。
ここまでできたら、先程インポートした音源(シャイニングスター)をAudio sourceオブジェクトのAudio sourceコンポーネント(Inspectorのウィンドウに表示されている場所)のAudioClip欄にドラッグ&ドロップしてください。
用語が増えてきたのでちょっとややこしくなりますが、赤枠で囲んだ部分を赤枠で囲んだ場所に入れればいいです。
hoga2.png
この状態になったらOKです。
画面中央上部の再生ボタンみたいなやつをクリックして再生したときに、曲が再生されたらここまでの作業は完了です!

5.オブジェクトを配置する

オブジェクトは「もの」って言い換えてもらって大丈夫です。

※今回はハードコーディング(作るのは楽だけど修正がめんどくさい方法)で一旦実装します。
汎用性を持たせるのは次回以降にしておきます(説明とかが長くなるので)。
hoga3.png

Hierarchy上で右クリック→3D Object→Cubeを選択してください。
hoga4.png
Cubeが作成できたら、図のようにInspector上のtransformの数値を設定してください。
オブジェクトの名前を「Cube1」
Positionの数値をx→5,y→0,z→-5.5
Scaleの数値をx→0.5,y=1,z=0.5
これを複製して8個分作ります。
hoga5.png
Hierarchy上のCube1にカーソルを合わせて、キーボードのCtrlを押しながらDボタンを押すと、選択したオブジェクトが複製されます。
image.png
(1)と名前の付いたオブジェクトができていれば成功です。
hoga6.png
複製したオブジェクトを横に等間隔に並べていきたいので、
複製したオブジェクトの名前を「Cube2」
Inspector上のtransformのxの値を4にしてください。
これを繰り返して、Cube1-Cube8を作成してください。
それぞれのCubeのInspector上のtransformのxの値が5,4,3,2,1,0,-1,-2になっていればOKです。
このとき、下の画像のように等間隔に並んだ白い柱ができているはずです。
image.png
音源の音の波形でこの柱の形が変化するようにします。

6.Udonsharpを使ってオブジェクトの操作を行う

まだUdonsharpをimportしてなかったのでimportしましょう。
importの方法忘れた人は前回の記事を参考にしてください。
hoga7 (3).png
Udonsharpのimportが終わったら、赤枠あたりの位置で右クリック→Create→U# Scriptを選択してください。
image.png
なんかウィンドウが出るので名前を「AudioVisualizer」と入力して「保存」を押してください。
ここで決めた名前は途中で変えないほうがいいです。
hoga9.png
保存を押して少しすると赤枠の位置に白い英文が表示されます。赤文字でなにか表示されているうちは操作しないでください。
hoga10.png
白い英文が表示されたら、赤枠のファイル「AudioVisualizer.cs」をメモ帳なりVisualStudioなりで開いてください。
hoga11.png
開いたらこんな画面になると思います。初期設定は見づらいので左下の倍率を200%位にしておきましょう。

この記事を参考にしてコーディングをしていきましょう。

using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class AudioVisualizer : UdonSharpBehaviour
{
    public GameObject cube1;
    public GameObject cube2;
    public GameObject cube3;
    public GameObject cube4;
    public GameObject cube5;
    public GameObject cube6;
    public GameObject cube7;
    public GameObject cube8;

    public GameObject audioObj;
    private AudioSource audios; 
    private float[] waveData_;
    private float[] size;
    private int num;

    void Start()
    {
        audios = audioObj.GetComponent<AudioSource>();
        waveData_ = new float[128];
        size = new float[8];
        num = waveData_.Length / size.Length;
    }
    void Update()
    {
        audios.GetOutputData(waveData_,1);
        for(int h = 0; h < size.Length; h++)
        {
            size[h] = 0f;
        }

        for (int i = 0; i < waveData_.Length; i++)
        {
            int index = (int)(i / num);
            size[index] += waveData_[i];
        }

        cube1.transform.localScale = new Vector3(0.5f, size[0],0.5f);
        cube2.transform.localScale = new Vector3(0.5f, size[1],0.5f);
        cube3.transform.localScale = new Vector3(0.5f, size[2],0.5f);
        cube4.transform.localScale = new Vector3(0.5f, size[3],0.5f);
        cube5.transform.localScale = new Vector3(0.5f, size[4],0.5f);
        cube6.transform.localScale = new Vector3(0.5f, size[5],0.5f);
        cube7.transform.localScale = new Vector3(0.5f, size[6],0.5f);
        cube8.transform.localScale = new Vector3(0.5f, size[7],0.5f);
    }
}

とても汚いコードですが、今回は動かすことを優先にします。
説明も後回しにします。
これをそのままコピペして先程のAudioVisualizer.csファイルに貼り付けてください。
貼り付けたら保存してください。
ここまで終わったら、Unityの方に戻ります。
hoga12.png
コードが間違っているとここに赤色でエラーメッセージが出ます。
今回はコピペなので出ないはずです。このように白色のメッセージが出ていれば現状は問題ありません。
hoga13.png
先程作成したAudioSourceを選択して、右側のInspector欄の一番下の「Add Component」を選択してください。
hoga14.png
出てきた検索欄にudonって打ち込むとなんか出るので、Udon Behaviourを選択しましょう。
hoga15.png
AudioSourceのInspector欄になんか増えるので、先程作成したスクリプト(末尾がCSじゃない方)をProgram Sourceの欄にドラッグ&ドロップしてください。
使うのはU#マークのついてる、末尾がAssetの方です。#マークの方ではありません。
そもそも#マークの方は入れようとしても入らないんですけどね。
hoga16.png
そうするとこんな感じになって、なんか欄が増えます。
hoga17.png
左側のHierarchyウィンドウにあるやつと名前を対応させてあるので、Hierarchyウィンドウにあるやつをドラッグ&ドロップして1個ずつ入れていきましょう。
HierarchyウィンドウにあるCube1を、右側のAudioSourceのInspectorのUdonBehabiour欄の「Cube1」の欄にドラッグ&ドロップすればいいです。Cube2-8も同様に同じ名前のところに入れていきましょう。AudioObjの欄にはAudio Sourceをドラッグ&ドロップすればOKです。

ここまで終わったら、ウィンドウ中央上部の再生ボタンを押してみましょう。
image.png
曲に合わせて白い柱のサイズが変わっていればOKです!

おつかれさまでした!これで連動は完了です!

ps.コード部分についての説明

public GameObject cube1;
public GameObject cube2;
public GameObject cube3;
public GameObject cube4;
public GameObject cube5;
public GameObject cube6;
public GameObject cube7;
public GameObject cube8;

public GameObject audioObj;
private AudioSource audios; 
private float[] waveData_;
private float[] size;
private int num;

コーディングするとき、なにを使うかまず「宣言」する必要があります。
「これからこれらを使います」という意味です。
アクセス範囲、型、名前 の順で記載します。
誰が使えて、何を入れられる、◯◯という名前の付いた箱というイメージです。
[]が型の後ろについているものは配列です。2個以上のオブジェクトを入れることができます。
Unityで使う場合、publicだとUnityの上で書き換えたりすることができます。
privateだとUnity上では基本的に確認できません。
必要に応じて使い分けましょう。詳しくは次回以降で。

void Start()
{
    audios = audioObj.GetComponent<AudioSource>();
    waveData_ = new float[128];
    size = new float[8];
    num = waveData_.Length / size.Length;
}

宣言をした際に箱を作ったので、箱の中身を入れましょう。
もしくは、配列の場合は箱のサイズを決めましょう。
public型は中身を入れなくてもUnity上で入れる場合もあるのでエラーになりませんが、
private型は中身を入れないとエラーになります。

void Update()
{
    audios.GetOutputData(waveData_,1);
    for(int h = 0; h < size.Length; h++)
    {
        size[h] = 0f;
    }

    for (int i = 0; i < waveData_.Length; i++)
    {
        int index = (int)(i / num);
        size[index] += waveData_[i];
    }

    cube1.transform.localScale = new Vector3(0.5f, size[0],0.5f);
    cube2.transform.localScale = new Vector3(0.5f, size[1],0.5f);
    cube3.transform.localScale = new Vector3(0.5f, size[2],0.5f);
    cube4.transform.localScale = new Vector3(0.5f, size[3],0.5f);
    cube5.transform.localScale = new Vector3(0.5f, size[4],0.5f);
    cube6.transform.localScale = new Vector3(0.5f, size[5],0.5f);
    cube7.transform.localScale = new Vector3(0.5f, size[6],0.5f);
    cube8.transform.localScale = new Vector3(0.5f, size[7],0.5f);
}

ここで行っているのは
1.audiosという名前のオブジェクトから、waveData_という名前の配列に波形データを入れる
2.sizeという配列の中身をすべて0にする
3.sizeという配列の1番目にはwaveData_の1番目から16番目までのデータの合計を、
2番目には17番目から32番目のデータの合計を・・・という風に16個ずつデータを足したものをsizeという配列の中身に入れる
4.size配列の1-8の値を、cube1-8の高さに設定する
ということを処理しています。

今回はかなり雑に、動けばいいという前提でコードを書いてます。

次回はどのような動作をさせたいか文章にまとめてから、コーディングをしてみましょう。

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?