물질화
소개
컴포넌트 프로토타입
또는 엔티티 프로토타입
에서 컴포넌트 또는 컴포넌트 인스턴스를 생성하는 프로세스가 물질화(Materialization) 입니다.
맵 에셋에 베이크 된 씬 프로토타입의 물질화는 Frame.Create
API를 사용하여 코드 작성 인스턴스를 물질화하는 것과 동일한 규칙과 실행 흐름을 따릅니다.
프로토타입 vs 인스턴스
컴포넌트 인스턴스와 엔티티 인스턴스는 게임 상태의 일부입니다. 즉, 런타임에 조작할 수 있습니다. DSL에 선언된 컴포넌트는 해당하는 컴포넌트 프로토타입
을 생성하는 데 사용됩니다. 코드 생성 프로토타입은 MyComponent_Prototype
이라는 명명 규칙을 따릅니다.
컴포넌트 프로토타입
과 엔티티 프로토타입
은 둘 다 에셋 이며, 이는 게임 상태의 일부가 아니며 런타임에 변하지 않으며 모든 클라이언트에서 항상 동일해야 함을 의미합니다. 각 컴포넌트 프로토타입
에는 ComponentPrototypeRef
가 있으며, Frame.FindPrototype<MyComponentName_Prototype>(MyComponentPrototypeRef)
을 사용하여 해당하는 에셋을 찾는 데 사용할 수 있습니다.
컴포넌트 프로토타입
컴포넌트 프로토타입은 구현에 직접 사용되지 않을 수 있는 데이터를 포함하도록 확장할 수 있습니다. 이를 통해 특정 컴포넌트의 인스턴스 간에 데이터를 공유하거나 프레임에서 읽기 전용 데이터를 제외하여 게임 상태를 슬림 하게 유지할 수 있습니다.
코드 생성 컴포넌트 프로토타입
은 쉽게 확장할 수 있는 부분 클래스입니다.
MyComponentName_Prototype.cs
라는 C# 파일을 만듭니다.- 스크립트 바디를
Quantum.Prototypes
네임스페이스로 넣습니다. - ( 선택 ) 인스펙터 속성에 접근하기 위해
설명서 \ ECS
의속성
섹션에 설명되어 있는using Quantum.Inspector;
을 추가합니다.
그러면 컴포넌트 프로토타입
에셋에 추가 데이터를 추가하고 partial MaterializeUser()
메소드를 구현하여 사용자 정의 물질화 로직을 추가할 수 있습니다.
예제
다음 예는 아케이드 레이싱 템플릿에서 볼 수 있는 차량
컴포넌트의 물질화를 보여줍니다.
차량
컴포넌트는 주로 런타임에 계산된 동적 값을 보유합니다. 이러한 매개 변수는 초기화할 수 없으므로 DSL의 컴포넌트 정의는 해당 매개 변수에 대해 ExcludeFromPrototype
속성을 사용하여 에셋 설계자가 유니티 편집기에서 조작할 수 있는 Vehicle_Prototype
에서 제외합니다. Nitro
매개 변수는 디자이너가 특정 Vehicle
의 초기화 정도를 결정할 수 있도록 편집할 수 있는 부분일 뿐입니다.
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
에셋은 특정 차량 엔티티 프로토타입 "type"의 모든 인스턴스에 대한 공유 값을 보유할 수 있습니다. Vehicle
컴포넌트의 Prototype
매개 변수는 AssetRef
에 해당하는 컴포넌트별 ComponentPrototypeRef
타입입니다. 이를 채우기 위해 partial 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);
}
}
}
물질화 순서
씬 프로토타입을 포함한 모든 엔티티 프로토타입
의 물질화는 다음 순서로 실행됩니다:
- 빈 엔티티가 생성됩니다.
엔티티 프로토타입
에 포함된 각컴포넌트 프로토타입
에 대해 다음을 수행합니다.- 컴포넌트 인스턴스가 스택에 생성됩니다.
컴포넌트 프로토타입
은 컴포넌트 인스턴스로 물질화됩니다.- ( 선택 )
MaterializeUser()
가 호출됩니다. ISignalOnComponentAdded<MyComponent>
시그널을 트리거 하는 엔티티에 컴포넌트가 추가됩니다.
- 물질화된 각 엔티티에 대해
ISignalOnEntityPrototypeMaterialized
가 실행됩니다.- 맵 / 씬 로드 : 시그널을 모든 씬 프로토타입을 물질화한 후 모든 엔티티와
엔티티 프로토타입
쌍에 대해 호출됩니다. Frame.Create()
으로 생성: 시그널을 프로토타입이 구체화된 후 즉시 호출됩니다.
- 맵 / 씬 로드 : 시그널을 모든 씬 프로토타입을 물질화한 후 모든 엔티티와
컴포넌트 프로토타입
의 구체화 단계는 기본 컴포넌트를 미리 정해진 순서대로 구체화합니다.
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