土鍋で雑多煮

UnityでXR・ゲーム開発をしています。学んだことや備忘録、趣味の記録などを書いていきます。

【UnityECS】EntityがComponentを持つか取得できるComponentLookup

どうも、土鍋です。

ECSでEntityは取得できてもコンポーネントにどうやったらアクセスできるんだ?
という問題に直面した際にComponentLookupが使えます。
自分はこれを知らなくて苦労しました。

まずはコードをご覧ください。

public partial struct CitizenMoveSystem : ISystem
{
    private EntityQuery _buildingQuery;

    [BurstCompile]
    public void OnCreate(ref SystemState state)
    {
        _buildingQuery = state.GetEntityQuery(typeof(LocalTransform), typeof(BuildingBase));
    }
    
    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
        // Jobの発行処理
        var job = new CitizenMoveUpdateJob()
        {
            Elapsed = (float)SystemAPI.Time.ElapsedTime,
            BuildingEntities = _buildingQuery.ToEntityArray(Allocator.TempJob),
            BuildingLookup = SystemAPI.GetComponentLookup<BuildingBase>(),
            BuildingPosLookup = SystemAPI.GetComponentLookup<LocalToWorld>()
        }; // 初期化
        job.ScheduleParallel(); // Jobの予約
    }
}
partial struct CitizenMoveUpdateJob : IJobEntity
{

~一部省略~

public NativeArray<Entity> BuildingEntities;
[ReadOnly] public ComponentLookup<BuildingBase> BuildingLookup;
[ReadOnly] public ComponentLookup<LocalToWorld> BuildingPosLookup;

void Execute(ref CitizenBase citizen, ref LocalTransform transform)
{

~一部省略~

foreach (var buildingEntity in BuildingEntities)
{
    if (BuildingLookup[buildingEntity].buildingType == BuildingType.Food)
    {
        float distanceSq = math.distancesq(BuildingPosLookup[buildingEntity].Position, transform.Position);

        if (distanceSq < minDistanceSq)
        {
            minDistanceSq = distanceSq;
            closestBuildingPosition = BuildingPosLookup[buildingEntity].Position;
        }
    }
}

~一部省略~

このコードではCitizenがBuildingEntitiyを全取得し、buildingTypeがFoodのものを選択し、一番近いものに訪問するということをやっています。

ComponentLookupについて

使い方

BuildingLookup[buildingEntity]

のようにEntityをIDとして配列の添え字のように記述することで、そのEntityのコンポーネントを取得することができます。

また、

BuildingLookup.HasComponent(buildingEntity)

のようにそのコンポーネントを持つかどうかのboolの取得もこのようにできます。

取得方法

SystemAPI.GetComponentLookup<BuildingBase>()

SystemAPI.GetComponentLookup<>()を使用することでほしいコンポーネントのComponentLookupを取得できます。

ちなみにEntityの取得はEntityQueryからToEntityArrayでNativeArrayを取得しています。

参考

wgn-obs.shop-pro.jp

qiita.com