2Dオンラインゲーム編
Lesson2 ロビーを作ろう
2-1 タイトル画面を作る
参加者が待機するロビーを作りましょう。
タイトル画面でEnterキーを押すと、プレイヤーはロビー(待機所)に参加し、ゲームの開始を待つことになります。
ルームの作成者(ルームに最初に参加したプレイヤー)はPUNにおいてマスタークライアントと呼ばれます。
このレッスンでは、
① ルームを作成して参加するプレイヤーを待つ
② マスタークライアントが開始命令を出すことでインゲームへ遷移する
③ インゲーム側で各プレイヤーを生成する
といった流れでマルチプレイを開始してみましょう。

ロビー専用のシーンを作っても良いのですが、今回は簡略化のためタイトルシーンでロビーの処理を行います。
Titleシーンを作成してください。

Titleシーンを開いたら、まずはタイトル部分を作成しましょう。
背景やロゴを配置して自由にタイトル画面を作成してください。
【サンプルで使用しているフォント】https://nicofont.pupu.jp/nicomoji-plus.html

今回は背景のUVスクロールをシェーダーグラフで実装していきます。シェーダーグラフはURPの機能で、ノードを繋ぐことで簡単にシェーダーを作ることができる機能です。
(シェーダーグラフについては3D脱出ゲーム編3-8を参照してください)
Shaderフォルダを作成して「Create」→「Shader Graph」→「URP」→「Sprite Unlit Shader Graph」を追加してください。

シェーダーグラフを作成したら、ダブルクリックして開いてください。

シェーダーグラフに新しいパラメータ MainTex(Texture2D型)とScroll(Vector2型)を作成してください。
MainTexはUnity側で指定している特殊な名前のため、間違いのないように名前を入力してください。

何もない場所を右クリックして、メニューから「Create Node」を選択してください。
検索欄から使用したいノードを選択すると、ノードを作成できます。

以下のようにノードを繋げて、UVスクロールを作ってみてください。
※ 各ノードの詳細はEX「シェーダーグラフ」にまとめています

Tiling And Offsetノードの後ろにSample Texture 2Dノードを追加して、結果をFragmentのBase Colorに出力してください。Sampler StateのFilterを「Point」に、Wrapを「Repeat」に設定しましょう。
これで画像をUVスクロールする処理が完成しました。

シェーダーグラフを保存して、シェーダーグラフ編集画面を閉じてください。
新しいマテリアルを作成して、シェーダーグラフをドラッグ&ドロップしてください。

インスペクターでMainTexとScrollを設定できます。スクロールの速度を示すScrollはX方向に適当な速度で動くように設定してください。
※ マテリアルのMainTexには何も設定しなくても構いません
Imageに設定している画像が自動的に反映されるようになっています

マテリアルを背景に適用することで、背景がスクロールするようになります。
このようにシェーダーグラフを用いることでシンプルな演出であれば簡単につくることができます。

2-2 カスタムプロパティ
それではロビー部分の機能を作っていきます。
まずはEnterキーが押されたときに、インターネットへの接続、ルームの作成、ルームへの参加を一気に実行します。内容としては1-6とほぼ同じです。
Lobbyスクリプトを作成して、以下のように入力してください。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun; // PUNを使うために必要
using Photon.Realtime; // PUNを使うために必要
public class Lobby : MonoBehaviourPunCallbacks // 継承する
{
enum LobbyState
{
enTitle, // タイトル
enStandby, // 参加待ち
enStartWait, // 開始待ち(準備OK)
enRoom, // 開始中
}
// ロビーの状態
LobbyState m_lobbyState = LobbyState.enTitle;
void Update()
{
switch (m_lobbyState)
{
case LobbyState.enTitle:
// タイトル
// Enterキーが押されたらネットワークに接続
if (Input.GetKeyDown(KeyCode.Return))
{
// ステートを切り替える
m_lobbyState = LobbyState.enStandby;
// Photonのサーバーに接続する
PhotonNetwork.ConnectUsingSettings();
}
break;
case LobbyState.enStartWait:
// 開始待ち
break;
case LobbyState.enStandby:
// 準備OK
break;
case LobbyState.enRoom:
// 開始中
break;
}
}
// サーバーへ接続した瞬間に呼ばれる関数
public override void OnConnectedToMaster()
{
// ルーム設定の作成
RoomOptions roomOptions = new();
roomOptions.MaxPlayers = 4;
// 部屋に入る(同名の部屋がなかったら作る)
PhotonNetwork.JoinOrCreateRoom("GameRoom",
roomOptions,
TypedLobby.Default);
}
// 自分がルームへ参加した瞬間に呼ばれる関数
public override void OnJoinedRoom()
{
Debug.Log("ルームに参加しました");
}
// 新規でルームにプレイヤーが参加した瞬間に呼ばれる関数
public override void OnPlayerEnteredRoom(Photon.Realtime.Player newPlayer)
{
Debug.Log(newPlayer.ActorNumber + "番のプレイヤーが参加しました");
}
}
状態をステートで管理している以外はGameManagerスクリプトと同じです。
コードが描けたら保存して、適当な空オブジェクトにアタッチしてください。
ゲームを実行してEnterキーを押すとPhotonのサーバーに接続され、ログが出力されます。


次に参加しているプレイヤーの状態(開始OKかどうか、プレイヤーの番号)を管理する機能を実装します。別々のプレイヤーの状態をどのように管理すればよいか迷うかもしれませんが、PUNにはカスタムプロパティというデータの共有を行うための機能があるため、今回はこれを活用して状態管理を実装してみましょう。
(執筆中)