1
1

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.

Unity Fusion Golfの要約

Last updated at Posted at 2022-08-22

はじめに

3DゲームはKarts、Tanknarok、Projectilesときて次はGolfが提供されました。

環境 バージョン
Fusion Golf 1.1.2 Build 3
Fusion Golf Unity 2020.3.35f1
筆者のUnity 2021.3.8f1

ざっくり中身を見ておこうと思います。
目新しい機能は大きく分けて3つほどでしょうか。


1.状態遷移

ネットワーク共有される状態遷移が設計されています。

2.ステージ進行

インゲーム部分はKartsやProjectilesよりもシンプルですが、ステージ(レベル)の切替が実装されています。Levelクラスが付いたプレファブをロード、アンロードする形です。

3.マッチメイキング

マッチメイキング機能があります。これでセッション名を入力する必要が無くなり、一覧から選択できるようになります。


以下、アウトゲームを構成する上での土台となるクラスを要約します。
インゲームは開発者の好きにやる部分なので割愛気味です。

クラスごとに重要度を3段階で付けています。個人的主観です。今回のサンプルの仕組みを理解する上で知っておくべきと感じた度合いを基準にしています。

イベントトリガー

  • InterfaceManager
オブジェクト名 イベント名 ターゲット
Options Button m_OnClick In Game UI Screen (UIScreen)Focus
Play Button m_OnClick Main Menu Screen (UIScreen)Focus
Options Button m_OnClick Main Menu Screen (UIScreen)Focus
Host Button m_OnClick Mode Selection Screen (UIScreen)Focus
Join Button m_OnClick Mode Selection Screen (UIScreen)FocusScreen
InterfaceManager (Golf.Matchmaker)TryJoinLobby
Back Button m_OnClick Mode Selection Screen (UIScreen)Back
Back Button m_OnClick Host Screen (UIScreen)Back
Confirm Button m_OnClick Host Screen (Golf.SessionSetup)TryCreateSession
Back Button m_OnClick InterfaceManager (Golf.Matchmaker)CloseLobby
Confirm Button m_OnClick InterfaceManager (Golf.Matchmaker)TryJoinSessionUI
Slider EndDrag Session Screen (Golf.SessionScreenUI)ApplyColorChange
PointerClick Session Screen (Golf.SessionScreenUI)ApplyColorChange
Slider EndDrag Session Screen (Golf.SessionScreenUI)ApplyColorChange
PointerClick Session Screen (Golf.SessionScreenUI)ApplyColorChange
Slider EndDrag Session Screen (Golf.SessionScreenUI)ApplyColorChange
PointerClick Session Screen (Golf.SessionScreenUI)ApplyColorChange
Start Button m_OnClick Session Screen (Golf.SessionScreenUI)StartGame
MoveTo Button m_OnClick Session Screen (Golf.SessionScreenUI)ToggleSpectate
Leave Button m_OnClick Session Screen (Golf.SessionScreenUI)Leave
Audio Button m_OnClick Options Menu Screen (Golf.OptionScreen)SetActivePanel
Graphics Button m_OnClick Options Menu Screen (Golf.OptionScreen)SetActivePanel
Controls Button m_OnClick Options Menu Screen (Golf.OptionScreen)SetActivePanel
Back Button m_OnClick Options Menu Screen (UIScreen)Back
Resume Button m_OnClick Pause Screen (Golf.PauseMenuUI)Resume
Options Button m_OnClick Pause Screen (UIScreen)FocusScreen
Leave Button m_OnClick Pause Screen (Golf.PauseMenuUI)Leave

ResourcesManagerクラス

重要★★☆
プレファブなどのリソースの格納庫です。
常駐シングルトンです。

往々にしてFusionのサンプルには常駐(DontDestroyOnLoad)シングルトンが多い印象です。サンプルで学習すべき視点を絞る上での適切な使い方をしているように見えます。

  • Putter playerControllerPrefab
    キャラクター用プレファブ
    image.png

  • PlayerScoreboardUI playerScoreUI
    スコアボードレイアウトプレファブ
    image.png

  • ScoreItem scoreItem
    スコアボード要素プレファブ
    image.png

  • PlayerSessionItemUI playerSessionItemUI
    プレイヤーセッション要素プレファブ
    image.png

  • WorldNickname worldNicknamePrefab
    自分以外のキャラクターの上でに出すニックネームプレファブ

  • GameObject splashEffect
    水に落ちたときのエフェクトプレファブ

Matchmakerクラス

重要★★★
Menuシーンにあります。
マッチメイキングを担当します。
InterfaceManagerにより、こちらも常駐シングルトンになっています。

  • NetworkRunnerプレファブ
  • NetworkManagerプレファブ
  • SessionItemUIプレファブ(セッション一覧のUI要素)
  • セッションアイテムの親
  • ロビー関連のUnityEvent

NetworkRunnerの生成および破棄、セッションの作成と参加を処理しています。

INetworkRunnerCallbacksからセッションリスト更新をOnSessionListUpdated()に受け取り、UI要素を生成します。

やっていること自体はPUNとあまり違いが無さそうです。

PlayerObjectクラス

重要★★☆
セッション中に存在するプレイヤー1人分の情報を持つオブジェクトです。

  • ニックネーム
  • カラー
  • コントローラへの参照
  • ローカルプレイヤーへの参照
public static PlayerObject Local { get; private set; }

PlayerRegistryクラス

重要★★★
生成されたPlayerObjectを受け取って保持し、アクセスを提供します。
常駐シングルトンです。

  • プレイヤーの最大数
  • プレイヤーの数
  • 観戦者の数
  • 観戦者とプレイヤーを区分けしたPlayerObjectの一覧
  • UIクラスへ提供するためのネットワークコールバック

InterfaceManagerクラス

重要★★☆
Menuシーンにあります。
ゲーム全体のUIへのアクセスを提供する常駐シングルトンです。

  • メインメニュー画面
    image.png

  • インゲーム画面
    image.png

  • オプション画面
    image.png

  • ホスト設定画面
    image.png

  • クライアント設定画面
    image.png
    ソースコードからではなく"Join Button"のEventTriggerで表示されます。

  • セッション画面
    image.png
    この時点でセッションは作成済みです。

  • ステージリザルト画面
    image.png

  • パフォーマンス(個人のスコア)画面
    image.png

  • ポーズ画面
    image.png

  • ゲームリザルト画面
    image.png

  • ニックネーム用ワールドキャンバス

  • 画面表示切替用の参照(UIScreen)

その他、ゲーム開始カウントダウンアニメーションとショートカットキーからの画面制御も行っています。

GameStateクラス

重要★★★
シングルトンです。
PlayerRegistryにより常駐します。
ネットワーク上でゲームの状態を管理し、プレイヤー間で共有します。

  • 現在のステート
  • 直前のステート
  • 遅延時間
  • 遅延用ステート

状態を変更するにはServer_SetState()とServer_DelaySetState()を使います。
後者を使うと指定秒数遅延(ゲーム終了後に自動でロビーに戻す)します。
以下のステートを切替えながら同期を取っています。

ステート名 設定タイミング
Off 初期状態
Pregame スポーンされた直後
Loading ゲームスタート時
Outro遷移時に全ステージを完了していないとき
Intro カウントダウン中
Game Intro開始後(遅延)
Outro 全員がゴールしたとき
Postgame Outro遷移時に全ステージを完了していたとき

Postgameに入ったときの処理例

StateMachine[EGameState.Postgame].onEnter = prev =>
{
	Level.Unload();
	InterfaceManager.Instance.postgameUI.SetWinner(PlayerRegistry.OrderDesc(p => p.TotalScore).First());
	UIScreen.Focus(InterfaceManager.Instance.postgameUI.screen);
	Server_DelaySetState(EGameState.Pregame, 5);
};

Pregameに入ったときの処理例

StateMachine[EGameState.Pregame].onEnter = prev =>
{
	if (prev == EGameState.Postgame)
	{
		Runner.SetActiveScene("Menu");
		if (!Runner.SessionInfo.IsOpen) Runner.SessionInfo.IsOpen = true;
		UIScreen.activeScreen.BackTo(InterfaceManager.Instance.sessionScreen.screen);
	}
};

GameManagerクラス

重要★★★
シングルトンです。
PlayerRegistryにより常駐します。
重要ではありますが、やっていることはほとんどありません。

  • GameState _gameState:GameStateクラスの参照
  • int CourseLengthIndex:コースの数
  • int MaxTimeIndex:制限時間
  • int MaxStrokesIndex:最大ショット数
  • bool DoCollisions:他プレイヤーと衝突させるか

static PlayerDNF(PlayerObject player)

最大ショット回数によりプレイヤーをリタイアさせ、ステージ終了判定を行います。

static CalculateScores()

全プレイヤーのスコアを計算し、PlayerObjectに格納します。

Rpc_LoadDone()

PlayerObjectのIsLoadedフラグをオンにします。
PlayerObejctが単純にスポーンされるとこのメソッドを呼びます。
全員がオンになると、GameStateクラスがステートをIntroに切り替えます。

Rpc属性に渡されている[HostMode = RpcHostMode.SourceIsHostPlayer]がポイントで、
これが無いとサーバモードの挙動として扱われ、ホストのPlayerRefが入らずNoneになります。
PUNには無かった概念ですが、明示的に指定する必要があります。

Levelクラス

重要★★☆
継承:NetworkBehaviour

1レベル(ステージ)の構成です。
地形メッシュの他、Levelプレファブ自体をロードする役割を持ちます。

image.png

  • static Current:現在のLevel
  • プレイヤーを出現させる高さ

static Load(Level level)

このクラスそのものが引数として与えられたレベルプレファブをSpawnします。
呼び出しタイミングは以下です。

  • ゲームシーンがロードされたとき
  • OutroステートからLoadingに遷移したとき

static Unload()

現在ロードされているLevelを破棄します。
Load()の前に行います。

Spawned()

Currentに自身を格納します。
GameManagerへロード完了を通知します。

Vector3 GetSpawnPosition(int index)

プレイヤーの生成位置を計算します。

PlayerSpawnerPrototypeクラス

重要★☆☆
PlayerObjectを自動生成するユーティリティクラスです。

NetworkSceneManagerDefaultクラス

重要★☆☆
シーン遷移を行うユーティリティクラスです。
ピアの種類別の処理や、ネットワークオブジェクトのシーン移動をよしなにやってくます。
このサンプルはユーティリティで事足りるのに、シーン1つで完結しているProjectilesの方は独自実装しているのが謎なので、後日詳しく見てみます。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?