見出し画像

オープンソース少人数マルチプレイVR空間の開発①

VRSNS、楽しいですよね。
でも時々規約や仕様の面で不便を感じることもあります。
そこで思ったのです。
『オープンソースの少人数マルチプレイVRSNS、作ったらたのしくね?』と。

勿論、プログラミング初心者の私がこんなことを考えたのには理由があります。それはこんなアセットを見つけたからです。

俺ばかだからよくわかんねぇけど(本当にわからん)、この『Multiplayer VR Template』を使えばマルチプレイVR空間ができるらしい。
というわけで、この記事はプログラミング初心者がマルチプレイVR空間開発チャレンジする内容となっております。
連載途中でエタったらそういうものだと笑ってください。ではやってきましょう。れっつめたばーす!

開発環境

Unity 2021.3.15f1

使用アセット

・XR Interaction Toolkit
・Open XR Plugin
・XR Plug-in Management
・finalIK
・UniVRM
・Multiplayer VR Template
・PUN 2 - FREE
・Photon Voice 2

今回やること

今回は最低限の環境作りをしていきます。
・Multiplayer VR Templateを利用するのに必要な最低限のセットアップ
・VR空間でのトラッキングに必要な機能諸々
をしていきましょう。

①Unityのプロジェクトを作成
Unity 2021.3.15f1/3Dでプロジェクト作成。
プロジェクト名は適当に『Free_VR』とでも名付けましょう。

②VR開発に必要なアセットをインポートする。
・XR Interaction Toolkit
・Open XR Plugin
・XR Plug-in Management

上記の記事がVR開発環境づくりには詳しいです。

上記アセットがインポートできたら、Edit→Project settingからXR Plug-in Managementを開き、OpenXRをチェック。

次にOpenXRをクリックして、対応したいコントローラーを追加します。

トラッカーを使うために、Assets\Scriptsフォルダを作って、そこに以下のフォーラムからDLしたスクリプト『HTCViveTrackerProfile.cs』を入れます。
https://forum.unity.com/threads/openxr-and-openvr-together.1113136/#post-7803057

するとさっきのOpenXR設定のコントローラー追加欄にHTCViveTrackerが追加されているのでそれを追加します。

③次にハンドトラッキングに必要なスクリプトをDLします。

以下のスクリプトをzipでまるごとDLし、openxrhands-main\openxrhands-main\Assets\OpenXRHandTrackingフォルダだけをUnityのAssets\Scriptsフォルダに配置します。
するとOpenXR Feature GroupsにHand tracking Extensionが追加されるのでチェックを入れます。

次にAssets\scripts\OpenXRHandTrackingに以下のスクリプトを追加。

using System;
using UnityEditor;
using UnityEngine;

namespace FingerOperations
{
    [ExecuteAlways]
    [RequireComponent(typeof(Animator))]
    public class FingerOperation : MonoBehaviour
    {
        public Animator _animator;
        public HandGetter HandGetter_L;
        public HandGetter HandGetter_R;


        private void Start()
        {
            _animator = GetComponent<Animator>();
        }

        private void Update()
        {
            if (_animator != null)
            {
                _animator = GetComponent<Animator>();
            }

            var handler = new HumanPoseHandler(_animator.avatar, _animator.transform);
            var humanPose = new HumanPose();
            handler.GetHumanPose(ref humanPose);

            // Left Hand
            humanPose.muscles[55] = 0 - HandGetter_L.Curls[0] * 2;
            humanPose.muscles[57] = 0 - HandGetter_L.Curls[0] * 2;  
            humanPose.muscles[58] = 0 - HandGetter_L.Curls[0] * 2; 

            humanPose.muscles[59] = 0.7f - HandGetter_L.Curls[1] * 1.7f;
            humanPose.muscles[61] = 0.7f - HandGetter_L.Curls[1] * 1.7f;
            humanPose.muscles[62] = 0.7f - HandGetter_L.Curls[1] * 1.7f;

            humanPose.muscles[63] = 0.7f - HandGetter_L.Curls[2] * 1.7f;
            humanPose.muscles[65] = 0.7f - HandGetter_L.Curls[2] * 1.7f;
            humanPose.muscles[66] = 0.7f - HandGetter_L.Curls[2] * 1.7f;

            humanPose.muscles[67] = 0.7f - HandGetter_L.Curls[3] * 1.7f;
            humanPose.muscles[69] = 0.7f - HandGetter_L.Curls[3] * 1.7f;
            humanPose.muscles[70] = 0.7f - HandGetter_L.Curls[3] * 1.7f;

            humanPose.muscles[71] = 0.7f - HandGetter_L.Curls[4] * 1.7f;
            humanPose.muscles[73] = 0.7f - HandGetter_L.Curls[4] * 1.7f;
            humanPose.muscles[74] = 0.7f - HandGetter_L.Curls[4] * 1.7f;
            
            // Right Hand
            humanPose.muscles[75] = 0 - HandGetter_R.Curls[0] * 2;
            humanPose.muscles[77] = 0 - HandGetter_R.Curls[0] * 2;  
            humanPose.muscles[78] = 0 - HandGetter_R.Curls[0] * 2; 

            humanPose.muscles[79] = 0.7f - HandGetter_R.Curls[1] * 1.7f;
            humanPose.muscles[81] = 0.7f - HandGetter_R.Curls[1] * 1.7f;
            humanPose.muscles[82] = 0.7f - HandGetter_R.Curls[1] * 1.7f;

            humanPose.muscles[83] = 0.7f - HandGetter_R.Curls[2] * 1.7f;
            humanPose.muscles[85] = 0.7f - HandGetter_R.Curls[2] * 1.7f;
            humanPose.muscles[86] = 0.7f - HandGetter_R.Curls[2] * 1.7f;

            humanPose.muscles[87] = 0.7f - HandGetter_R.Curls[3] * 1.7f;
            humanPose.muscles[89] = 0.7f - HandGetter_R.Curls[3] * 1.7f;
            humanPose.muscles[90] = 0.7f - HandGetter_R.Curls[3] * 1.7f;

            humanPose.muscles[91] = 0.7f - HandGetter_R.Curls[4] * 1.7f;
            humanPose.muscles[93] = 0.7f - HandGetter_R.Curls[4] * 1.7f;
            humanPose.muscles[94] = 0.7f - HandGetter_R.Curls[4] * 1.7f;                    


            handler.SetHumanPose(ref humanPose);
        }
    }
}

参照記事:https://zenn.dev/drumath2237/articles/2e8f47cb9fc7d55f544a


④必要なアセットをインストールしていく。
・finalIK
・UniVRM(UniVRM-0.107.0_1e8a.unitypackage)
・PUN 2 - FREE
・Photon Voice 2
・Multiplayer VR Template
・Magic Mirror Pro(なくてもいいけどちょっと鏡作るのが楽になる)

がんがん入れていきましょう。ただ、Multiplayer VR Templateはそのままだとエラーが出るので、
Assets\IRONHEAD Games\Scripts\Voice Chat\NetworkedPlayerVoiceChatManager.cs(21,13): error CS0246: The type or namespace name 'PhotonVoiceNetwork' could not be found (are you missing a using directive or an assembly reference?)
というエラーがでるので、Assets\IRONHEAD Games\Scripts\Voice Chat\NetworkedPlayerVoiceChatManager.csの『PhotonVoiceNetwork』を『PunVoiceClient』に置換してください。
PUN 2、Photon Voice 2の設定については、
Window→Photon Unity networking→Locate Photon ServerSettingsからできます。
サイトに会員登録して、App Id PUNとApp id voiceのアプリ IDを習得してUnityで設定する必要があります

⑤KotauchiTrackerCalibratorを丸ごとDL。解凍したフォルダがAssets\scripts\KotauchiTrackerCalibrator-masterな位置になるように配置しましょう。
ついでにKotauchiVRIKController.csを以下のように改変。左コントローラーからキャリブレーションできるように設定しました。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.XR;
using RootMotion.FinalIK;

public class KotauchiVRIKController : MonoBehaviour
{
    private IKTargetRepositoryInterface repository;
   
    public  InputAction leftAction; // 左用の入力アクション

    public VRIK ik;
    public VRIKCalibrator.Settings settings;
    public Transform headTracker;
    public Transform bodyTracker;
    public Transform leftHandTracker;
    public Transform leftElbowTracker;
    public Transform rightHandTracker;
    public Transform rightElbowTracker;
    public Transform leftFootTracker;
    public Transform leftKneeTracker;
    public Transform rightFootTracker;
    public Transform rightKneeTracker;



   // コンポーネントが有効化された場合
   private void OnEnable()
   {
       leftAction.Enable();
   }

   // コンポーネントが無効化された場合
   private void OnDisable()
   {
       leftAction.Disable();
   }


    void Awake()
   {
       // 入力が発生した時の処理
       leftAction.performed += context =>
       {
            KotauchiVRIKCalibrator.Calibrate(
                repository,
                ik, 
                settings,
                headTracker,
                bodyTracker, 
                leftHandTracker,
                leftElbowTracker,
                rightHandTracker,
                rightElbowTracker, 
                leftKneeTracker,
                leftFootTracker,
                rightKneeTracker,
                rightFootTracker
            );        
       };
   }

    void Start()
    {
        repository = new GameObjectIKTargetRepository();
    }

    void LateUpdate()
    {
        if (Input.GetKeyDown(KeyCode.C))
        {
            KotauchiVRIKCalibrator.Calibrate(
                repository,
                ik, 
                settings,
                headTracker,
                bodyTracker, 
                leftHandTracker,
                leftElbowTracker,
                rightHandTracker,
                rightElbowTracker, 
                leftKneeTracker,
                leftFootTracker,
                rightKneeTracker,
                rightFootTracker
            );
        }
    }

}

⑥これで準備完了です。
testVR.unitypackageをDLしてインポート、『test』シーンを開いてみてください。この時点で
・コントローラーでの移動
・ハンドトラッキング
・キャリブレーション(左コントローラーBボタン)
・トラッカー対応
していると思います。各種設定方法について解説するのは疲れたのでまた今度。触ってみていろいろと試してみてください。

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