5 - プレイヤーのスポーン
概要
プレイヤーキャラクターのエンティティを作成した後は、ゲームに参加したプレイヤー毎にプレイヤーキャラクターをスポーンして、プレイヤーの入力とエンティティを連携します。
プレイヤーのプレハブ
現在、船はシーン上のオブジェクトです。Unityのシングルプレイヤーゲームでプレハブを実行時に生成するのと同じように、Quantumもエンティティを実行時にスポーンできます。シーンのAsteroidsShip
ゲームオブジェクトをResources
フォルダーにドラッグして、船をプレハブにしましょう。そしたら、シーンのAsteroidsShip
は削除します。

EntityPrototype
と、プレハブ内にEntityView
ファイルが作成されます。これらは、エンティティをスポーンしたり、そのエンティティをUnityのビューと連携したりするために使用されます。
PlayerLinkコンポーネント
Quantumには「プレイヤー」の概念があります。各クライアントは、1つまたは複数のプレイヤーを持ちます。ただし、Quantumに「プレイヤーオブジェクト/アバター」の概念はありません。ゲームに接続した各プレイヤーにはユニークなIDが与えられ、このIDはPlayerRef
と呼ばれます。エンティティを特定のプレイヤーと紐づけるために、所有者のPlayerRef
を持つPlayerLink
コンポーネントを作成します。
Assets/QuantumUser/Simulation
フォルダーにPlayerLink.qtn
ファイルを作成し、以下のコードを追加してください。
C#
component PlayerLink
{
player_ref PlayerRef;
}
プレイヤーのデータ
動的にキャラクターをスポーンするには、どのエンティティを作成すべきなのかをゲームプレイコードに知らせる必要があります。Quantumには「プレイヤーデータ」の概念があり、各プレイヤー接続時に、シミュレーションに情報を渡すことができます。情報とは、プレイヤーが選択したキャラクターや使用中のスキンなどです。
プレイヤーデータはデフォルトでAvatar
エンティティとPlayer Nickname
を含んでいますが、このデータはPhoton/QuantumUser/Simulation/RuntimePlayer.User.cs
ファイルから拡張できます。
プレイヤーエンティティをスポーンするために、定義済みのavatar
フィールドを使用します。QuantumではAssetRefEntityPrototype
がプレハブと同等のものになります。
ゲームを再生すると、Quantumのシミュレーションが自動的に実行されます。これは、UnityのQuantumGameScdne
上のQuantumDebugRunner
ゲームオブジェクトのQuantumRunnerLocalDebug
コンポーネントによって動作しています。このコンポーネントは、開発中にGame
をシングルプレイヤーバージョンでローカルに実行するために使用されます。
QuantumLocalRunnerDebug
は、複数のローカルプレイヤーをシミュレートできます。AsteroidsShip
プレハブにあるAsteroidsShipEntityPrototype
ファイルを、QuantumLocalRunnerDebug
のLocal Players
のPlayer Avatar
フィールドにドラッグ&ドロップしてください。

これでプレハブがプレイヤーデータに紐づいたので、後はプレイヤー参加時にエンティティをスポーンするコードを記述するだけです。
プレイヤーオブジェクトのスポーン
新しくShipSpawnSystem.cs
クラスを作成して、以下のコードを追加します。
C#
using UnityEngine.Scripting;
namespace Quantum.Asteroids
{
[Preserve]
public unsafe class ShipSpawnSystem : SystemSignalsOnly, ISignalOnPlayerAdded
{
public void OnPlayerAdded(Frame frame, PlayerRef player, bool firstTime)
{
{
RuntimePlayer data = frame.GetPlayerData(player);
// resolve the reference to the avatar prototype.
var entityPrototypAsset = frame.FindAsset<EntityPrototype>(data.PlayerAvatar);
// Create a new entity for the player based on the prototype.
var shipEntity = frame.Create(entityPrototypAsset);
// Create a PlayerLink component. Initialize it with the player. Add the component to the player entity.
frame.Add(shipEntity, new PlayerLink { PlayerRef = player });
}
}
}
}
このコードでは、プレイヤー参加時に船のエンティティを作成して、そこにPlayerLink
コンポーネントを追加することでプレイヤーを連携させています。
「シグナル」はC#のイベントと似ていて、Quantumのシステム間のやり取りに使用されます。Quantumには様々な既存のシグナルが用意されていて、ISignalOnPlayerAdded
はプレイヤーがセッションに参加してプレイヤーデータが共有された後に呼び出されます。
SystemSignalsOnly
は特別なシステムの型で、更新ルーチンを持たず、軽量にシグナルへ反応するためだけに使用されます。
AsteroidsShipConfig
アセットのシステムリストで、AsteroidsShipSystem
の後にShipSpawnSystem
を追加してください。
移動の更新
今までは、AsteroidsShipSystem
の船の移動には、常にプレイヤー0の入力を使用していました。
C#
var input = f.GetPlayerInput(0);
コードを以下に置き換えて、連携したプレイヤーの入力を取得しましょう。
C#
Input* input = default;
if(f.Unsafe.TryGetPointer(filter.Entity, out PlayerLink* playerLink))
{
input = f.GetPlayerInput(playerLink->PlayerRef);
}
フィルターは調整していないので、PhysicsBody2D
を持ちPlayerLink
を持たないエンティティもフィルタリングされていることに注意してください。このケースでは入力のdefault
値が使用され、移動せずに重力が適用されます。このパターンによって、異なるソースからの入力を渡すAI操作の船の追加が簡単になります。
Quantumはsparse set ECSを使用しているため、TryGet
を使用したコンポーネントの取得はO(1)
で非常に高速です。
f.Unsafe
はQuantumのunsafeなAPIへのアクセスを提供していて、一般的に高速で、ポインターを使わない方より使いやすいです。ポインタの使用を避けたい場合は、f.Get
のような安全なAPIも使用できます。
Unityに戻り、ゲームを再生しましょう。船がスポーンして、キーボード入力に反応します。
Back to top