DOTS v1.2.1
EntityPrefabReference란?
Prefab을 런타임 중에 Entity 로 생성할 때 사용하는 구조체이다.
DOTS에서 Prefab을 Entity로 생성하는 방법
DOTS에서 Prefab을 Entity로 생성하는 방법에는 복제와 참조 두 가지 방식이 있다.
보통은 복제하는 방식을 사용하지만, 게임의 규모가 큰 게임의 경우 여러 SubScene이 존재하는 경우는 참조하는 방식을 사용한다. 왜냐하면 복제의 경우 SubScene에서 이미 Baking 된 Prefab을 다른 SubScene에서 사용하려면 또 베이킹을 해야하기 때문이다. 참조의 경우는 하나의 SubScene에서 Baking을 했다면 참조를 통해 다른 SubScene에서도 Baking없이 Entity로 생성할 수 있다.
1. 복제하는 방법
베이킹으로 MonoBehaviour에 멤버변수로 등록된 Prefab을 Entity로 만드는 방법이다.
■ 코드 예제
using Unity.Collections;
using Unity.Entities;
using UnityEngine;
namespace PrefabReference
{
public class GetPrefabAuthoring : MonoBehaviour
{
public GameObject Prefab;
class Baker : Baker<GetPrefabAuthoring>
{
public override void Bake(GetPrefabAuthoring authoring)
{
// 프리팹을 등록하고
var entityPrefab = GetEntity(authoring.Prefab, TransformUsageFlags.Dynamic);
// 스포너에 EntityPrefabComponent 추가
var entity = GetEntity(TransformUsageFlags.None);
AddComponent(entity, new EntityPrefabComponent(){
Value = entityPrefab
});
}
}
}
public struct EntityPrefabComponent : IComponentData
{
public Entity Value;
}
public partial struct InstantiatePrefabSystem : ISystem
{
public void OnUpdate(ref SystemState state)
{
var ecb = new EntityCommandBuffer(Allocator.Temp);
foreach (var prefab in
SystemAPI.Query<RefRO<EntityPrefabComponent>>())
{
// Entity 생성.
ecb.Instantiate(prefab.ValueRO.Value);
}
ecb.Playback(state.EntityManager);
ecb.Dispose();
}
}
}
2. 참조하는 방법
베이킹할 때 EntityPrefabReference를 통해 Entity를 참조시킨다.
System에서 참조시킨 Entity를 생성할 때 조금 복잡한 절차가 필요하다.
1. RequestEntityPrefabLoaded 컴포넌트를 추가한다.
2. RequestEntityPrefabLoaded 가 추가되면 프리팹 로드가 요청된다.
3. 로드가 완료되면 Entity에게 PrefabLoadResult 컴포넌트가 추가된다.
4. prefabLoadResult.PrefabRoot 를 통해 Entity를 인스턴스화(생성) 한다.
■ 코드 예제
using Unity.Collections;
using Unity.Entities;
using Unity.Entities.Serialization;
using Unity.Scenes;
using UnityEngine;
namespace PrefabReference
{
public struct EntityPrefabReferenceComponent : IComponentData
{
public EntityPrefabReference Value;
}
public class GetPrefabReferenceAuthoring : MonoBehaviour
{
public GameObject Prefab;
class Baker : Baker<GetPrefabReferenceAuthoring>
{
public override void Bake(GetPrefabReferenceAuthoring authoring)
{
// Prefab의 래퍼런스를 만든다.
var entityPrefab = new EntityPrefabReference(authoring.Prefab);
// 스포너에 EntityPrefabReferenceComponent 추가
var entity = GetEntity(TransformUsageFlags.Dynamic);
AddComponent(entity, new EntityPrefabReferenceComponent() {Value = entityPrefab});
}
}
}
public partial struct InstantiatePrefabReferenceSystem : ISystem
{
public void OnStartRunning(ref SystemState state)
{
var query = SystemAPI.QueryBuilder()
.WithAll<EntityPrefabReferenceComponent>()
.WithNone<PrefabLoadResult>().Build();
// query로 조회된 Entity들에게 RequestEntityPrefabLoaded를 추가한다.
// RequestEntityPrefabLoaded가 추가된 Entity는 Load를 시작한다.
state.EntityManager.AddComponent<RequestEntityPrefabLoaded>(query);
}
public void OnUpdate(ref SystemState state)
{
var ecb = new EntityCommandBuffer(Allocator.Temp);
// RequestEntityPrefabLoaded로 인하여 로드가 완료된 Entity에게는
// PrefabLoadResult 가 추가된다.
foreach (var (prefab, entity) in
SystemAPI.Query<RefRO<PrefabLoadResult>>().WithEntityAccess())
{
var instance = ecb.Instantiate(prefab.ValueRO.PrefabRoot);
// Entity 생성에만 필요한 두개의 컴포넌트를 삭제한다.
ecb.RemoveComponent<RequestEntityPrefabLoaded>(entity);
ecb.RemoveComponent<PrefabLoadResult>(entity);
}
ecb.Playback(state.EntityManager);
ecb.Dispose();
}
}
}
'Unity DOTS > Dots Custom Manual' 카테고리의 다른 글
UNITY DOTS - Dynamic Buffer Component 에 대해 알아보자. (0) | 2022.08.02 |
---|---|
UNITY DOTS - BLOB assets 에 대해 알아보자 (0) | 2022.07.31 |
UNITY DOTS - IJobEntity Jobs 에 대해 알아보자 (0) | 2022.07.31 |
UNITY DOTS - Entity Command Buffers 에 대해 알아보자. (0) | 2022.07.30 |
댓글