Quantum 104 - プレイヤーのスポーニング
概要
プレイヤーキャラクターのエンティティを作成した後は、ゲームに参加するプレイヤーごとにプレイヤーキャラクターを生成し、プレイヤーの入力をエンティティにリンクさせるという手順が必要です。
プレイヤーキャラクターのプレファブ
現在、キャラクターはシーンオブジェクトです。Quantumは、1人用のUnityゲームでプレハブを実行時に生成できるのと同様に、エンティティを実行時に生成することができます。シーンから PlayerCharacter
GameObject を Resources/DB
フォルダにドラッグして PlayerCharacter
プレファブを作成します。その後、PlayerCharacter
をシーンから削除してください。
プレハブの下に EntityPrototype
と EntityView
ファイルが作成されていることに注目してください。これらは Quantum がエンティティを生成し、Unity のビューにリンクさせるために使用されます。
重要: Quantum のすべてのプレハブは Resources/DB
フォルダかそのサブフォルダ内にある必要があります。外部にあるプレハブには、EntityPrototype
ファイルは作成されません。
プレイヤーリンクコンポーネント
Quantumはプレイヤーという概念を持っています。各クライアントは、1つまたは複数のプレーヤーを持つことができます。しかし、Quantumには、プレイヤーオブジェクト/アバターという概念は組み込まれていません。ゲームに接続された各プレイヤーには、一意のIDが与えられます。このIDは PlayerRef
と呼ばれます。エンティティを特定のプレイヤーにリンクさせるには、オーナーの PlayerRef
を含む PlayerLink コンポーネントを作成します。
quantum-code
プロジェクトの Platformer
フォルダに PlayerLink.qtn
ファイルを作成し、次のコードを追加します。
C#
component PlayerLink
{
player_ref Player;
}
プレイヤーデータ
キャラクターを動的に生成するためには、ゲームプレイコードにどのようなエンティティを生成するかを知らせる必要があります。Quantumにはプレイヤーデータという概念があります。プレイヤーデータにより、各プレイヤーは接続時にシミュレーションに情報を渡すことができます。これは、プレイヤーがどのキャラクターを演じているか、どのスキンを使っているかなど、あらゆる情報を伝えることができます。
プレイヤーデータ
は RuntimePlayer.User
ファイルにあります。quantum_code
プロジェクトの RuntimePlayer.User
ファイルを開き、その内容を以下のように置き換えます。
C#
using Photon.Deterministic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Quantum
{
partial class RuntimePlayer
{
public AssetRefEntityPrototype CharacterPrototype;
partial void SerializeUserData(BitStream stream)
{
stream.Serialize(ref CharacterPrototype);
}
}
}
ビルド(ctrl + shift + b
)を押してください。
このコードでは、プレハブに相当する AssetRefEntityPrototype
をプレイヤーデータに追加しています。これはプレハブに相当するもので、後でプレイヤーキャラクターの実体を生成するために使用されます。
IMPORTANT: RuntimePlayer
クラスに追加されるすべてのデータは SerializeUserData
関数でシリアライズする必要があります。BitStream
はすべての基本的な型のシリアライズを提供します。
プレイモードに入ると、Quantum シミュレーションが自動的に実行されます。これは Unity の Game
シーンの QuantumRunnerDebug
GameObject にある QuantumLocalRunnerDebug
コンポーネントによって駆動されます。このコンポーネントは、開発用にローカルで Game
のシングルプレイヤー版をデバッグするために使用されます。
QuantumLocalRunnerDebug
では、任意の人数のローカルプレイヤーをシミュレートすることができます。 QuantumLocalRunnerDebug
の Players
の下に新しいエントリーを追加してください。このエントリには CharacterPrototype
フィールドが含まれていますが、これは以前にプレイヤーデータに追加されたフィールドです。このフィールドに、プレハブ PlayerCharacter
の下にある PlayerCharacterEntityPrototype
ファイルをドラッグ&ドロップしてください。
プレハブとプレイヤーデータの連携が完了したので、あとはプレイヤーが参加したときにエンティティをスポーンするコードを書くだけです。
プレイヤーオブジェクトを生成する
Create a new PlayerSpawnsystem.cs
class. Add the following code:
C#
namespace Quantum.Platformer
{
unsafe class PlayerSpawnSystem : SystemSignalsOnly, ISignalOnPlayerDataSet
{
public void OnPlayerDataSet(Frame frame, PlayerRef player)
{
var data = frame.GetPlayerData(player);
// resolve the reference to the prototype.
var prototype = frame.FindAsset<EntityPrototype>(data.CharacterPrototype.Id);
// Create a new entity for the player based on the prototype.
var entity = frame.Create(prototype);
// Create a PlayerLink component. Initialize it with the player. Add the component to the player entity.
var playerLink = new PlayerLink()
{
Player = player,
};
frame.Add(entity, playerLink);
// Offset the instantiated object in the world, based in its ID.
if (frame.Unsafe.TryGetPointer<Transform3D>(entity, out var transform))
{
transform->Position.X = 0 + player;
}
}
}
}
このコードでは、プレイヤーが参加したときにキャラクターの実体を作り、それにPlayerLinkコンポーネントを追加することでプレイヤーにリンクさせます。
シグナルは、C#のイベントに似ています。Quantumのシステムが互いに通信するために使用されます。例えば、ISignalOnPlayerDataSet
はプレイヤーがセッションに参加し、プレイヤーデータを共有した後に呼び出されるシグナルです。
SystemSignalsOnlyは、それ自身では何もしない特別なタイプのシステムです。シグナルを聞くだけのシステムを実装することができます。
PlayerSpawnSystem を SystemSetup.cs
の MovementSystem
の後のシステムのリストに追加してください。
MovementSystemのアップデート
今までMovementSystemは常に0プレイヤーからの入力を使って次のようなコードで移動していました。
C#
var input = *f.GetPlayerInput(0);
これを次のように置き換えると、リンク先のプレイヤーから入力されるようになります。
C#
Input input = default;
if(f.Unsafe.TryGetPointer(filter.Entity, out PlayerLink* playerLink))
{
input = *f.GetPlayerInput(playerLink->Player);
}
フィルターは調整されていないため、システムは引き続き CharacterController を持つが PlayerLink コンポーネントを持たないエンティティをフィルター処理することに注意してください。この場合、入力には default
値が使用されます。重力以外の動きはありません。
QuantumのTryGet
を使ったコンポーネントの取得は、QuantumがスパースセットECSを使っているため、O(n)と非常に高速になります。
ビルド(ctrl + shift + b
)を押してUnityに切り替えてプレイモードにします。すでにシーンにいるキャラクターに加えて、プレイヤーキャラクターが生成され、キーボード入力に反応するようになります。