Unity DOTS 入門 (10) - 他のエンティティのコンポーネントデータへのアクセス
これまで、エンティティ自身のコンポーネントデータにアクセスしてきました。今回は、他のエンティティのコンポーネントデータへのアクセスする方法を説明します。
・Unity 2019.3.14.f1
・Entities 0.11.1
1. 他のエンティティのコンポーネントデータへのアクセス
「Unity DOTS 入門 (9)」のサンプルを改良して、キー操作で動く立方体「Cube」の後ろを、立方体「Chaser」が追いかけるようにします。
(1) 「Unity DOTS 入門 (9)」のサンプルの「PlayerTag」のないCubeを1つだけ残し、名前を「Chaser」とし、Transformを以下のように設定。
Translate = (-2, 0, 0)
Rotation = (0, 0, 0)
Scale = (0.8, 0.8, 0.8)
(2) 「Chaser」にタグ「ChaserTag」を追加。
using Unity.Entities;
[GenerateAuthoringComponent]
public struct ChaserTag : IComponentData
{
}
(3) 「Chaser」にスクリプト「ChaserData」を追加。
以下の2つのフィールドを保持します。
・アクセス対象となるエンティティの参照(正確にはID)。
・アクセス対象となるエンティティ取得する位置。
using Unity.Entities;
using Unity.Mathematics;
[GenerateAuthoringComponent]
public struct ChaserData : IComponentData
{
public Entity targetEntity; // アクセス対象となるエンティティの参照(正確にはID)
public float3 targetTranslation; // アクセス対象となるエンティティ取得する位置
}
(4) コンポーネント「ChaserData」の「Target Entity」に「Cube」(ConvertToEntityを持つGameObject)をドラッグ&ドロップ。
(5) Projectウィンドウにスクリプト「ChaserSystem」を追加。
using UnityEngine;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Transforms;
using System;
public class ChaserSystem : SystemBase
{
protected override void OnUpdate()
{
float deltaTime = Time.DeltaTime;
float speed = 3f;
// ターゲット位置の取得
Entities.
WithAll<ChaserTag>().
ForEach((ref ChaserData chaserData) =>
{
// Translationコンポーネント群の取得
ComponentDataFromEntity<Translation> allTranslations =
GetComponentDataFromEntity<Translation>(true);
if (!allTranslations.Exists(chaserData.targetEntity))
{
return;
}
Translation targetPos = allTranslations[chaserData.targetEntity];
// ターゲット位置の保持
chaserData.targetTranslation = targetPos.Value;
}).Schedule();
// チェイサーの移動
Entities.
WithAll<ChaserTag>().
ForEach((ref Translation translation, in ChaserData chaserData) =>
{
float dx = (chaserData.targetTranslation.x - translation.Value.x);
float dz = (chaserData.targetTranslation.z - translation.Value.z);
translation.Value.x += dx * deltaTime * speed;
translation.Value.z += dz * deltaTime * speed;
}).Schedule();
}
}
◎ GetComponentDataFromEntity<T>()
GetComponentDataFromEntity<T>() でTranslationコンポーネント群を取得します。引数のtrue/falseは「読み込み専用」かどうかで、未設定時はfalseになります。
◎ ターゲット位置の取得とチェイサーの移動を分ける
「ターゲット位置の取得」で同時にチェイサーの移動を行うため、ForEachに「ref Translation translation」を付加すると、次のようなエラーがでまします。
Entities.ForEachは、GetComponentDataFromEntity()と読み書き可なラムダ関数のパラメータで同じコンポーネント種別を使うことはできません。
そこで分けましたが、もっとスマートな方法あるかも。
(6) 実行。
「Cube」を「Chaser」が追いかけることを確認できます。
この記事が気に入ったらサポートをしてみませんか?