Materialization
概述
從一個Component Prototype
或Entity Prototype
來建立一個實體或元件執行個體的流程稱為 具體化 。
內嵌於地圖場景的場景原型的具體化,遵循與使用Frame.Create
API的程式碼建立的執行個體的具體化的相同的規則及執行流程。
原型 vs 執行個體
元件執行個體及實體執行個體是遊戲狀態的一部分;換句話說,可以在運行階段操控它們。在DSL中宣告的元件用於生成它們的相應的Component Prototypes
。程式碼生成的原型遵循命名慣例MyComponent_Prototype
。
Component Prototypes
及Entity Prototypes
都是 資產;這意味著它們不是遊戲狀態的一部分,在運行階段不可變,並且在所有時間都必須對於所有客戶端而言完全相同。各個Component Prototype
有一個ComponentPrototypeRef
,其可使用 Frame.FindPrototype<MyComponentName_Prototype>(MyComponentPrototypeRef)
來找出相應的資產。
元件原型
可以延伸一個Component Prototype
以包含不直接用於具體化的資料。舉例而言,這允許在特定元件的執行個體之間共享資料,或從幀中排除唯讀資料,以保持遊戲狀態精簡。
程式碼生成的Component Prototypes
是部分類別,其可輕易被延伸:
- 建立一個C#檔案名為
MyComponentName_Prototype.cs
; - 將指令碼主體放入
Quantum.Prototypes
命名空間; - (選擇性)新增
using Quantum.Inspector;
以存取Manual \ ECS
頁面的Attributes
章節中呈現的檢查器屬性。
之後可以新增額外的資料到Component Prototype
資產,並且執行部分MaterializeUser()
方法以新增自訂具體化邏輯。
例子
以下例子呈現了Vehicle
元件的具體化,其出現於街機賽車範本之中。
Vehicle
元件主要保有運行階段時計算的動態值。由於這些無法被初始化,在DSL中的元件定義使用這些參數上的ExcludeFromPrototype
屬性,以從設計師可在Unity編輯器中操控的Vehicle_Prototype
資產中排除它們。Nitro
參數是唯一可編輯部分,以讓設計師決定一個特定的Vehicle
要初始化多少Nitro。
C#
component Vehicle
{
[ExcludeFromPrototype]
ComponentPrototypeRef Prototype;
[ExcludeFromPrototype]
Byte Flags;
[ExcludeFromPrototype]
FP Speed;
[ExcludeFromPrototype]
FP ForwardSpeed;
[ExcludeFromPrototype]
FPVector3 EngineForce;
[ExcludeFromPrototype]
FP WheelTraction;
[ExcludeFromPrototype]
FPVector3 AvgNormal;
[ExcludeFromPrototype]
array<Wheel>[4] Wheels;
FP Nitro;
}
延伸Vehicle_Prototype
資產以提供設計師可自訂的唯讀參數。Vehicle_Prototype
資產可因此保有針對一個特定車輛實體原型「類型」的所有執行個體的共享的值。在Vehicle
元件中的Prototype
參數屬於類型ComponentPrototypeRef
,其是等同於AssetRef
的元件特定。為了填入它,使用部分MaterializeUser()
方法,以指派Vehicle_Prototype
的參照。
C#
using Photon.Deterministic;
using Quantum.Inspector;
using System;
namespace Quantum.Prototypes
{
public unsafe partial class Vehicle_Prototype
{
// PUBLIC METHODS
[Header("Engine")]
public FP EngineForwardForce = 130;
public FP EngineBackwardForce = 120;
public FPVector3 EngineForcePosition;
public FP ApproximateMaxSpeed = 20;
[Header("Hand Brake")]
public FP HandBrakeStrength = 10;
public FP HandBrakeTractionMultiplier = 1;
[Header("Resistances")]
public FP AirResistance = FP._0_02;
public FP RollingResistance = FP._0_10 * 6;
public FP DownForceFactor = 0;
public FP TractionGripMultiplier = 10;
public FP AirTractionDecreaseSpeed = FP._0_50;
[Header("Axles")]
public AxleSetup FrontAxle = new AxleSetup();
public AxleSetup RearAxle = new AxleSetup();
[Header("Nitro")]
public FP MaxNitro = 100;
public FP NitroForceMultiplier = 2;
// PARTIAL METHODS
partial void MaterializeUser(Frame frame, ref Vehicle result, in PrototypeMaterializationContext context)
{
result.Prototype = context.ComponentPrototypeRef;
}
[Serializable]
public class AxleSetup
{
public FPVector3 PositionOffset;
public FP Width = 1;
public FP SpringForce = 120;
public FP DampingForce = 175;
public FP SuspensionLength = FP._0_10 * 6;
public FP SuspensionOffset = -FP._0_25;
}
}
}
Vehicle_Prototype
中的參數保有必要的值,以計算元件執行個體中找到的動態值,該元件執行個體影響Vehicle
元件附加的實體的行為。舉例而言,當玩家選取額外的Nitro
,保存在Vehicle
元件中的值被夾鉗到Vehicle_Prototype
中找到的MaxNitro
值。這將強制執行在取消同步懲罰下的限制,並保持遊戲狀態精簡。
C#
namespace Quantum
{
public unsafe partial struct Vehicle
{
public void AddNitro(Frame frame, EntityRef entity, FP amount)
{
var prototype = frame.FindPrototype<Vehicle_Prototype>(Prototype);
Nitro = FPMath.Clamp(Nitro + amount, 0, prototype.MaxNitro);
}
}
}
具體化順序
對於每個Entity Prototype
,包含場景原型,具體化時按照順序執行以下步驟:
- 建立一個空的實體。
- 針對各個包含在
Entity Prototype
之中的Component Prototype
:- 在堆疊上建立元件執行個體;
Component Prototype
被具體化到元件執行個體;- ( 選擇性 )調用
MaterializeUser()
;及, - 元件被新增到實體,其觸發
ISignalOnComponentAdded<MyComponent>
信號。
- 針對各個已具體化實體,
ISignalOnEntityPrototypeMaterialized
被叫用。- 載入地圖/場景:在所有場景原型已經被具體化之後,針對所有實體及
Entity Prototype
配對,叫用信號。 - 以
Frame.Create()
被建立:在原型已經被具體化之後,立即叫用信號。
- 載入地圖/場景:在所有場景原型已經被具體化之後,針對所有實體及
Component Prototype
具體化步驟以一個預先確定的順序來具體化預設元件。
C#
Transform2D
Transform3D
Transform2DVertical
PhysicsCollider2D
PhysicsBody2D
PhysicsCollider3D
PhysicsBody3D
PhysicsJoints2D
PhysicsJoints3D
PhysicsCallbacks2D
PhysicsCallbacks3D
CharacterController2D
CharacterController3D
NavMeshPathfinder
NavMeshSteeringAgent
NavMeshAvoidanceAgent
NavMeshAvoidanceObstacle
View
MapEntityLink
當所有預設元件已經被具體化,使用者定義的元件以字母順序被具體化。
C#
MyComponentAA
MyComponentBB
MyComponentCC
...
Back to top