オンラインのマルチプレイゲームが作りたい?分かった分かった。でもとりあえずはローカルでのマルチプレイを作りましょう。ほとんどソースを変えることなくオンライン化出来ます。なのでまずはこれやっていきましょう。
プロジェクト作成・パッケージの導入
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エディタと通信させてみましょう。
Edit > Project SettingsからPlayerを選択して、印部分を変更してください。Company NameやProduct Nameは好きなものでOKです。
Fullscreen ModeはWindowedにしておかないと、チェックしづらいです。それに応じてDefault Screen Width/Heightも変えておきましょう。(Run In Backgroundはアプリが非アクティブでも動いてくれます。この手のチェックをする場合は有効にしておいたほうが便利かも)
準備が出来たら「Build And Run」を行って、アプリを起動させます。Build Settingsに先程編集したシーンが先頭で登録されていることを確認してください。Build And Runは以下2つから行うことが出来ます。
- Build Settingウインド右下の「Build And Run」ボタン
- ツールバーのFile > Build And Run
Build And Runを行うと、アプリのファイルを保存するフォルダを指定すると、ゲーム画面が立ち上がるのが確認出来ます。保存フォルダはAssetsフォルダ内は避けた場所にしてください。
渡しの場合はBuildフォルダなどを作成して、そこに出力させています。
ビルドは少し時間がかかります。しばらくすると、下図のようなボタンしかないアプリが立ち上がれば成功です。
アプリが立ち上がった状態で、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ポジションのみで大丈夫です。
動作確認
同様に動かしてみると、各アプリで自分のプレイヤーを独立して動かすことができるようになっています。
ちゃんと同期して動くことが確認できましたでしょうか?
この状態はローカルネットワーク内で接続している状態で、オンラインではまだ他の人と一緒に遊ぶことは出来ません。と、いうことで!次はオンライン対応を行ってみたいと思います!
コメント
コメント一覧 (1件)
[…] Netcode for GameObjectsのチュートリアル【Unity+ローカルマルチプレイ】 […]