This document is about: QUANTUM 2
SWITCH TO

Quantum 103 - プレイヤーキャラクター

概要

Quantum 103 では、キャラクタ コントローラを使って移動するキャラクタを紹介します。また、Quantum でゲームプレイのコードを書き始めるための説明もあります。

キャラクタ・エンティティのセットアップ

Game シーンに新しいキャラクタ・コントローラ・エンティティを作成します (Quantum > 3d > Character Controller Entity)。名前を PlayerCharacter とし、オブジェクトのトランスフォームを (2, 2, 0) に設定します。

このエンティティは PhysicsCollider3D が有効になっており、EntityPrototype MonoBehaviour に CharacterController3D コンポーネントが追加されていることに注意してください。

  • CharacterController3Dはキャラクターの動きを制御する。configフィールドはキャラクターコントローラーの動作を微調整するための設定を提供します。デフォルトの設定は、Resources/DB/Configsにあります。このチュートリアルでは、デフォルトの設定が使用されます。
  • UnityのCharacterControllerとは異なり、Quantumのキャラクターコントローラはコライダーとして動作しません。PhysicsCollider3Dコンポーネントは、エンティティのコライダーとして動作し、ビジュアル球のサイズに合わせます。
PlayerCharacter Inspector

エンティティ間で共有されるデータや、コンポーネントデータとは異なり、特定のエンティティに依存しないデータへのアクセスをエンティティに与える必要がある場合があります。Quantumでは、これはアセット設定ファイルによって行われます。設定ファイルは、コードで作成するか、Unity の ScriptableObjects で定義します。キャラクターコントローラには、キャラクターコントローラの動きやインタラクションに関する情報を格納したコンフィグファイルがあります。

プレイモードを押してみてください。ご覧の通り、このエンティティはまだ動いておらず、重力の影響も受けません。キャラクターコントローラを動作させるためには、コードの実装が必要です。

Quantum コード プロジェクトを開く

Quantumのゲームプレイは、quantum_codeというc#プロジェクトで書かれています。プロジェクトを開くには、Visual Studio または Rider の新しいインスタンスを開いてください。

  • Visual Studio では Open a project or solution を選択してください。
  • Rider では Open を選択します。
    quantum_code フォルダにある .sln ファイルを検索して選択します。

Visual Studioを使用している場合、.NETフレームワークのバージョンをアップグレードするように指示するポップアップが表示されるかもしれません。推奨されるバージョンをダウンロードするよう選択してください。

Prompt to update .NET Framework
ターゲティングパックをダウンロードする

Riderを使用する場合、ソリューションを開いた後、ctrl + shift + bを押してください。エラーメッセージのウィンドウが表示されたら、指示に従ってMicrosoftから.NET Framework Targeting Packをダウンロードしてください。

これで、ゲームプレイコードを書き始める準備ができました。

ゲームプレイコード

ソリューションエクスプローラーでquantum_codeプロジェクトファイルを右クリックし、Add > New Directory を選択します。ディレクトリ名はPlatformerとします。

Add a new directory
新しいディレクトリを追加

次に、新しく作成した Platformer フォルダを右クリックします。Add > Class を選択します。そして、ポップアップで再びクラスを選択し、名前を MoventSystem.cs に設定して、Add ボタンをクリックします。

Add a the MovementSystem
MovementSystem.csを追加します。

以下のテキストを含むクラスファイルが作成されました。

C#

namespace Quantum.Platformer
{
    class MovementSystem
    {
    }
}

ECSでゲームプレイのコードを書く際に最もよくあるパターンは、コンポーネントのリストを含むエンティティのコレクションをシステムが反復処理することです。Quantum ECSでは、システムのメインスレッドフィルタを使って、これを実現することができます。

まず、MovementSystemクラスにフィルター構造体を追加します。

C#

public struct Filter
{
    public EntityRef Entity;
    public CharacterController3D* CharacterController;
}

各フィルタには、必ず EntityRef フィールドと、フィルタリングするコンポーネント ポインタ フィールドを任意の数だけ含める必要があります。フィルタのコンポーネントタイプには、常にポインタを使用します。

publicunsafe キーワードを追加し、 SystemMainThreadFilter<MovementSystem.Filter> クラスを継承するようにします。

C#

public unsafe class MovementSystem : SystemMainThreadFilter<MovementSystem.Filter>

Add an override of the abstract Update function with the following code:

C#

public override void Update(Frame f, ref Filter filter)
{
    // note: pointer property access via -> instead of .
    filter.CharacterController->Move(f, filter.Entity, default);
}

更新関数は、フィルター内のすべてのコンポーネントを持つ各エンティティについて、各フレームで1回ずつ実行されます。frameパラメータはシステムが動作している現在のフレームを表し、その特定のフレームに対する完全なゲーム状態にアクセスすることができます。

このコードでは、キャラクターコントローラの移動関数を呼び出し、デフォルトのゼロベクターを渡しているだけです。これは、キャラクターコントローラがどの方向にも動こうとせず、エンティティが重力の影響を受けることを意味します。

しかし、このコードはまだ実行されません。システムを動かすには、SystemSetup.cs ファイルに登録する必要があります。このファイルを開いて、using宣言に以下を追加してください。

C#

using Quantum.Platformer;

その後、user systems go here のコメントの下に以下の行を追加してください。

C#

// user systems go here
new MovementSystem(),

最後に、Core.CullingSystem2DCore.PhysicsSystem2DNavigationSystemを追加する行をコメントアウトします。
Core.NavigationSystemを追加する行をコメントアウトします。このシリーズで作成されるゲームでは、これらは使用されません。

SystemSetup ファイルは次のようにします。

C#

using Photon.Deterministic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Quantum.Platformer;

namespace Quantum {
  public static class SystemSetup {
    public static SystemBase[] CreateSystems(RuntimeConfig gameConfig, SimulationConfig simulationConfig) {
            return new SystemBase[] {
        // pre-defined core systems
        // new Core.CullingSystem2D(),
        new Core.CullingSystem3D(),

        // new Core.PhysicsSystem2D(),
        new Core.PhysicsSystem3D(),

        Core.DebugCommand.CreateSystem(),

        // new Core.NavigationSystem(),
        new Core.EntityPrototypeSystem(),
        new Core.PlayerConnectedSystem(),

        // user systems go here
        new MovementSystem(),
      };
    }
  }
}

SystemSetupに含まれるシステムは、リストアップされた順番に実行されます。

動きの実装を完成させるために、最後のステップが残っています。quantum_code プロジェクトは別のプロジェクトなので、ビルドする必要があります。ビルド (ctrl + shift + b) を押してください。

重要: quantum_code プロジェクトを変更したときは、Unity プロジェクトで変更を反映させるためにビルドする必要があります。

Unityエディタに戻り、プレイモードにします。キャラクター球はKCC重力の影響を受けるようになりましたが、キーボード入力にはまだ反応しません。

入力

Platformer フォルダを右クリックします。Add > New Itemを選択します。新しいウィンドウがポップアップするので、Visual C# Items > General > Text Fileを選択し、ファイル名をInput.qtnにしてAddボタンをクリックします。

Add the text file
テキストファイル」を選択し、「Input.qtn」という名前をつけます

Qtnファイルは、Quantumドメイン固有言語(DSL)を用いたQuantum特有のファイルです。DSLの構文はC#に似ています。DSLはエンティティコンポーネントデータと入力データの定義に使用されます。ゲームプレイ系はC#です。

Input.qtnファイルに以下を追加します。

C#

input
{
    button Jump;
    FPVector2 Direction;
}

inputはQuantumの特別なキーワードです。Quantum は input sync を使用するので、ゲーム状態ではなく入力だけがネットワーク上に送信されます。ここで定義される input は、ネットワーク上で送信され、ゲームプレイシミュレーションの入力として使用されるデータです。

注意: 入力はtickごとに送信され、頻繁に変化し、リアルタイムのゲームプレイに影響を与える入力に使用されます。例としては、移動とボタン操作が挙げられます。予測を必要としない不定期なレア入力には、commandsを使用してください。

FPVector2 型は、Unity の Vector2 型と同等の Quantum 型です。Quantum では浮動小数点ではなく固定小数点(FP)を使用し、デバイス間で決定論的なシミュレーションができることを保証しています。方向ベクトルには、後で水平と垂直の入力軸を記入します。

ジャンプボタンは、プレイヤーをジャンプさせるために使用されます。ボタンタイプはQuantum固有のタイプで、すべてのボタン入力に使用する必要があります。ボタン入力にブーリアンは使わないでください。より多くの帯域幅を使用します。

これで入力が定義できたので、build (ctrl + shift + b) を押してください。これでDSLコンパイラが実行され、C#のクラスで入力が利用できるようになります。

__ 注意:__ DSLファイルのシンタックスハイライトをIDEに追加するには、ガイドここに従ってください。

Movement System を更新する

入力が可能になったので、MovementSystem を開き、Update 関数内のコードを以下のコードに置き換えます。

C#

public override void Update(Frame f, ref Filter filter)
    {
        // gets the input for player 0
        var input = *f.GetPlayerInput(0);

        if (input.Jump.WasPressed)
        {
            filter.CharacterController->Jump(f);
        }

        filter.CharacterController->Move(f, filter.Entity, input.Direction.XOY);
    }

Unity入力の接続

Unityプロジェクト内のPhoton/QuantumDemo/Game/Scripts/LocalInputスクリプトを開いてください。このスクリプトは、Unityの入力を収集し、Quantumエンジンに渡す役割を担っています。スクリプト内のコードを以下のように置き換えてください。

C#

using Photon.Deterministic;
using Quantum;
using UnityEngine;

public class LocalInput : MonoBehaviour
{
    private void Start()
    {
        QuantumCallback.Subscribe(this, (CallbackPollInput callback) => PollInput(callback));
    }

    public void PollInput(CallbackPollInput callback)
    {
        Quantum.Input input = new Quantum.Input();

        // Note: Use GetButton not GetButtonDown/Up Quantum calculates up/down itself.
        input.Jump = UnityEngine.Input.GetButton("Jump");

        var x = UnityEngine.Input.GetAxis("Horizontal");
        var y = UnityEngine.Input.GetAxis("Vertical");

        // Input that is passed into the simulation needs to be deterministic that's why it's converted to FPVector2.
        input.Direction = new Vector2(x, y).ToFPVector2();

        callback.SetInput(input, DeterministicInputFlags.Repeatable);
    }
}

これで、再びプレイモードに入ると、キャラクターはWASDキーで移動し、spaceキーでジャンプすることができます。

Player movement in Unity editor
Back to top