Photon Quantum3 Commandの使い方

コマンドについて

コマンドは毎フレーム値を変更する(ポーリング)必要のないデータをシュミレーション側に送信するシステムです。
コマンドが実行されるのには遅延があります。

手順

  1. Commandで送信するデータを任意のシリアライズ可能なデータを作成するクラスを作成。
  2. CommandをQuantumに登録する
  3. UnityからCommandを呼び出す
  4. シュミレーション側で送られた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);
         }
    }
}

コメント

タイトルとURLをコピーしました