コマンドについて
コマンドは毎フレーム値を変更する(ポーリング)必要のないデータをシュミレーション側に送信するシステムです。
コマンドが実行されるのには遅延があります。
手順
- Commandで送信するデータを任意のシリアライズ可能なデータを作成するクラスを作成。
- CommandをQuantumに登録する
- UnityからCommandを呼び出す
- シュミレーション側で送られたCommandを取得
コード
// 1.Commandで送信する任意のシリアライズ可能なデータを作るクラスを作成
// Project->Create->Quantum->Command
// Simulationフォルダー内に作成
// Commandとして送信するデータを作成するクラス
using Quantum;
public class SomethingCommand : DeterministicCommand
{
// FPデータをシュミレーションに渡したい
public FP SomethingFP;
// FPVector3データをシュミレーションに渡したい
public FPVector3 SomethingFPVector3;
// このメソッド内に渡したいデータをBitStreamに渡す
public override void Serialize(BitStream stream)
{
// 初期化渡す値をrefで初期化する
stream.Serialize(ref SomethingFP);
stream.Serialize(ref SomethingFPVector3);
}
// コマンドが実行された時、実行するメソッド
public void Exceute(Frame frame)
{
Log.Debug($"受信したデータFP:{SomethingFPValue},FPVector3:{SomethingFPVector3}");
}
}
// 2.CommandをQuantumに登録する
// Project->Asset->QuantumUser->Simulation->CommandSetup.User.cs
namespace Quantum {
using System.Collections.Generic;
using Photon.Deterministic;
public static partial class DeterministicCommandSetup {
static partial void AddCommandFactoriesUser(ICollection<IDeterministicCommandFactory> factories, RuntimeConfig gameConfig, SimulationConfig simulationConfig) {
// ココに追加したいDeterministicCommandを継承したCommandを記述
factories.Add(new SomethingCommand());
}
}
}
// 3.UnityからCommandを呼び出す
public class SamethingClass
{
public void ButtonPush()
{
// 送信するコマンドを作成
var command = new SomethingCommand()
{
SomethingFP = FP._10,
SomethingFPVector3 = FPVector3.zoro,
}
// コマンドを呼び出す
QuantumRunner.Default.Game.SendCommand(command);
}
}
// .qtn
// 4.シュミレーション側で送られたCommandを取得、例1の時
component PlayerLink
{
PlayerRef Player;
}
// 4.シュミレーション側で送られたCommandを取得
// コマンドを受け取るSystem
// 例1
public unsafe class CommandsRelatedToSystem : SystemMainThreadFilter<CommandsRelatedToSystem.Filter>
{
public override void Update(Frame frame, ref Filter filter)
{
// コマンドを実行したプレイヤのコマンドを取得する
if (frame.GetPlayerCommand(filter->Player.Player) is SomethingCommand command)
{
// コマンドを実行する
command.Exceute(frame);
}
}
public class Filter
{
public EntityRef Entity;
public PlayerLink* Player; // .qtnの作成が必要
}
}
// 例2
public unsafe class CommandsRelatedToSystem : SystemMainThread
{
public override void Update(Frame frame)
{
// 参加しているPlayerの数だけ繰り返す
for (int i = 0; i < frame.MaxPlayerCount; i++)
{
// Commandを実行したPlayerならデータを取得
var command = frame.GetPlayerCommand(i) as CommandSpawnEnemy;
// Commandがあれば実行
command?.Execute(frame);
}
}
}

コメント