8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【超簡単!】Netcode for GameObjectsでマルチプレイを実装する

Last updated at Posted at 2023-03-13

概要

Netcode for GameObjectsで位置, アニメーションの同期を行います。
この記事では実装手順のみを紹介します。
初学者向けに細かい操作も書いておきます。

TL;DR

NetworkManagerとPlayerを用意してStartHost, StartClientする。
PlayerにはNetworkObjectともろもろ同期用のNetworkBehaviourを継承したクラスを付ける。
後は感覚で行ける。

1. プロジェクトを用意する

image.png
3Dテンプレートを選択し、プロジェクトを作成

2. パッケージをインストールする

Unity Registry -> Netcode for GameObjects
image.png
※以前はUnity Transportを手動で入れる必要があったが自動で入れてくれるようになった。

3. シーン上にNetworkManagerを配置する

CreateEmptyして...
image.png
名前をNetworkManagerにしておく
image.png
作ったオブジェクトにNetworkManagerコンポーネントを付ける
image.png

4. Playerオブジェクトを用意する

ユニティちゃんを使う。
ダウンロードしてきたものをインポート。
image.png

一回シーンにおいて、AnimatorControllerを交換
image.png

このままだとピンクなので....
image.png

とりあえず描画できるStandardに設定
image.png

ここから...
image.png

NetworkObject, NetworkAnimator, NetworkTransform, NetworkRigidbody,NewScriptからPlayerControllerを追加
image.png

NetworkAnimatorにAnimatorをセット
image.png

CapsuleColliderを追加して、いいかんじに調整
image.png
image.png

RigidbodyのFreezePositionとFreezeRotationを設定
image.png

PlayerControllerに以下のコードを記載

using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine;

public class PlayerController : NetworkBehaviour
{
    [SerializeField] float speed = 1f;
    Animator animator;
    
    void Start()
    {
        animator = GetComponent<Animator>();
    }

    void Update()
    {
        if (IsOwner)
        {
            var h = Input.GetAxis("Horizontal");
            var v = Input.GetAxis("Vertical");
            // サーバー(ホスト)のメソッドを呼び出す
            MoveServerRpc(h, v);
        }
        
        if (IsServer)
        {
            // ステージから落ちたら戻してあげる
            if (transform.position.y < -10.0)
            {
                transform.position = new Vector3(Random.Range(-3, 3), 3, Random.Range(-3, 3));
            }
        }
    }
    
    [ServerRpc]
    void MoveServerRpc(float vertical, float horizontal)
    {
        // ここはサーバー(ホスト)でだけ処理される
        var moveInput = new Vector3(horizontal, 0, vertical);
        if (moveInput.magnitude > 0f)
            transform.LookAt(transform.position + moveInput);

        transform.position += moveInput * Time.deltaTime * speed;
        animator.SetFloat("Speed", moveInput.magnitude);
    }
}

5. 床を用意

Plane作って...
image.png

でっかくする
image.png

6. NetworkManagerの設定

TransportをUnityTransportに設定
image.png
image.png

PlayerPrefabを設定
image.png

7. ボタンを追加

先ほど作ったNetworkManagerオブジェクトにAddCompornent -> NewScriptからNetworkManagerControllerを追加
NetworkManagerControllerの中に以下のコードを入れる

using Unity.Netcode;
using UnityEngine;

public class NetworkManagerController : MonoBehaviour
{
    void OnGUI()
    {
        GUILayout.BeginArea(new Rect(10, 10, 300, 300));
        if (GUILayout.Button("Host")) NetworkManager.Singleton.StartHost();
        if (GUILayout.Button("Client")) NetworkManager.Singleton.StartClient();
        if (GUILayout.Button("Server")) NetworkManager.Singleton.StartServer();
        GUILayout.EndArea();
    }
}

8.ビルド

Add Open Scenesを押して、Build And Runする。
image.png

9.実行

Build And Runが完了したら勝手にゲームが起動する。
↑これとエディタで位置とアニメーション同期を確認する

片方でHost、もう片方でClientを押すと、シーン上にキャラクターが2体出てくる。
AWSDや矢印キーで動ける。

image.png

完成!

まとめ

今回は簡単な位置同期とアニメーション同期を試してみました。
簡単とはいえマルチプレイをこれだけの作業で実装できるのは嬉しいです。
ただ、このままだと同じPC上でしか動きません。
NetworkManagerからIPを直接設定することでローカルネットワーク内で通信出来たり、Relayを使うことでインターネットの海を飛び越えることが出来たりします。
是非いろいろ試してみてください。

参考

以下を参考にしています。
本当に分かりやすく丁寧に説明してくださっているので是非見てみてください!!!

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?