Golf Sample
ターンベースのフレームワーク統合
Golfサンプル では、ターンベースのフレームワーク機能をいくつか使用しています。これらの機能については、次のセクションで詳しく説明し、以下に簡単に要約します。
各プレイヤー には、グローバルな現在のターン データから 統計を蓄積する ための独自のターンデータインスタンスがあります。
プレイヤーのターンステータスもターンシステムによって更新されます。
Play/Skip Command Received シグナルがフレームワークによってトリガーされて、現在アクティブなプレイヤーから有効な Play/Skip Command が受信されると、Play System がボールを打つ物理学関連のロジックを実行します。また、Skipコマンドの場合、ターンシステムはターン終了シグナルをトリガーするため、ターンは別のプレイヤーに渡されます。
フレームワークのPlay Command Dataは、ボールの打つ方向と力 としてそれぞれ使用される FPVector3
と FP
をラップします。これらは、Play Command を介してプレイヤーによって送信されます。
ターンシステムによって ターン終了 シグナルがリッスンされると、プレイヤーがプレイをスキップまたは解決したときに 他のプレイヤーのターンを有効にする などのターン関連のロジックが実行されます。プレイヤーのターンデータインスタンスのターンデータの統計情報 を蓄積し、グローバルな現在のターンフィールドをリセットします。
また、Game End and Score Systems によってリッスンされ、それぞれゲーム終了条件を確認およびスコアを更新します。
ゲームモデル
ゲームには、配列の初期化とボールエンティティの最大数の定義に使用される定数を介して、最大数2のプレイヤーがあります**。
Spawn Pointは、スポーンポイントのタイプ、その位置、どのエンティティがスポーンされているかを決定する構造体です。
タイプはNear Holeです。これは、Game Config assetで[Spawn Balls Near Hole]を選択したときに使用されるスポーンポイントです。または、通常のゲームでボールをスポーンするRegularタイプにすることができます。
ユーザーマップアセットインスタンスを介して渡されるデータに基づいてSpawn System で初期化されるスポーンポイントのグローバル配列データ。
ゲームが終了すると、ゲームプレイ終了イベント が発生してUnityに通知され、視覚的なフィードバックを表示できます。
すべてのゲーム終了条件が満たされると、ゲーム終了システムによって発生します。
C#
#define MAX_PLAYERS 2
asset ConfigAssets;
asset GameConfig;
asset UserMap;
enum SpawnPointType { Regular, NearHole }
struct SpawnPoint
{
SpawnPointType Type;
Boolean IsAvailable;
FPVector3 Position;
entity_ref Entity;
}
global
{
array<SpawnPoint>[4] SpawnPoints;
}
synced event GameplayEnded { }
ボールモデル
ボールモデルは Ball.qtn
ファイルで定義され、以下のフィールドで構成されます:
-Actor: このエンティティを所有するプレイヤーへの参照を保持するコンポーネント。
アクターのアクティベーション状態は、プレイヤーが現在このゲームでアクティブであるかどうかを表し、保存されたファイルからゲームを読み込むときに使用されます。
-Turn Stats: グローバルな現在のターンデータから統計を蓄積 するターンデータ構造体のインスタンス。
Turn Statusはターンシステムによって更新され続けます。
-Last Position: 打つ前のボールの最後の位置を表します。
Rough Fieldに着地する際、ボールの位置をリセットするために使用されます。
-Has Completed Course: プレイヤーがボールをコースのホールに入れることによって現在のコースを完了したかどうかを表します。
Play Systemによって確認および更新されます。
-End of Movement Timer: ボールが停止したと見なされるまでPlay System によって増加するタイマー。
-Score: プレイヤーのプレイターンが終了すると、スコアシステムによって更新されます。
プレイヤーがまだコースを完了していない場合は0です。
それ以外の場合、コースの最大ストローク数に1を足した値から、プレイヤーがボールをホールに入れるために必要なストローク数を引いたものです。
-On Ball Shot Signal: ボールが打たれたときにトリガーされるシグナル。
たとえば、Turn SystemがTurn StatusをResolvingに設定するために使用されます。
-Input: プレイヤーがボールを打つときに送信するPlay Command に加えて、プレイヤーは現在の照準方向で入力を送信し、バーマークの位置を強制して、他のプレイヤーが照準を複製できるようにします。
これらの値は視覚的なフィードバックを目的としたものであり、プレイヤーが実際にボールを打つときは考慮されませんが、その場合でも、入力コマンドとPlay Commandの照準方向の値は同じです。
C#
asset BallSpec;
component Actor
{
Boolean Active;
player_ref Player;
}
entity Ball[MAX_PLAYERS]
{
use Transform3D;
use DynamicBody3D;
use Prefab;
use Actor;
fields
{
TurnData TurnStats;
FPVector3 LastPosition;
Boolean HasCompletedCourse;
Int32 EndOfMovementTimer;
Int32 Score;
}
}
signal OnBallShot(Ball* b);
input
{
FPVector3 Direction;
FP ForceBarMarkPos;
}
ゲームアセット
Config アセット
フレームワークのTurn ConfigアセットやGame Config(以下を参照)など、ゲームの他のすべてのConfigアセットへのアセットリンクを保持するデータアセット。
Unityでアセットを初期化し、Quantumで直列化するプロセスを容易にするために使用され、データアセットの新しいタイプやインスタンスをゲームに追加するプロセスを容易にします。
このサンプルでは、 ConfigAssets.cs
ファイルで宣言されています:
C#
public partial class ConfigAssets
{
public GameConfigLink GameConfig;
public BallSpecLink BallSpec;
public TurnConfigLink StartCountdownConfig;
public TurnConfigLink PlayTurnConfig;
public TurnConfigLink CountdownTurnConfig;
}
It is initialized and serialized on RuntimeConfig.User.cs
:
C#
partial class RuntimeConfig
{
public ConfigAssetsLink ConfigAssets;
partial void SerializeUserData(BitStream stream)
{
stream.Serialize(ref ConfigAssets.Guid);
}
}
Unity側では、このデータ資アセットのインスタンスは、ローカルデバッグモード でプレイするために、Quantum Runner Local Debugで初期化されます。

また、オンラインモード でプレイするときの UIRoom.cs
スクリプトで:
C#
RuntimeConfig config;
config.ConfigAssets.Guid = UnityDB.AllOf<ConfigAssetsAsset>().First().Settings.Guid;
新しいカスタムデータアセットを追加するには、 ConfigAssets.cs
ファイルにそのリンクを追加し、プロジェクトをビルドして、カスタムアセットインスタンスをUnityのConfig Assetsインスタンスにドラッグアンドドロップします。
ゲーム Config
一般的にゲームのシミュレーションで使用される値を保持するデータアセット:
-Spawn Balls Near Hole:Spawn Systemによって使用され、RegularまたはNear Holeのスポーンポイントタイプ(#game-model)でボールをスポーンするかどうかを決定します。
-Min-Max Strike Angle and Force: Play Systemがボールの打撃を制限するために使用する最小値と最大値。
-Force Bar Velocity: Unityからポーリングされ、プレイヤーが照準を合わせているときにフォースバーのマーキング位置を更新します。
-Hit Hole Velocity Threshold: ホールコライダーをトリガーするときに、ボールがホールにヒットしたと見なされる速度の値。
-Hole Bump Force: 「Hit Hole Velocity Threshold」よりも大きい速度でホールを打ったときにボールに加わる垂直方向の力。
-Hole Trigger and Rough Field Layers: Hole TriggerとRough Fieldの物理レイヤー名の文字列フィールド。ボールが静的コライダーに当たったとき、それらのレイヤーを検出するためにPlay Systemが使用します。
C#
public partial class GameConfig {
public Boolean SpawnBallsNearHole;
public Int32 MinStrikeAngle;
public Int32 MaxStrikeAngle;
public Int32 MinStrikeForce;
public Int32 MaxStrikeForce;
public Int32 ForceBarVelocity;
public Int32 HitHoleVelocityThreshold;
public Int32 HoleBumpForce;
public string HoleTriggerLayer;
public string RoughFieldLayer;
}
ユーザーマップ
プレイヤーが特定のコース(マップ)を完了するまでに打つことができる最大ストローク数など、マップ固有のデータを保持するデータアセット。Game End System、Score System、およびマップ固有のスポーンポイントの配列で使用されます(Game Modelをご確認ください)。
C#
public partial class UserMap
{
public Int32 MaxStrokes;
public SpawnPoint[] SpawnPoints;
}
ボールスペック
ボール関連データを保持するデータアセット:
-Radius: ボールの球体コライダーの半径
-Mass: ボールの動的体重
-Physics Mat: ボールの物理素材へのリンク
-End of Movement Velocity Threshold: ボールがまだ動いていると見なされる速度の大きさの値。
-End of Movement Waiting in Ticks: ボールが動きを止めた後、プレイの終了を宣言するまでPlay System が待つティック数。
-Player 1 Prefab Name: シミュレーションの最初のプレイヤーのボールをUnityのプレハブにリンクするために使用される名前。
-Player 2 Prefab Name: シミュレーションの二人目のプレイヤーのボールをUnityのプレハブにリンクするために使用される名前。
-Layer Name: ボールの物理レイヤー名。
C#
partial class BallSpec
{
public FP Radius;
public FP Mass;
public PhysicsMaterialLink PhysicsMat;
public FP EndOfMovementVelocityThreshold;
public Int32 EndOfMovementWaitingInTicks;
public string Player1PrefabName;
public string Player2PrefabName;
public string LayerName;
}
Golfシステム
セットアップシステム
Actor、Dynamic Body、Prefabコンポーネントの初期化や、プレイヤーのTurn Dataインスタンスのリセット、ボールのスポーンなど、プレイヤーデータの受信時の初期ボールのセットアップを処理します(以下のSpawn Systemを確認してください)。
また、以前に保存されたゲームを読み込む際のプレイヤーデータの初期化も処理します。
この場合、プレイヤーデータをリセットする必要はなく、以前のゲームデータが新しいプレイヤー参照にマップされます。
スポーンシステム
初期化時に、User Map アセットを介して渡されたマップスポーンポイントを読み、それらをグローバルスポーンポイント配列に割り当てます。次に、ボールのスポーンがリクエストされると(上記セットアップシステムを確認)、そのボールの位置を最初の利用可能なスポーンポイントに更新して、次にスポーンポイントを無効にします。ボールを穴の近く(ゲームConfig)、また、現在のスポーンタイプにスポーンするかどうかも考慮します。
Play System
プレイヤーから送信されたPlay Commandデータに基づいてボールを打つことにより、ボールの物理学を処理し、コースのホールおよび外側のRough Fieldでトリガーされた衝突を判断します。
有効なPlay Commandを受信すると、システムは「Game Config アセット」で定義された値に従ってストライクデータ(方向と力)をクランプします。次に、Dynamic Bodyに力を加えてボールを打って、On Ball Shot signalをトリガーします。
グローバルな現在のターンステータスがResolvingの場合(つまりボールが動いている)、システムはその動きが終了したかどうか、すべてのティックで確認して、その速度の大きさをBall Spec アセット。
速度がしきい値を下回る場合、動作終了タイマー は、ボール仕様でも定義されている待機時間に達するまで増加します。
ボールが停止時にRough Field静的コライダー(外側の濃い緑色のフィールド)をトリガーしている場合、その位置は、ストライキが発生する前の位置にリセットされます。

プレイが終了すると、そのプレイヤーのターンがインアクティブである間の不要な相互作用を避けるために、ボールのダイナミックボディは無効になります。
次に、システムはターン終了シグナルをトリガーして、それをターンシステムに伝えます。
ボールが「Hole」レイヤーで静的コライダーをトリガーし、その速度が所定のしきい値(Game Config アセット)を下回ると、 その場合、ホールにボールが入りコースを完了した と認識されるので、プレイも終了します。
ターンシステム
ターンベースのフレームワーク機能を使用して、ターン関連のロジックを処理します。
ボールが打たれたら(上記Play Systemをご確認ください)、アクティブプレイヤーとグローバルカレントターンのステータスをResolvingにリセットします。
有効なスキップコマンドがアクティブプレイヤーから受信されると、Turn Endedシグナルをトリガーします。
ターン終了がトリガーされると、ターンタイプを確認します:Countdown ターンの場合、次のターンに適格なボールがあれば次のボールのターンをアクティブにします。Play ターンの場合、各プレイヤーのターンデータに グローバルカレントターンの統計を蓄積し、** プレイヤーのステータスをインアクティブにリセットして**、Config AssetsのCountdown Turn Configに従って、global current turnの*TypeをCountdown**にリセットします。
スコアシステム
Play ターンが終了すると、次のルールに従ってアクティブなボールのスコアを変える更新が行われます: ボールが コースを完了した場合(ホールに入った場合)、スコアは、マップ(User Map アセット)で許可されている最大ストローク数に1を足した値から、プレイヤーがボールをホールに入れるために打ったストローク数を引いたものです。ボールが コースを完了していない場合、スコアは0です。
ゲーム終了システム
ターンが終了すると、ゲーム終了条件を確認します。これは、すべてのボールがそのマップ(User Map アセット)で許可されている最大ストローク数に達した場合、またはコースを完了している場合(ホールに入った場合)はtrueになります。
その場合、グローバルでの現在のターンデータはデフォルトにリセットされ、[ゲームプレイ終了イベント]((#game-model)が発生します。
Unity
カメラ
CameraController.cs
はメインのカメラ移動制御を処理します。
これにはダミー変換があります。これは、実際のカメラが常に向かっている位置と回転値です。また、ターゲットエンティティ。があります。これは、カメラが現在見ているエンティティプレハブルートコンポーネントを持つゲームオブジェクトであり、グローバルの現在のターン エンティティが更新されると自動的に更新されます。

コントローラは、カメラのパン、チルト、ズーム へのプレイヤー入力を読み取りを行い、以下を行うためのフィールドを持ちます。:
-Relative Position: 対象エンティティに対するカメラの位置。
-Relative Rotation: カメラが相対的な位置に配置され、ターゲットエンティティを見ている後にカメラに加えられる回転量。
-Follow Target: カメラが移動中に対象エンティティを追跡するかどうかを決定します。
-Lerp velocity: 実際のカメラをダミー変換に向けるときに使用されるステップ係数。
-Zoom Sensitivity: ターゲットエンティティを拡大および縮小するときに使用されるスケール係数。
-Closest Distance: 対象エンティティを拡大するときに許容される最も近い距離。
-Farthest Distance: 対象エンティティをズームアウトする際に許容される最も遠い距離。
-Rotation Sensitivity: プレイヤーがカメラをパンまたはチルトしているときに使用されるスケール係数。
-Invert Rotation: マウスのドラッグ値は、カメラをパンまたはチルトする前に反転します。
-Target clickable area radius: クリックされたと見なされるターゲットエンティティの周りの円の半径。
入力
入力マネージャー
クライアントマシンは複数のローカルプレイヤーを持つことができるため、Input Managerはこれらのプレイヤーの入力を読み取り、各Unityフレームアップデートの他の入力スクリプトで処理するユーザーを制御します。
マウスボタンイベントなど、他のスクリプトが登録する さまざまな入力イベント用のC#静的イベント があります。
Input Poller
Quantumシミュレーションは、Unityからの入力を指定された速度でポーリングします(決定論的構成 の 入力送信速度 を確認)。
InputPoller.cs
は、ローカルプレイヤーの最後に登録された入力を読み取り、シミュレーションに挿入 を送信します。
入力データは、登録されてから、そのプレイヤーからの別の入力によって上書きされるまで、またはそのプレイヤーのターンが終了するまで保存されます。その場合、登録された入力はデフォルト値にリセットされます。
これは、照準データ(Aiming Displayを確認)が**照準を合わせているプレイヤーがリモートの場合はシミュレーションからポーリングされますが、ローカルの場合 は入力ポーラーの 登録済みの入力 からポーリングされるので、視覚的な反応がよりシャープになります。
Strike Input
StrikeInput.cs
登録のためにアクティブなプレイヤーの照準入力 とポーラーを入力ポーラーで送信します。
このスクリプトは、入力マネージャーによって送信されたアクティブなローカルプレイヤーからの入力イベントをリッスンし、マウスドラッグを適用して照準方向を更新し、フォースバーマーキング位置も絶えず更新します。
ストライク入力には次のフィールドがあります:
-Aim Sensitivity: マウスをドラッグして撮影方向を変更するときに使用されるスケール係数。
-Reverse Controls: 入力ドラッグ値は、打つ方向に適用される前に反転されます。
-Clamp Direction: 必要に応じて、Game Config アセットのmin-maxストローク角度の値(シミュレーションでもダブルチェックされます)および最大ストローク開始値(UIのみ。シミュレーションではクランプされません)に従って、照準方向の角度がクランプされます。
-Max Strike Opening Angle: 照準を開始したときのカメラの向きに対する最大開口角度。
プレイヤーが照準を合わせてマウスボタンを離すと、現在の照準方向とフォースバーマーキングの位置とともに Play Command(以下を確認)がリクエストされます。
Player Commands
CommandDispatcher.cs
は、特定のプレイヤーがリクエストしたすべてのPlayコマンドとSkipコマンドをシミュレーションに送信するために使用されます。
Player UI
Aiming Display
AimingDisplay.cs
は、プレイヤーが照準を合わせているときに視覚的特徴(方向矢印とフォースバー)を更新します。
プレイヤーがローカル の場合、照準を合わせると、入力ポーラーからそのプレイヤーの 登録された入力をポーリングして(上記のセクションを確認してください)よりシャープな視覚的応答性を実現します。プレイヤーがリモート の場合、照準を合わせると、そのプレイヤーの シミュレーションからの最新の入力をポーリングします。

Turn Clock
UITurnClock.cs
は、タイマーを使用するアクティブターンの場合、シミュレーションからグローバルの現在のターンの残りのターン持続時間をポーリングし、セントラル時計パネルの表示時間を更新します。

Start Countdown
UIStartCountdown.cs
は、最初のターンが始まる前に画面の中央に視覚的なタイマーカウントダウンを表示します。

Player View
UIPlayerView.cs
は、プレイヤーのターンが終了したときに ターン番号 を増やすなど、特定のプレイヤーのターンデータ情報をポーリングし、視覚要素を有効化/無効化/更新します。また、プレイヤーのステータスが変更されたときに ステータステキスト を変更したり、ターンがアクティブでない場合やプレイヤーがローカルでない場合に スキップボタン をインタラクト不能にして、プレイヤーの 充填可能なリングタイマー を更新します。

Custom Interpolation
CustomInterpolation.cs
は、エンティティプレハブのルート位置補間値を、ローカルプレイヤーとリモートプレイヤーに属するエンティティのカスタム値で上書きします。

Save Game
Save Game ボタンは、現在のゲームの状態 をファイルに保存します。ファイルは、ゲームプレイを続行するために別の瞬間に読み込むことができます。
デフォルトの保存ファイル名はgamesave
ですが、指定された入力フィールドにファイル名を入力することで変更できます。
以前に保存したゲームを読み込む には、ルームに入った後、Menu Sceneでファイル名を入力します(または、ファイルがデフォルト名で保存された場合は空白のままにします)。

Score
UIScore.cs
は、Gameplay Ended event がシミュレーションによって発生したときに、プレイヤーのスコア情報を含むスコアパネルを有効にします。

Spawn Points
Spawn Pointコンポーネントは、ゲームオブジェクトに追加 して、マップベイク処理 中に見つけられるようにすることができます。
これらは、様々なタイプにすることができます。これは、ゲームオブジェクトコンポーネントからシミュレーション内のSpawn Point構造体インスタンスに変換されます。
SpawnPointsBaker.cs
は、Map Data Bakerコールバックを実装して、シーンからスポーンポイントデータを読み取り、それらをシミュレーションに送信される現在のマップ上のユーザーマップアセット に追加します。

