見出し画像

BeatSaberのプレイヤーを撮影してる話

はじめまして。ゆずもちと申します。

この度「Beat Saber Advent Calendar 2020」という企画で6日目の記事を書かせていただいております。

今回は「BeatSaberのプレイヤーを撮影する」をテーマにTwitterのまとめ記事になります。

私はエンジョイ勢なのでプレイに関しては完走が目標で、どちらかというと撮り終えた動画を見る方が好きです。
「映像に個性を持たせたい」と思っている方の参考になれば幸いです。

目次

1.きっかけ
2.じゅんび
3.つくる
4.えたもの
5.あとがき

1.きっかけ

私がBeatSaberの動画投稿を始めたころ、国内でもアーケード版の体験会があり話題となっていました。これをアバターを通じて表現できたら面白そう!と始めたのがテーマのきっかけでした。

画像7

2.じゅんび

私が使っているものは以下のとおりです。

・VRMファイル
  現身となるアバターです。私はVRoid Studioをベースに作成しました。

UniVRM
  UnityにVRMファイルをインポートするためのものです。

バーチャルモーションキャプチャー(以下、VMC)
  自身の動きをキャプチャーするものです。
  外部にモーション送信できるバージョンが必要です。

EasyVirtualMotionCaptureForUnity
  Unity上でVMCのモーションを受け取ってアバターを動かすものです。

uWindowCapture
  Unity上にウィンドウの映像を表示するものです。
  BeatSaberの映像を筐体に映すのに使います。

画像3

3.つくる

画像4

(1) Unityプロジェクト作成~VMC連携

公式の取扱説明書をご覧いただければ幸いです(逃
Unity上でアバターが動かせるようになります。


(2) 小道具を配置する

Blenderなどで作成した3Dモデルなどを配置していきます。私は面倒くさがりなのでUnityの3D Objectにテクスチャぺたぺたしてます。

ここに配置したアバターはVMCと同じものを利用することになりますが、Unity上のアバターに物を持たせたりすることは可能です。下の図は手のボーンにお玉を持たせています。振り心地が良いです(謎

画像7


アーケード筐体(のようなもの、わざと似せてない)にモニター用の3D Object(平面でok)を重ねてuWindowCaptureのスクリプトを追加します。これでBeatSaberの画面がUnity上に表示されます。あくまで録画用なのでこの画面を見ながらのプレイは難しいかも。

画像5

サイドのバーランプはマイクで音を拾って伸び縮みするスクリプトをつけています。鼻息で反応するのは改善の余地あり。

// ソースコードは下記を参考にさせていただきました
// https://qiita.com/ELIXIR/items/ff503d48c24092c05843
// @ELIXIR様

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

public class MicVolume : MonoBehaviour {

 // オプション
 public bool useOculus;  // OculusQuest使う
 public bool useVive;    // ViveCosmos使う

 // 音量調整
 [SerializeField, Range(0f, 10f)] float m_gain = 1f; // 音量に掛ける倍率
 float m_volumeRate; // 音量(0-1)

 // 筐体の光る部分
 GameObject LeftLight;
 GameObject RightLight;

 // 光の幅
 float scale_y_new;  // 新しい幅
 float scale_y_old;  // 前回の幅(ちらつき防止用)

 // 初期化
 void Start () {
   AudioSource aud = GetComponent<AudioSource>();
   LeftLight = GameObject.Find("LeftLightRoot");
   RightLight = GameObject.Find("RightLightRoot");

   // オーディオソースとマイクがあるか
   if (aud != null && Microphone.devices.Length > 0) {
     Debug.Log("マイク:" + string.Join(", ", Microphone.devices));

     // とりあえず0番目のマイクを使用
     string devName = Microphone.devices[0];
     if (useOculus) {
       devName = "Headset Microphone (Oculus Virtual Audio Device)";
     }
     if (useVive) {
       devName = "マイク (2- VIVE Cosmos Multimedia Audio)";
     }
     Debug.Log("デバイス名:" + devName);

     // 音を取得する準備
     int minFreq, maxFreq;
     Microphone.GetDeviceCaps(devName, out minFreq, out maxFreq); // 最大最小サンプリング数を得る
     aud.clip = Microphone.Start(devName, true, 2, minFreq);      // 音の大きさを取るだけなので最小サンプリングで十分
     aud.Play(); //マイクをオーディオソースとして実行(Play)開始
   }
 }

 // フレームごとの処理
 void Update () {
   // スケールに合わせて調整する
   scale_y_new = (m_volumeRate * 100 >= 1) ? 1 : m_volumeRate * 100;

   // ちらつき防止のため平均をとる
   scale_y_new = (scale_y_new + scale_y_old) / 2;
   LeftLight.transform.localScale = new Vector3(1, scale_y_new, 1);
   RightLight.transform.localScale = new Vector3(1, scale_y_new, 1);
   scale_y_old = scale_y_new;
 }

 // オーディオが読まれるたびに実行される処理
 private void OnAudioFilterRead(float[] data, int channels) {
   float sum = 0f;
   for (int i = 0; i < data.Length; ++i) {
     sum += Mathf.Abs(data[i]); // データ(波形)の絶対値を足す
   }
   // データ数で割ったものに倍率をかけて音量とする
   m_volumeRate = Mathf.Clamp01(sum * m_gain / (float)data.Length);
 }
}

(3) カメラを設置する

Unityのカメラを設置します。映像の出力にはUnityCaptureを利用しています。お好みでPost ProcessingやChinemachineを使うと映画のような映像が撮れるかも(私は使いこなせない...

画像6

(4) 録画する

OBS等でUnityの映像を取り込みます。私の場合はプレイヤーを撮影するのが目的なので極力何も加えずにそのまま録画しています。加工はお好みで。

4.えたもの

・Modが無くても撮影できる環境。不意のアプデに怯えなくなった(笑
・BlenderやUnityと仲良くなれた。アバター改変やPlatform作り楽しい!

5.あとがき

BeatSaberをプレイする側には生活があり、物語があると思っています。
(何言ってるんだコイツ...

この半年間自身のアバターと向き合って、好きな服を着せたりアイテム作って持たせたりと、表現したかったものが少しずつつくれるようになり、成長を感じることができました。

・・・BeatSaberの腕はぜんぜん成長してない(´;ω;`)

画像6

最後に、配信はしておりませんがTwitterで気ままに動画上げているので気になった方は見に来てね(@yuzumoti_chan)

またこの度アドカレにお誘いくださいましたはるふぁ(@HARUFA_v)様、記事を書く機会をいただき感謝いたします!


この記事が気に入ったらサポートをしてみませんか?