本文へ移動
cccskills
無料GitHub で公開

unity-dots-ecs

Use when working in a Unity project that uses Entities (DOTS) or when a task needs thousands of simulated objects - when ECS is worth it, components/bakers/ISystem with IJobEntity and Burst, entity command buffers for structural changes, native memory rules, and testing systems in a test World.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md6.5 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Unity DOTS / ECS

Overview

Unity's Entities package stores data in tightly packed chunks and runs Burst-compiled jobs over it in parallel. It scales to tens of thousands of entities where GameObjects choke — and it makes simple gameplay code more verbose. Use it where the scale needs it, follow the project's existing split between GameObjects and entities, and never introduce DOTS into a GameObject project on your own initiative.

Core principle: Components are plain data, systems are Burst-compiled ISystems scheduling jobs, and structural changes go through an entity command buffer.

When it is worth it

SituationUse
Thousands of similar units, projectiles, boids, crowd agentsECS (or Jobs + Burst over native arrays first)
Heavy simulation with little per-object uniquenessECS
UI, menus, a handful of characters, bespoke scripted momentsGameObjects
Mixed gameHybrid: entities for the swarm, GameObjects for the player, UI and cameras

The pieces

// Data: unmanaged structs
public struct Speed : IComponentData { public float Value; }
public struct Target : IComponentData { public float3 Position; }

// Authoring + baking: designers edit a MonoBehaviour in a subscene; the baker turns it into components
public sealed class SpeedAuthoring : MonoBehaviour {
    public float value = 5f;
    sealed class Baker : Baker<SpeedAuthoring> {
        public override void Bake(SpeedAuthoring a) {
            var e = GetEntity(TransformUsageFlags.Dynamic);
            AddComponent(e, new Speed { Value = a.value });
        }
    }
}

// Behaviour: a Burst-compiled ISystem scheduling a parallel IJobEntity
[BurstCompile]
public partial struct SeekSystem : ISystem {
    [BurstCompile] public void OnCreate(ref SystemState state) => state.RequireForUpdate<Speed>();

    [BurstCompile] public void OnUpdate(ref SystemState state) {
        new SeekJob { Dt = SystemAPI.Time.DeltaTime }.ScheduleParallel();
    }
}

[BurstCompile]
partial struct SeekJob : IJobEntity {
    public float Dt;
    void Execute(ref LocalTransform transform, in Speed speed, in Target target) {
        var to = target.Position - transform.Position;
        var dist = math.length(to);
        if (dist > 0.01f) transform.Position += to / dist * math.min(speed.Value * Dt, dist);
    }
}

Rules

  • ISystem with [BurstCompile] over SystemBase for new systems; SystemBase only where managed objects are unavoidable.
  • Burst everything on the hot path: no managed types (classes, strings, List<T>) in components or jobs that should be Burst-compiled; use FixedString, NativeArray, DynamicBuffer.
  • in for read-only, ref for written components in Execute — it drives the dependency system and parallelism.
  • Structural changes (create/destroy entities, add/remove components) are recorded in an entity command buffer, not done inside jobs:
var ecb = SystemAPI.GetSingleton<EndSimulationEntityCommandBufferSystem.Singleton>()
                   .CreateCommandBuffer(state.WorldUnmanaged).AsParallelWriter();
new ExpireJob { Ecb = ecb, Now = (float)SystemAPI.Time.ElapsedTime }.ScheduleParallel();
// in the job: void Execute([ChunkIndexInQuery] int key, Entity e, in Lifetime l) { if (Now > l.EndsAt) Ecb.DestroyEntity(key, e); }
  • Frequent on/off states use enableable components (IEnableableComponent) instead of add/remove, which moves the entity between chunks.
  • Archetype hygiene: many tiny component combinations fragment chunks; check chunk utilisation in the Entities windows.
  • Native memory: every NativeArray/NativeList is disposed — Allocator.Temp inside a frame, TempJob within four frames, Persistent in OnDestroy. Leak warnings are bugs.
  • Aspects (IAspect) are deprecated in recent Entities releases — use explicit component parameters and queries instead of adding new ones.
  • Physics (Unity Physics / Havok) runs in its own fixed-step group — gameplay that reacts to physics runs in or after that group, not in an arbitrary Update system.

Testing systems

public class SeekSystemTests {
    World _world; EntityManager _em;

    [SetUp] public void SetUp() { _world = new World("Test"); _em = _world.EntityManager; }
    [TearDown] public void TearDown() => _world.Dispose();

    [Test] public void Update_EntityWithSpeed_MovesTowardTarget() {
        var e = _em.CreateEntity(typeof(LocalTransform), typeof(Speed), typeof(Target));
        _em.SetComponentData(e, LocalTransform.FromPosition(float3.zero));
        _em.SetComponentData(e, new Speed { Value = 2f });
        _em.SetComponentData(e, new Target { Position = new float3(10, 0, 0) });
        var system = _world.CreateSystem<SeekSystem>();

        _world.SetTime(new TimeData(elapsedTime: 0.5, deltaTime: 0.5f));
        system.Update(_world.Unmanaged);
        _em.CompleteAllTrackedJobs();

        Assert.That(_em.GetComponentData<LocalTransform>(e).Position.x, Is.EqualTo(1f).Within(1e-4));
    }
}
  • A fresh World per test, disposed in teardown; create only the systems under test.
  • Complete jobs before asserting.
  • Keep the math in static Burst-compatible functions so it can also be tested as a plain function.

Netcode for Entities (if the project uses it)

Ghost components replicate state; prediction runs in the predicted simulation group; input travels as IInputComponentData. Server-authority rules from game-networking still apply — validate input on the server world.

Common Mistakes

  • Converting a small game to ECS for "performance" with no profiler evidence.
  • Structural changes inside a job, or EntityManager calls in a hot loop on the main thread.
  • Managed components in a system that is supposed to be Burst-compiled; Burst silently falls back or errors.
  • Forgetting RequireForUpdate, so a system runs (and throws) before its data exists.

Red Flags

  • SystemBase + Entities.ForEach in new code (legacy API).
  • Native containers without a matching Dispose.
  • A system that reads and writes the same component from two jobs without dependencies.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases

日本語の概要は準備中です。原文の説明を表示しています。

makifbaysal/tasktrooper1122026年10月11日 更新

Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping

日本語の概要は準備中です。原文の説明を表示しています。

makifbaysal/tasktrooper1122026年10月11日 更新

Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal

日本語の概要は準備中です。原文の説明を表示しています。

makifbaysal/tasktrooper1122026年10月11日 更新

Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task

日本語の概要は準備中です。原文の説明を表示しています。

makifbaysal/tasktrooper1122026年10月11日 更新

How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.

日本語の概要は準備中です。原文の説明を表示しています。

makifbaysal/tasktrooper1122026年10月11日 更新

Use when deciding whether a request needs an analiz task before implementation - the conditions that require the architect's analysis versus going straight to implementation

日本語の概要は準備中です。原文の説明を表示しています。

makifbaysal/tasktrooper1122026年10月11日 更新

makifbaysal のスキルをすべて見る

このスキルの問題を報告する