Netcode for GameObjectsのチュートリアル【Unity+ローカルマルチプレイ】

オンラインのマルチプレイゲームが作りたい?分かった分かった。でもとりあえずはローカルでのマルチプレイを作りましょう。ほとんどソースを変えることなくオンライン化出来ます。なのでまずはこれやっていきましょう。

目次

プロジェクト作成・パッケージの導入

Netcode for GameObjects(以下NGOとかって略すことあり)はUnityのパッケージを利用します。

Unityプロジェクトを作成

よくあるパターンだと3Dでやってること多いんですが、色々考えること多くなるので、私の方では2Dのプロジェクトから作成したいと思います。

Unityのバージョンは、2021.3以上が目安になります。古いバージョンだとパッケージマネージャーからのインポートで表示されないことがあります。

必要なパッケージの導入

いくつか必要なパッケージがあります。これらはまとめて導入しておきましょう。

  • Netcode for GameObjects
  • Multiplayer Tools(一応あとからでもOK)
  • Multiplayer Samples Utilities
    • https://github.com/Unity-Technologies/com.unity.multiplayer.samples.coop.git?path=/Packages/com.unity.multiplayer.samples.coop#main

Multiplayer Samples Utilitiesは左上のプラスボタンから「Add Package from URL…」に併記してあるURLを貼り付けてから導入してください。

確認用サンプル : ホスト – クライアント間の同期まで

まずは、動作確認をかねてシンプルなものを作ってみたいと思います。各コンポーネントの基本的な使い方になるので、ここの作業をしっかりと追えるようにしてください。

NetworkManagerの追加

空のGameObjectを作成(名:NetowrkManager)し、「Netcode>NetworkManager」を追加します。

スライム

コンポーネント上部に警告が出ている場合、「Multiplayer Tools」のパッケージが追加されていない可能性があります。要注意!

コンポーネントが追加できたら、「Select Transport…」をUnity Transportに設定してください。設定すると、さらに下側にUnityTransportというコンポーネントが追加されます。これはデフォルトの設定のままにしておいてください。

プレイヤープレファブの作成

ゲームに参加したら、自分のプレイヤーが表示されるようなものを作ります。そのためのプレファブを作成します。

空のGameObject(名:Player)を作成し、「Netcode>NetworkObject」コンポーネントを追加します。2Dの場合はPlayerゲームオブジェクトの子供にキャラクターの画像(SpriteRenderer)を追加してください。

設定が完了したら、Playerゲームオブジェクトをプロジェクトビューにドラッグアンドドロップしてプレファブ化してください。

プレファブ化が終了したら、シーン内のPlayerは削除してください!削除して、ください!!

NetworkManagerにプレファブを登録

再びシーン内のNetworkManagerを選択してインスペクターに設定を追加します。

PlayerPrefabの項目に、先程プレファブ化したPlayerのプレファブをドラッグアンドドロップします。(ヒエラルキーからPlayerがいないことも合わせて確認してください。)。またNetworkPrefabsにも同様のプレファブを追加してください。

この作業は今回のテスト用だということに注意をしてください。ゲームによってはプレイヤー用のプレファブが不要なパターンも存在します。

バージョン更新で変更がありました
新しいバージョンではプレファブを直接セットすることが出来ず、アセット経由で登録を行います。
初期状態だと、DefaultNetworkPrefabsというアセットがセットされており、そのアセットのインスペクターでプレファブを登録することが出来ます。

再生して、Start Hostしてみる

ここまでの設定が完了したら、ゲームを再生して見てましょう。何も映っていない状態が正解です。そして、再生中にNetowrkManagerコンポーネントにボタンが3つあります。今回は「Start Host」ボタンを押してください。

正しく設定が出来ていると、Playerのプレファブが画面中央に表示されるはずです。押したボタン部分は「Stop Host」ボタンに変わります。

この状態になれば成功!

インスペクターのボタンをUIで使えるようにする

このあとは、スタンドアローンのアプリとUnityEditorでローカル通信を行いたいのですが、アプリ側ではインスペクターのボタンが使えません。そのためUIとしてボタンを作成します。

画面右上に2つボタンを作成します。

空のGameObject(名:NetworkManagerUI)を作成し、以下のスクリプトを作成してください。

using UnityEngine;
using UnityEngine.UI;
using Unity.Netcode;
public class NetworkManagerUI : MonoBehaviour
{
    [SerializeField] private Button hostButton;
    [SerializeField] private Button clientButton;
    private void Awake()
    {
        hostButton.onClick.AddListener(() =>
        {
            NetworkManager.Singleton.StartHost();
        });
        clientButton.onClick.AddListener(() =>
        {
            NetworkManager.Singleton.StartClient();
        });
    }
}

スクリプトが作成できたらNetworkManagerUIのGameObjectに貼り付けます。インスペクターに2つのボタンをセットする場所があるので、対応したボタンをセットしてください。

クライアントアプリを作成して、ローカル通信を行う

実際にアプリを作成し、Unityエディタと通信させてみましょう。

STEP
プロジェクト設定を行う

Edit > Project SettingsからPlayerを選択して、印部分を変更してください。Company NameやProduct Nameは好きなものでOKです。

Fullscreen ModeはWindowedにしておかないと、チェックしづらいです。それに応じてDefault Screen Width/Heightも変えておきましょう。(Run In Backgroundはアプリが非アクティブでも動いてくれます。この手のチェックをする場合は有効にしておいたほうが便利かも)

STEP
Build And Run

準備が出来たら「Build And Run」を行って、アプリを起動させます。Build Settingsに先程編集したシーンが先頭で登録されていることを確認してください。Build And Runは以下2つから行うことが出来ます。

  • Build Settingウインド右下の「Build And Run」ボタン
  • ツールバーのFile > Build And Run

Build And Runを行うと、アプリのファイルを保存するフォルダを指定すると、ゲーム画面が立ち上がるのが確認出来ます。保存フォルダはAssetsフォルダ内は避けた場所にしてください。

渡しの場合はBuildフォルダなどを作成して、そこに出力させています。

ビルドは少し時間がかかります。しばらくすると、下図のようなボタンしかないアプリが立ち上がれば成功です。

STEP
Unityエディタとアプリを動かす

アプリが立ち上がった状態で、Unity側もゲームを実行します。組み合わせ自体はどちらでもいいのですが、今回は下記のような組み合わせでボタンを1回ずつ押してください。押す順番は必ずHost側が先になるようにしてください。

  • Unityエディタ:「Host」ボタン
  • アプリ:「Client」ボタン

正しい手順通りに動かすことができれば、2つの画面にプレイヤーが表示されます。これは同じ位置に重なっているため、Unityエディタ側で2つのプレイヤーが作られていることを確認してください。

ここでは重なったPlayerが表示されたことが確認できればOK。

ホストとクライアントを交代したテストをしてもいいですね。

確認用アプリ:移動処理などの同期

ここまでの作業は動きがなさすぎて、マルチプレイ感なさすぎますね。ということでここからはキャラクターを動かして、相手と同期するところをやってみたいと思います。

キャラクターを動かす

動かし方自体は普通のものですが、継承するクラスが異なります。NetworkBehaviourを継承することで、自分のGameObjectが所有権あるものかどうかなどを判断することが出来ます。下スクリプトでは、IsOwnerの時しか動く処理を実行しないようになっています。

using UnityEngine;
using Unity.Netcode;

public class PlayerMovement : NetworkBehaviour
{
    private void Update()
    {
        if (IsOwner == false)
        {
            return;
        }

        Vector2 direction = new Vector2()
        {
            x = Input.GetAxisRaw("Horizontal"),
            y = Input.GetAxisRaw("Vertical")
        };
        float moveSpeed = 3f;
        transform.Translate(direction * moveSpeed * Time.deltaTime);
    }
}

作成したスクリプトはPlayerのプレファブにAddComponentしてください。

この状態で一度実行してみてください。動かすことはできるようになりますが、相手側にその情報が反映されていないと思います。それでOK。次はこの位置情報の共有を行います。

ClientNetworkTransformで位置を同期

プレイヤーの位置を同期させる場合、プレイヤーのプレファブに「ClientNetworkTransform」コンポーネントを追加して、下のチェックボックスを設定してください。今回はxyポジションのみで大丈夫です。 

動作確認

同様に動かしてみると、各アプリで自分のプレイヤーを独立して動かすことができるようになっています。

ちゃんと同期して動くことが確認できましたでしょうか?

この状態はローカルネットワーク内で接続している状態で、オンラインではまだ他の人と一緒に遊ぶことは出来ません。と、いうことで!次はオンライン対応を行ってみたいと思います!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメント一覧 (1件)

コメントする

目次