Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when touching Unity per-frame code, spawning, physics queries, UI updates or rendering setup - profiling with numbers, zero-GC hot paths (caching, NonAlloc queries, no LINQ/closures/boxing, TMP SetText), ObjectPool, allocation tests, Burst/Jobs for bulk math, and rendering/physics settings that cost frames.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
Unity's managed heap is garbage-collected; every allocation in Update is a future GC spike, and the incremental collector only spreads the pain. Most frame drops in Unity projects come from a short list: allocations per frame, per-frame lookups, unpooled spawning, physics queries that allocate, UI rebuilds, and draw calls. Find which one with the Profiler, fix it, and prove the fix with numbers (game-performance-budget).
Core principle: Zero managed allocations per frame in gameplay, measured — not assumed — with the Profiler's GC Alloc column or an allocation test.
static readonly ProfilerMarker s_Marker = new("Enemy.Think"); using (s_Marker.Auto()) { ... }.// ❌ allocates or searches every frame
void Update() {
var enemies = FindObjectsByType<Enemy>(FindObjectsSortMode.None); // array + scene search
var close = enemies.Where(e => (e.transform.position - transform.position).sqrMagnitude < r2).ToList(); // LINQ + closure
hpText.text = "HP: " + hp; // new string every frame
if (other.tag == "Enemy") { } // allocates the tag string
var hits = Physics.OverlapSphere(transform.position, 5f); // new array per call
StartCoroutine(Flash(new WaitForSeconds(0.1f))); // allocation per call
}
// ✅ cached, reused, non-allocating
readonly Collider[] _hits = new Collider[32];
static readonly WaitForSeconds FlashDelay = new(0.1f);
int _shownHp = -1;
void Update() {
int count = Physics.OverlapSphereNonAlloc(transform.position, 5f, _hits, enemyMask);
for (int i = 0; i < count; i++) { /* use _hits[i] */ }
if (hp != _shownHp) { _shownHp = hp; hpText.SetText("HP: {0}", hp); } // TextMeshPro, no string alloc
if (other.CompareTag("Enemy")) { }
}
More of the same:
RaycastNonAlloc, SphereCastNonAlloc, OverlapBoxNonAlloc. 2D: the overloads taking a ContactFilter2D and a reused List<T>/array (the 2D *NonAlloc methods are obsolete).GetComponentsInChildren(list) overloads that fill a reused list.Animator.StringToHash, Shader.PropertyToID, cached WaitForSeconds/WaitForFixedUpdate.foreach over List<T> and arrays is fine; over an IEnumerable<T> interface it boxes the enumerator.string.Format/interpolation, params arrays or boxing (struct → object/interface) in hot paths.Debug.Log in a hot path allocates and stalls — strip it from builds ([Conditional("UNITY_EDITOR")] wrapper) or remove it.Camera.main is cheaper than it was but is still a lookup — cache it.using UnityEngine.Pool;
public sealed class BulletSpawner : MonoBehaviour {
[SerializeField] Bullet prefab;
ObjectPool<Bullet> _pool;
void Awake() => _pool = new ObjectPool<Bullet>(
createFunc: () => { var b = Instantiate(prefab); b.Init(release: x => _pool.Release(x)); return b; },
actionOnGet: b => b.gameObject.SetActive(true),
actionOnRelease: b => b.gameObject.SetActive(false),
actionOnDestroy: b => Destroy(b.gameObject),
collectionCheck: false, defaultCapacity: 64, maxSize: 256);
public void Fire(Vector3 pos, Vector3 dir) { var b = _pool.Get(); b.Launch(pos, dir); }
}
Pre-warm at load (get and release defaultCapacity instances) so the first fight does not instantiate. A pooled object resets all its state in actionOnGet/Launch, not in Start.
using Is = UnityEngine.TestTools.Constraints.Is;
[Test] public void Tick_SteadyState_DoesNotAllocate() {
var sim = TestSim.WithEnemies(100);
sim.Tick(0.016f); // warm-up: first call may JIT/initialise
Assert.That(() => sim.Tick(0.016f), Is.Not.AllocatingGCMemory());
}
For the same math over hundreds or thousands of items (flocking, projectiles, terrain), a Burst-compiled job on native containers:
[BurstCompile]
struct MoveJob : IJobParallelFor {
public NativeArray<float3> Positions;
[ReadOnly] public NativeArray<float3> Velocities;
public float Dt;
public void Execute(int i) => Positions[i] += Velocities[i] * Dt;
}
// schedule: var h = new MoveJob { ... }.Schedule(count, 64); later h.Complete();
Allocator.Persistent in OnDestroy; TempJob within four frames; Temp within the frame).MaterialPropertyBlock where it breaks batching); GPU instancing for repeated meshes; static batching for static scenery; Sprite Atlases for 2D.Physics.autoSyncTransforms off; tune Time.fixedDeltaTime deliberately.Application.targetFrameRate explicitly; watch thermal throttling over minutes, not seconds.Instantiate/Destroy for bullets, hit effects and damage numbers.NativeArrays (the leak detection warning in the console is a real bug).GC.Alloc above zero in a gameplay Update in the Profiler.FindObjectsByType, GetComponent or new inside Update/FixedUpdate.아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
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
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
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
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
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.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when the repository keeps its alerting in code, or a person asks for alerts outside TaskTrooper - PrometheusRule YAML, a Cloud Monitoring alert policy in Terraform, a Datadog monitor, each routed to TaskTrooper's alert ingest URL so it opens an incident here
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.