feature image

2020年11月14日 | ブログ記事

【AdC1日目】UnityとPhotonでオンラインゲームを作る

はじめに

みなさんどうも、はじめましての方ははじめまして、そうでない方もはじめまして、19のNと申します。今回は、Unityで簡単に(?)オンラインゲームが作れちゃうPhotonの機能をご紹介します。公式のドキュメントが読みづらかったり、英語だったり、するので覚書も含めています。それではさっそくいってみましょう。

Photonの概要

Photonって…?

伝説上の生き物さ。

PhotonとはUnityで簡単にオンラインゲームが作れちゃうミドルウェアです。UnityAssetsStoreからPUN2と検索して出てきたものをインポートすればすぐに使うことができます。ルームの作成や、プレイヤー間でのオブジェクトの同期など、様々なことをやってくれます。

Photonを使うには???

Step1

Step2

これでPhotonが使えるようになりました。もっと詳しい手順は公式ドキュメントを読んでください。

Photonの基礎知識

ルームとロビー

Photonにはルームとロビーという二つの状態があります。ロビーとはマッチングの待機場所というイメージで、ルームは実際にゲームをするところ、という風に理解していれば大丈夫だと思います。

マスタークライアント

Photonではマスタークライアントというホストプレイヤーのようなものがあります。全員揃ったらゲームをスタートする、などのマスタークライアント特有の処理をさせることができます。複数プレイヤーいるなかで、特別なプレイヤーと思ってもらえれば大丈夫です。

PhotonView

PhotonにはPhotonViewという便利なコンポーネントがあります。これをつけてるオブジェクトは他プレイヤーに同期されます。座標や、アニメーションなど、様々なものを同期することができます。

MonoBehaviourPunCallbacks

同期するオブジェクトにスクリプトをつけるとき、MonoBehaviourPunCallbacksというクラスを継承することになります。これにはルームに入ったときの処理、他プレイヤーがルームに入ってきたときの処理、など様々なコールバック関数が入っています。これをオーバーライドすることで、そのときどきに応じたコールバック関数に機能をつけたすことができます。

実践Photon

ロビーに入る→ルームを作成orすでにあるルームに入る

サーバーに接続

テキトーなスクリプトにMonoBehaviourPunCallbacksを継承して以下のConnect関数でサーバーに接続できる。以下、継承部分などは省略する。

using Photon.Pun;
using Photon.Realtime;

public class NetworkManager : MonoBehaviourPunCallbacks{
    public void Connect()
    {
        if (!PhotonNetwork.IsConnected)
        {
            PhotonNetwork.ConnectUsingSettings();
        }
    }
}

ロビーに入る

他の記事ではいきなりルームに入るような仕様のものが多いが、本記事ではロビーに入る→ルームを作成して入る or 他の人が作ったルームに入る のような流れで実装する。
MonoBehaviourPunCallbacksの中にあるOnConnectedToMaster()というサーバーに接続したときに呼ばれるコールバック関数でPhotonNetwork.JoinLobbyを呼び出す。これによって、ロビーに接続した状態になる。(他のプレイヤーが作ったルームなどが見える状態になる。)

public override void OnConnectedToMaster()
{
    PhotonNetwork.JoinLobby(customLobby);
}

ルームを作る

以下のCreateRoom()関数を作成して、適当なbuttonなどにつけたらできる。ルームごとのプロパティを設定することができて、以下ではルームの名前とメッセージを設定している。他にもいろんなものをつけられる。nicknameは適当なinputfieldとかから受け取ればよい。

public void CreateRoom()
{
    string nickname = inputfield.text;
    Photon.LocalPlayer.NickName=nickname;
    PhotonNetwork.CreateRoom(
        $"{nickname}'s room",
        new RoomOptions()
        {
            MaxPlayers = MAX_PLAYER_NUM,
            CustomRoomProperties = new ExitGames.Client.Photon.Hashtable()
            {
                { "DisplayName", $"{nickname}'s room" },
                { "Message", "Anyone can join !" }
            },
            CustomRoomPropertiesForLobby = new[]
            {
                "DisplayName",
                "Message"
            },
            IsOpen = true,
            IsVisible = true,
        }
    );
}

すでにあるルームの一覧を取得

OnRoomListUpdate(List<RoomInfo> roomList)というルームが新しく作られたときに呼ばれる便利なコールバック関数がある。roomListにルームの一覧が入っている。これを使って、以下ではroomListViewという別のクラスで取得したルームをUIに反映させる処理をしている。ここではPhotonの機能に限ったことを紹介するので、その辺は省く。

public override void OnRoomListUpdate(List<RoomInfo> roomList)
{
    roomListView.OnRoomListUpdate(roomList);
}

すでにあるルームに入る

以下のJoinRoom関数を適当なbuttonなどにつければよい。ここではルームに入った後、Gameシーンに遷移するようにしている。

private void JoinRoom(string roomName)
{
    PhotonNetwork.JoinRoom(roomName);
    PhotonNetwork.IsMessageQueueRunning = false;
    PhotonNetwork.LoadLevel("Game");
}

プレイヤー操作周りの実装

同期するオブジェクトのインスタンス化

プロジェクト直下にResourcesという名前のフォルダを作ってそこにPhotonViewコンポーネントを付けたPrefabを入れる。以下ではプレイヤーオブジェクトをインスタンス化している。

player = PhotonNetwork.Instantiate(this.playerPrefab.name, new Vector3(0f, 0f, 0f), Quaternion.identity, 0);

マスタークライアントのみで処理

if (PhotonNetwork.IsMasterClient)
{
    // 実際の処理
}

自機のみで処理

if (photonView.IsMine){
    // 実際の処理
}

自機の変更を同期

PunRPCという機能を使えば自機のクライアントでの変更を他プレイヤーに同期させることができる。以下のように[PunRPC]をつけた関数をphotonView.RPCで呼び出せばできる。第二引数をRpcTarget.AllViaServerにすると、サーバーで一括処理してから反映という風にすることができる。他にも色々な設定があるので、詳しくは公式ドキュメントなどを参照。

photonView.RPC(nameof(playerUpdate), RpcTarget.All, args);

[PunRPC]
playerUpdate(var args)
{
    // 実際の処理
}

プレイヤーに様々なプロパティを設定

CustomPropertiesという機能を使う。

var hashtable = new ExitGames.Client.Photon.Hashtable();
hashtable["State"] = state;
PhotonNetwork.LocalPlayer.SetCustomProperties(hashtable);
foreach (var p in PhotonNetwork.PlayerList)
{
    int pstate = (int)p.CustomProperties["State"];
}

最後に

Photonで作ったオンラインゲームを近日PlayStoreで公開予定…???!!!刮目せよ!!!!

明日はプロエロゲーマー、エロゲで金を稼ぐ美少女、あの有名なryohaさん?!の記事です。おたのしみに。

N icon
この記事を書いた人
N

物体が接触している他の物体や地面等の固体の面を押しているとき、その力の面に垂直な成分に対し、同じ大きさで反対向きの、固体の面が物体を押し返す力たそ(◞‸◟っ)

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2020年12月4日
【一緒に始めよう】VSTプラグインをつくる【AdC2020 21日目】
liquid1224 icon liquid1224
2020年12月17日
一人でゲームを作ったハッカソン【AdC2020 34日目】
Komichi icon Komichi
2020年11月19日
ICPC国内予選2020参加記【AdC6日目】
tatyam icon tatyam
2020年12月21日
かけだしデザイナーが「ほぼ」1ヵ月間毎日ロゴを描いてみた話【AdC2020 38日目】
WhiteFox icon WhiteFox
2020年12月17日
JavaScriptの非同期処理についてのメモ【AdC2020 33日目】
reyu icon reyu
2020年12月13日
全方位木DPについて
ebi icon ebi
記事一覧 タグ一覧 Google アナリティクスについて 特定商取引法に基づく表記