This document is about: QUANTUM 2
SWITCH TO

Quantum 103 - Player Character

概述

Quantum 103介紹了一個角色,其使用一個角色控制器來移動。它也提供了在Quantum中開始撰寫遊戲遊玩程式碼的指引。

角色實體設定

在遊戲場景中建立一個新的角色控制器實體(Quantum > 3d > Character Controller Entity)。將它命名為PlayerCharacter並且設定物件的轉換到(2, 2, 0)。

請注意,這個實體附有啟用的PhysicsCollider3D,以及一個在實體原型單行為中新增的CharacterController3D元件。

  • 角色控制器3D控制角色的移動。設置欄位提供了一個設置,來調校角色控制器的行為。可在Resources/DB/Configs中找到預設設置。針對這個教學,將使用預設設置。
  • 與Unity角色控制器不同,在Quantum中的角色控制器不作為碰撞器。物理碰撞器3D元件作為實體的碰撞器,並且匹配視覺效果球體的大小。
playercharacter inspector

通常需要為實體提供存取到實體之間共享的資料的權限,而且與没有特定一個單一實體的元件資料有所不同。在Quantum中,這透過資產設置檔案來完成。可透過程式碼建立或在Unity中的可指令碼物件上定義設置檔案。角色控制器有一個設置檔案,其儲存關於角色控制器如何移動及互動的資訊。

按下遊玩模式。正如您所看到,實體還沒有移動,也不受重力的影響。需要一個程式碼實作來使角色控制器工作。

開啟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框架目標套件。

您現在已經準備好開始撰寫遊戲遊玩程式碼。

遊戲遊玩程式碼

以右鍵按一下在解決方案瀏覽器中的quantum_code專案檔案,並且選擇Add > New Directory。將目錄命名為Platformer

add a new directory
新增一個新的目錄。

現在以右鍵按一下新建立的Platformer資料夾。選擇Add > Class。然後在彈出視窗中再次選擇類別,設定名稱為MoventCharacterSystem.cs,然後按一下Add按鈕。

add a the movementsystem
新增MovementSystem.cs。

已建立一個類別檔案,其含有以下文字:

C#

namespace Quantum.Platformer
{
    class MovementSystem
    {
    }
}

在ECS中撰寫遊戲遊玩程式碼的最常見的模式是,有一個系統來迭代實體的集合,这些實體含有元件的清單。有了Quantum ECS,這可以使用一個系統主執行緒篩選器來完成。

首先新增一個篩選器架構到移動系統類別:

C#

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

各個篩選器必須總是含有一個實體參照欄位,以及的任何數量的元件指標欄位,以進行篩選。針對在篩選器中的元件類型總是使用指標。

新增publicunsafe關鍵字到類別,並且讓它繼承自SystemMainThreadFilter<MovementSystem.Filter>類別:

C#

public unsafe class MovementSystem : SystemMainThreadFilter<MovementSystem.Filter>

以下列程式碼來新增一個抽象Update功能的覆寫:

C#

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

更新功能針對有所有在篩選器中的元件的各個實體,在各個幀上運行一次。幀參數代表了系統運行的目前的幀,並且針對該特定幀來提供到完整遊戲狀態的存取。

這個程式碼簡單地調用角色控制器的移動功能,並且傳送預設零向量到它之中。這意味著角色控制器不會嘗試向任何方向移動,但是實體將被重力所影響。

然而這個程式碼目前還不會運行。為了讓系統運行,它需要在SystemSetup.cs檔案中註冊。開啟檔案並且新增下列程式碼到使用宣告。

C#

using Quantum.Platformer;

在這之後,在user systems go here評論之下新增下列行。

C#

// user systems go here
new MovementSystem(),

最後,註解化那些新增Core.CullingSystem2DCore.PhysicsSystem2DCore.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(),
      };
    }
  }
}

在系統設定中的系統,按照清單中所列的確切順序來被執行。

為了完成移動實作,還有最後一步。因為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特定檔案,其使用Quantum網域特定語言(DSL)。DSL的語法類似於C#。DSL用於定義實體元件資料及輸入資料。遊戲遊玩系統是在C#之中進行。

新增下列程式碼到Input.qtn檔案:

C#

input
{
    button Jump;
    FPVector2 Direction;
}

輸入是Quantum中的一個特殊關鍵字。Quantum使用輸入同步,因此透過網路只發送輸入而非遊戲狀態。這裡定義的input是將透過網路發送的,並且用作為遊戲遊玩模擬的輸入的資料。

注意事項: 輸入在每個刷新被發送,而且用於經常變動並且影響即時的遊戲遊玩的輸入。示例包含移動及按按鈕。針對不需要預測的不規則的少量輸入,請使用命令

FP向量2類型是Unity向量2類型的Quantum相等版本。Quantum使用固定點(FP)而非浮動,以保證模擬在各個裝置之間是確定性的。稍後將填入方向向量的水平及垂直輸入軸。

跳躍按鈕將用於讓玩家跳躍。按鈕類型是一個Quantum特定類型,並且應該用於所有按鈕輸入。請不要針對按鈕輸入來使用布林值。它們使用了更多頻寬。

現在我們已經定義了輸入,按下組建(ctrl + shift + b)。這將運行DSL編譯器,並且使輸入在C#類別中可用。

注意事項: 為了在您的IDE中新增針對DSL檔案的語法聚焦顯示支援,請遵循這裡的指引。

更新移動系統

現在該輸入可用,請開啟移動系統,並使用以下的程式碼來替換在更新功能中的程式碼。

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