Unity Engine

[Unity]ECS - 2

Aostols 2023. 12. 19. 08:51
반응형

https://aostols.tistory.com/46

 

[Unity]ECS

ECS 가 최근에 정식으로 출시 되었습니다. DOTS 의 핵심중 하나인데요 DOTS 는 3가지 큰 주제로 구성되고 있습니다. 1. ECS Component 2. Burst Compiler 3. Job System 여기서 ECS 가 가장 늦게 정식버전이 되었는

aostols.tistory.com

 

여기서 이어서 진행됩니다.

 

소스에서 사용된 내용 몇개를 추가해 줍니다.

랜덤으로 스폰되어야 하기 떄문에 Random 관련 함수들을 추가해 줍니다.

using Unity.Mathematics;

public static class MathExtensions
{
    public static float3 NextOnDisk(this ref Random self)
    {
        while (true)
        {
            var v = self.NextFloat2(-1, 1);
            if (math.length(v) <= 1) return math.float3(v.x, 0, v.y);
        }
    }

    public static quaternion NextYRotation(this ref Random self)
        => quaternion.RotateY(self.NextFloat(math.PI * 2));
}

MathExtensions 는 랜덤 관련으로 사용합니다.

 

 

public struct Walker : IComponentData
{
    public float ForwardSpeed;
    public float AngularSpeed;

    public static Walker Random(uint seed)
    {
        var random = new Random(seed);
        return new Walker()
        {
            ForwardSpeed = random.NextFloat(0.1f, 0.8f),
            AngularSpeed = random.NextFloat(0.5f, 4),
        };
    }
}

Walker 구조체에도 Random을 추가해 줍니다.

 

 

public struct Dancer : IComponentData
{
    public float Speed;

    public static Dancer Random(uint seed)
    {
        return new Dancer()
        {
            Speed = new Random(seed).NextFloat(1, 8)
        };
    }
}

Dancer 구조체 역시 Random을 추가해 줍니다.

 

 

 

이제 스폰을 컨트롤 하는 부분을 제작해 보겠습니다.

using Unity.Entities;
using UnityEngine;

public struct Config : IComponentData
{
    public Entity Prefab;
    public float SpawnRadius;
    public int SpawnCount;
    public uint RandomSeed;
}

public class ConfigAuthoring : MonoBehaviour
{
    public GameObject Prefab = null;
    public float SpawnRadius = 1;
    public int SpawnCount = 10;
    public uint RandomSeed = 100;

    class Baker : Baker<ConfigAuthoring>
    {
        public override void Bake(ConfigAuthoring src)
        {
            var data = new Config()
            {
                Prefab = GetEntity(src.Prefab, TransformUsageFlags.Dynamic),
                SpawnRadius = src.SpawnRadius,
                SpawnCount = src.SpawnCount,
                RandomSeed = src.RandomSeed,
            };
            AddComponent(GetEntity(TransformUsageFlags.None), data);
        }
    }
}

Config IComponentData를 만들어줍니다.

Entity 는 기존에서 사용하던 Prefab과 동일합니다.

Config에 속해 있는 데이터는 스폰을 어떤것을 얼마나 어떻게 할것인가에 가깝습니다.

 

이제 실제 스폰을 시키는 부분입니다.

using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;

[UpdateInGroup(typeof(InitializationSystemGroup))]
public partial struct SpawnSystem : ISystem
{
    public void OnCreate(ref SystemState state)
        => state.RequireForUpdate<Config>();
    
    public void OnUpdate(ref SystemState state)
    {
        var config = SystemAPI.GetSingleton<Config>();

        var instances = state.EntityManager.Instantiate
            (config.Prefab, config.SpawnCount, Allocator.Temp);

        var rand = new Random(config.RandomSeed);
        foreach (var entity in instances)
        {
            var xform = SystemAPI.GetComponentRW<LocalTransform>(entity);
            var dancer = SystemAPI.GetComponentRW<Dancer>(entity);
            var walker = SystemAPI.GetComponentRW<Walker>(entity);

            xform.ValueRW = LocalTransform.FromPositionRotation
                (rand.NextOnDisk() * config.SpawnRadius, rand.NextYRotation());

            dancer.ValueRW = Dancer.Random(rand.NextUInt());
            walker.ValueRW = Walker.Random(rand.NextUInt());
        }

        state.Enabled = false;
    }
}

 

기본 구성은 이전 ECS의 System과 동일합니다.

partial struct로 구성되며 ISystem을 구현합니다.

 

추가된것은 OnCreate를 구현하였는데 여기에 state.RequireForUpdate<Config>()가 추가 되었는데 Config가 있기 전까지는 실행되지 않는다는 것 입니다.

OnCreate 에서 Config가 있는지를 확인한 후 Config가 있다면 SpawnSystem이 생성됩니다.

이후 OnUpdate는 자동으로 수행되며 Config에 있는 정보를 가지고 객체들을 스폰 시킨 후 마지막에 자신은 Enabled = false처리 됩니다.

Enabled = false처리가 되지 않는다면 매 Update마다 스폰을 시키게 됩니다.

 

 

 

ConfigAuthoring 에 입력된 데이터 입니다.

5천개가 입력되었습니다.

실행 화면입니다.

5천개의 Strawman 이 스폰된 것을 볼 수 있습니다.

반응형

'Unity Engine' 카테고리의 다른 글

[Unity]ECS - BurstCompile  (1) 2023.12.21
[Unity]ECS  (1) 2023.12.05
[Unity] Animation Controller  (0) 2023.04.23
[Unity] ScriptableObject + Reflection  (0) 2023.03.28
[Unity]Job System + String  (0) 2023.03.03