Unity DOTS/TIP

UNITY DOTS - Unity.Mathematics.Random 랜덤 사용하기

개양반 2022. 11. 28.
728x90

1. 개요

DOTS에서는 Random 값을 얻을려면 Unity.Mathematics 패키지에 있는 Random을 사용해야 한다. 하지만, 기존의 UnityEngine.Random 처럼 사용하면 모든 Entity가 같은 랜덤 값을 생성하는  문제가 발생한다. 

같은 Seed를 가진 Entity는 같은 랜덤값을 생성한다.

해결 방법으로는 Entity가 개별 Seed를 가지고 있으면 된다.

 

2. 예제

2-1 ComponentData

    public struct RandomScoreData : IComponentData
    {
        // Entity는 고유한 Ramdom Component를 가져야 한다.
        public Random Randomizer; 
    }

 

2-2 Authoring

    public class RandomScoreAuthoring : MonoBehaviour
    {
        public float randomTime;

        class RandomPositionBaker : Baker<RandomScoreAuthoring>
        {
            public override void Bake(RandomScoreAuthoring authoring)
            {
                AddComponent(new RandomScoreData
                {
                    Randomizer = new Random((uint)UnityEngine.Random.Range(0, int.MaxValue)),
                });
            }
        }
    }

2-2-1 설명

게임오브젝트가 BakeSystem을 통해 Entity로 변환될 때 Random Component를 랜덤한 Seed로 생성한다. 동일한 Seed를 가지면 동일한 랜덤값을 생성한다.

 

2-3 System

    [BurstCompile]
    public partial struct RandomScoreSystem : ISystem
    {
        [BurstCompile]
        public void OnCreate(ref SystemState state)
        {
            
        }

        [BurstCompile]
        public void OnDestroy(ref SystemState state)
        {
            
        }

        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            var deltaTime = SystemAPI.Time.DeltaTime;

            new RandomPositionJob
            {
            }.ScheduleParallel();
        }
    }

    [BurstCompile]
    public partial struct RandomPositionJob : IJobEntity
    {
        public void Execute([ChunkIndexInQuery] int chunkIndex, ref RandomScoreData randomScoreData, ref TransformAspect transform)
        {
            Debug.Log(string.Format("Random Score: {0}", randomScoreData.Randomizer.NextInt(0, int.MaxValue)));
           
           // 시드를 다시 할당
           randomScoreData.Randomizer = new Random((uint)randomScoreData.Randomizer.NextInt(0, int.MaxValue));
        
        }
    }

2-3-1 설명

BurstComplie 에서는 String을 사용할 수 없다. string.Format을 이용해서 디버그를 찍어야 한다. 

 

3. 결과

Seed가 다르면 랜덤값도 다르게 생성된다.

 

댓글

💲 추천 글