MLAPIで簡単なマルチプレイを作成する【MLAPI】

MLAPI のお勉強を始めました.

MLAPI

https://mlapi.network/mlapi.network

マルチネットワークライブラリの一つ. 最近Unity公式パッケージになりました.
他にはPhotonやMirrorなどがあります.

blogs.unity3d.com

新 MLAPI

(2021年3月28日追記)

本記事は旧 MLAPI に基づいた記事になります.
新 MLAPI を試したい場合は所々相違点があるので,ご注意ください.

新 MLAPI v0.1.0 リリースノートについて.
xrdnk.hateblo.jp

新 MLAPI v0.1.0 で手軽にサンプルを作ってみたい場合.
xrdnk.hateblo.jp

環境

  • Unity 2019.4.17f1
  • MLAPI 12.1.7

前準備

以下のアセットを利用します.

assetstore.unity.com

Invector_BasicLocomotion.unity をサンプルシーンとして使います.

また,MLAPIをGitHubのReleasesから入手します.

github.com

MLAPI-Installer.unitypackage と MLAPI.unitypackage をインポートします.中身が激薄でビビる.

Network Prefabs 用の Player Prefab の作成

マルチプレイ用のプレイヤーを作成します.

サンプルシーンを開くとすでにプレイヤーとカメラのPrefabがあるので,Original Prefabにします.

Original Prefab にした後は Hierarchy 上から ThirdPersonController_LITE と ThirdPersonCamera_LITE を削除します.
ThirdPersonController_LITE が Hierarchy 上に残っていると,いつまでもスポーン処理ができないので注意.

ThirdPersonController_LITE 設定

ThirdPersonController_LITE にネットワーク同期のために MLAPI の諸々の API をアタッチします.

Networked Object

ネットワーク上で複製するために必要なコンポーネント
今回パラメタはデフォルトのままにします.

Networked Transform

ネットワーク上で Transform を同期するために必要なコンポーネント
今回パラメタはデフォルトのままにします.

Networked Animator

ネットワーク上で Animation を同期するために必要なコンポーネント
今回パラメタはすべてチェックにし,Animatorには ThirdPersonController_LITE にアタッチされているものを設定します.

プレイヤーにTPSCameraが追従するようにする独自スクリプト

以下のスクリプト,MLAPI_InvectorBridge.cs を作成しアタッチします.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Invector.vCharacterController;
using MLAPI;

public class MLAPI_InvectorBridge : NetworkedBehaviour
{
    public GameObject playerCamera;
    private GameObject playerCam;

    private vThirdPersonInput vTPI;
    void Start()
    {
        if (!IsLocalPlayer)
        {
            GetComponent<vThirdPersonInput>().enabled = false;
        }
        else
        {
            playerCam = Instantiate(playerCamera);
            playerCam.name = this.gameObject.name + "camera";
            vTPI = GetComponent<vThirdPersonInput>();
            InitializeTpCamera();
        }
    }

    public virtual void InitializeTpCamera()
    {
        var tpCamera = playerCam.GetComponent<vThirdPersonCamera>();

        if (tpCamera)
        {
            tpCamera.SetMainTarget(this.transform);
            tpCamera.Init();
        }
        vTPI.tpCamera = tpCamera;
    }

}

加えて,vThirdPersonInput.cs を開き,Start()でInitalizeTpCamera() を呼び出さないようにコメントアウトします.

using UnityEngine;

namespace Invector.vCharacterController
{
    public class vThirdPersonInput : MonoBehaviour
    {
        #region Variables       

        [Header("Controller Input")]
        public string horizontalInput = "Horizontal";
        public string verticallInput = "Vertical";
        public KeyCode jumpInput = KeyCode.Space;
        public KeyCode strafeInput = KeyCode.Tab;
        public KeyCode sprintInput = KeyCode.LeftShift;

        [Header("Camera Input")]
        public string rotateCameraXInput = "Mouse X";
        public string rotateCameraYInput = "Mouse Y";

        [HideInInspector] public vThirdPersonController cc;
        [HideInInspector] public vThirdPersonCamera tpCamera;
        [HideInInspector] public Camera cameraMain;

        #endregion

        protected virtual void Start()
        {
            InitilizeController();
            // InitializeTpCamera();
        }
....

Player Camera に ThirdPersonCamera_LITE を設定します.

最終的には ThirdPersonController_LITE はこんな感じになるはず.

Network Manager

Hierarchy で空オブジェクトを生成して,NetworkManagerと名付けます.
Networked Prefabs に 前節で作成した ThirdPersonController_LITE を設定します.
Default Player Prefab にチェックを入れます.

また,Network Transport をどうするかを選ぶところがあるので,今回は UnetTransport としましょう.

すると,自動的に Unet Transport コンポーネントがアタッチされ,設定されます.
今回パラメタはデフォルトのままにします.

入室用のUI作成

ホストとして入りたい場合は,

using MLAPI;

NetworkingManager.Singleton.StartHost();

クライアントとして入りたい場合は,

using MLAPI;

NetworkingManager.Singleton.StartClient();

サーバーとして入りたい場合は.

using MLAPI;

NetworkingManager.Singleton.StartServer();

とします.

ボタン押下後にホスト入室,クライアント入室を実行するUIを作成します.

サンプルシーンの Hierarchy に Event System がないので,右クリック > UI > Event System で作成します.
Event System がないとボタン押下しても反応しないためです.

適当にボタンを3つ作成します.

以下のスクリプト,MLAPI_Initializer.cs を作成し,NetworkManager にアタッチします.

using UnityEngine;
using UnityEngine.UI;

using MLAPI;

public class MLAPI_Initializer : MonoBehaviour
{
    [SerializeField] private Button _hostButton;
    [SerializeField] private Button _clientButton;
    [SerializeField] private Button _serverButton;

    private void Start()
    {
        _hostButton.onClick.AddListener(StartHost);
        _clientButton.onClick.AddListener(StartClient);
        _serverButton.onClick.AddListener(StartServer);
    }

    private void StartHost() => NetworkingManager.Singleton.StartHost();
    private void StartClient() => NetworkingManager.Singleton.StartClient();
    private void StartServer() => NetworkingManager.Singleton.StartServer();
}

各ボタンを Inspector 上にあてはめておきます.

f:id:xrdnk:20210104222601p:plain

実機確認

マルチプレイの確認のため,StandaloneでBuildします.

Unity Editor では Host,Standalone では Client として入室してみましょう.

gyazo.com

プレイヤーの位置,アニメーションが無事同期されているのを確認しました.

参考動画

こちらの動画をそのまま参考にしました.

youtu.be

後でこちらのUnity Japan公式の動画も観よう.

youtu.be