This document is about: QUANTUM 3
SWITCH TO

5 - Player Spawning

概述

創建玩家角色實體後,接下來的步驟是為加入遊戲的每個玩家生成一個玩家角色,並將玩家的輸入連結到實體。

玩家預製件

目前,該船是一個場景物件。Quantum可以在運行時生成實體,類似於單人Unity遊戲中運行時生成預製件的方式。透過將AsteroidsShip遊戲物件從場景拖動到Resources資料夾中,將船變成預製件。完成此操作後,從場景中刪除“AsteroidsShip

The AsteroidsShip Prefab

請注意,EntityPrototypeEntityView檔案是如何巢狀在預製件中創建的。Quantum使用這些來生成實體並將其連結到Unity視圖。

玩家連結元件

Quantum有玩家的概念。每個客戶端可以擁有一個或多個玩家。然而,Quantum沒有內建的玩家物件/虛擬人偶概念。每個連接到遊戲的玩家都有一個唯一的ID。這個ID稱為PlayerRef。要將實體連結到特定玩家,我們將創建一個PlayerLink元件,其中包含所有者的PlayerRef

Assets/QuantumUser/Simulation資料夾中創建一個PlayerLink.qtn檔案,並向其中新增以下程式碼:

C#

component PlayerLink
{
    player_ref PlayerRef;
}

玩家資料

為了動態生成角色,我們需要讓遊戲程式碼知道它應該創建哪個實體。Quantum有玩家資料的概念。玩家資料允許每個玩家在連接時將資訊傳遞到模擬中。它可以是玩家選擇的角色或使用的皮膚等資訊。

預設下,玩家資料包含一個Avatar實體和一個Player Nickname,但資料也可以在Photon/QuantumUser/Simulation/RuntimePlayer.User.cs檔案中擴展。

為了生成玩家實體,我們將使用預先定義的虛擬人偶欄位。AssetRefEntityPrototype在Quantum中相當於預製件。

進入遊玩模式時,Quantum模擬會自動運行。這是由Unity中QuantumGameScene場景中QuantumDebugRunner遊戲物件上的QuantumRunnerLocalDebug元件驅動的。此元件用於在本機運行單人版的Game以進行開發。

QuantumLocalRunnerDebug允許模擬任意數量的本機玩家。在Local Players下的QuantumLocalRunnerDebug中,將AsteroidsShip預製件下找到的AsteroidsShipEntityPrototype檔案拖放到玩家的Player Avatar欄位中。

Inspector view of the QuantumDebugRunner

現在預製件已經連結到玩家資料,剩下的就是編寫程式碼,以在玩家加入時生成實體。

生成玩家物件

創建一個新的ShipSpawnSystem.cs類別。新增以下程式碼:

C#

using UnityEngine.Scripting;

namespace Quantum.Asteroids
{
    [Preserve]
    public unsafe class ShipSpawnSystem : SystemSignalsOnly, ISignalOnPlayerAdded
    {
        public void OnPlayerAdded(Frame frame, PlayerRef player, bool firstTime)
        {
            {
                RuntimePlayer data = frame.GetPlayerData(player);

                // resolve the reference to the avatar prototype.
                var entityPrototypAsset = frame.FindAsset<EntityPrototype>(data.PlayerAvatar);

                // Create a new entity for the player based on the prototype.
                var shipEntity = frame.Create(entityPrototypAsset);

                // Create a PlayerLink component. Initialize it with the player. Add the component to the player entity.
                frame.Add(shipEntity, new PlayerLink { PlayerRef = player });
            }
        }
    }
}

當玩家加入時,此程式碼會創建船實體,並透過向其新增PlayerLink元件,將其連結到玩家。

訊號類似於C#中的事件。它們被Quantum系統用來相互通信。Quantum附帶了許多現有的訊號,例如ISignalOnPlayerAdded,該訊號在玩家加入遊戲階段並共享其玩家資料後被調用。

SystemSignalsOnly是一種特殊類型的系統,它沒有更新常式,這使得它更精簡,只能用於對訊號做出反應。

ShipSpawnSystem新增到AsteroidsShipConfig資產中AsteroidsShipSystem之後的系統清單中。

更新運動

到目前為止,AsteroidsShipSystem中的飛船運動總是使用玩家0的輸入進行移動:

C#

var input = f.GetPlayerInput(0);

用以下程式碼替換它,以從連結的玩家獲取輸入:

C#

Input* input = default;
if(f.Unsafe.TryGetPointer(filter.Entity, out PlayerLink* playerLink))
{
    input = f.GetPlayerInput(playerLink->PlayerRef);
}

請注意,篩選器尚未調整,因此系統仍將篩選具有PhysicsBody2D但沒有PlayerLink元件的實體。在這種情況下,它將使用default值作為輸入。除了施加重力外,這不會導致任何運動。這種模式使得透過傳遞來自不同來源的輸入來新增人工智慧控制的船變得容易。

在Quantum中使用TryGet獲取元件非常快O(1),因為Quantum使用稀疏集ECS。

f.Unsafe提供了對Quantum的不安全API的存取,該API通常比無指標的API更快速、更方便地使用。但是,如果您希望避免使用指標,則可以使用安全的API,如f.Get

切換到Unity並進入遊玩模式。飛船將被生成,並對鍵盤輸入做出反應。

Back to top