Unity Entities Tips
- Unity Entities Tips
- 初めに
- 内容
- EntityManager.DestroyEntity
- Entity と Particle System
- EntityManager.CreateEntity その1
- EntityManager.CreateEntity その2
- Entity でマテリアル操作
- Entity が親子関係を持っている時の、子の World 座標
- TransformUsageFlags の意味
- 時間経過を制御する
- Entities サブシーンを動的ロード
- 動的に GameObject を Entity に変換
- EditorWindow でプレファブを Entity として配置
- DynamicBuffer
- Entities の System を外から切り替え
- Entities と NavMesh
- エラーが出た時
- 最後に
初めに
Unity Entities (ECSとも言われる)に関する情報が溜まってきたので書きます。
- Unity 6000.3.2f1
- Entities 1.4.3
内容
EntityManager.DestroyEntity
EntityManager.DestroyEntity には EntityQuery を渡すこともできるが、実行時エラーになる。 ToEntityArray で取り出したリストを渡す。
Entity と Particle System
Entityにパーティクルは置けるが、動的な操作は難しいらしく、調べたが解決出来なかった。
https://discussions.unity.com/t/particle-system-on-entity/772431/15
マネージドで位置同期するか、変更が無い設計にする。
EntityManager.CreateEntity その1
コード上で
var entity = entityManager.CreateEntity();
で Entity を作った場合、 LocalTransform を始め何も付いていない。
後から追加するには AddComponentData を使うが、大量に作る時はアーキタイプを指定する事で効率が上がる。
var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
var archetype = entityManager.CreateArchetype(typeof(LocalTransform), typeof(MyData.ComponentData));
for(var i = 0; i < 10000; i++)
{
var entity = entityManager.CreateEntity(archetype);
}
EntityManager.CreateEntity その2
EntityManager.CreateEntity で作成した Entity に子を追加する場合、子の位置がおかしくなる。
親である作成 Entity に LocalToWorld を付ける事で正しくなる。
Entity でマテリアル操作
リンクのみ
Entity が親子関係を持っている時の、子の World 座標
Entityが親子関係を持っている場合、子のワールド座標を得るには、
var pos = entityManaer.GetComponentData<LocalTransform>(entity).Position;
ではなく、
var pos = entityManaer.GetComponentData<LocalToWorld>(entity).Position;
になる。
https://docs.unity3d.com/Packages/com.unity.entities@1.4/api/Unity.Transforms.LocalToWorld.html
ただし定期的に計算されるものである為精度が低い。
動かないオブジェクトに対して使用するか、以下を参考に自分で計算する
TransformUsageFlags の意味
Bake する時に呼ぶ
var entity = GetEntity(TransformUsageFlags.Dynamic);
での TransformUsageFlags は、 MonoBehaviour から Entity に変換する際に MonoBehaviour から何を引き継ぐかを設定するものである。
時間経過を制御する
https://docs.unity3d.com/Packages/com.unity.entities@1.4/manual/systems-time.html
- システムは一つのシステムグループに属する。
- 属性を付ける事でどれに属するかを指定する。
- [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
- デフォルトは60fps、最大は0.1fps(10秒毎の更新)
変更方法
- 派生した専用システムを作る。
- コンストラクタで new しているので、派生より同じ実装をした方が良さそうだ。
- デフォルトの値を変更する。
var system = World.DefaultGameObjectInjectionWorld.GetExistingSystemManaged<FixedStepSimulationSystemGroup>();
system.Timestep = 0.1f;
- World.PushTime で一時的に変更、PopTimeで一つ前に戻す。
- ワールド全体の指定のみ
Entities サブシーンを動的ロード
リンクのみ
https://discussions.unity.com/t/generate-sub-scenes-programmatically/785860/21
動的に GameObject を Entity に変換
リンクのみ
https://note.com/upfrontier/n/nda5f57e9a1e3
EditorWindow でプレファブを Entity として配置
var targetSubScene = rootVisualElement.Q<ObjectField>("subScene").value as SubScene;
var obj = PrefabUtility.InstantiatePrefab(MyPrefab) as GameObject;
EditorSceneManager.MoveGameObjectToScene(obj, targetSubScene.EditingScene);
DynamicBuffer
DynamicBuffer は、シングルトンとすると直接アクセスできる関数が用意されている。
var builder = new EntityQueryBuilder(Allocator.Temp).WithOptions(EntityQueryOptions.IncludeSystems);
using var query = entityManager.CreateEntityQuery(builder);
if (!query.TryGetSingletonBuffer<MyData>(out var buffer))
{
var entity = entityManager.CreateSingletonBuffer<MyData>();
buffer = query.GetSingletonBuffer<MyData>();
}
buffer.CopyFrom(map.Points.Cast<MyData>().ToArray());
Entities の System を外から切り替え
https://discussions.unity.com/t/changing-systemstate-enabled-has-no-effect/924656/6
public static void SetEnable()
{
var systemTypeIndex = TypeManager.GetSystemTypeIndex<MySystem>();
var _handle = World.DefaultGameObjectInjectionWorld.GetExistingSystem(systemTypeIndex);
ref var state = ref World.DefaultGameObjectInjectionWorld.Unmanaged.ResolveSystemStateRef(_handle);
state.Enabled = true;
}
Entities と NavMesh
https://discussions.unity.com/t/getting-navigation-meshes-navmesh-to-work-with-entities-1-0/907090
実験的APIを使用。2026/01/03現在で正式になっていない。 https://docs.unity3d.com/6000.3/Documentation/ScriptReference/Experimental.AI.NavMeshQuery.html
https://discussions.unity.com/t/navagent-and-pathfinding-in-ecs/798264
エラーが出た時
Loading Entity Scene failed because the entity header file couldn't be resolved.
編集 → 環境設定。Entities → Clear Entity Cache ボタンを押す。
例外が出ている場合は対処
最後に
Unity 6.4 から Entities のバージョンが上がるようで、1.4 から 6.4 になる
https://docs.unity3d.com/Packages/com.unity.entities@6.4/manual/index.html
大きくバージョンが上がるのは、基礎への統合に向けた動きとみられる。
Entities.ForEach と Aspects が非推奨化。使ってなかったので良いが、割と影響が大きそう。