Unity game engine guardrails, patterns, and best practices for AI-assisted development.
Use when working with Unity projects, or when the user mentions Unity game development.
Provides MonoBehaviour patterns, component architecture, physics, UI, and scripting guidelines.
Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
Unity game engine guardrails, patterns, and best practices for AI-assisted development.
Use when working with Unity projects, or when the user mentions Unity game development.
Provides MonoBehaviour patterns, component architecture, physics, UI, and scripting guidelines.
Use singletons sparingly. Prefer Service Locator or dependency injection for testability.
Service Locator
publicstaticclassServiceLocator
{
privatestaticreadonly Dictionary<Type, object> Services = new();
publicstaticvoidRegister<T>(T service) where T : class
=> Services[typeof(T)] = service;
publicstatic T Get<T>() where T : class
=> Services.TryGetValue(typeof(T), outvar s) ? s as T : null;
publicstaticvoidClear() => Services.Clear();
}
// Register in bootstrapper Awake(), resolve anywhere
Health / Damageable Interface
publicinterfaceIDamageable
{
voidTakeDamage(int amount);
bool IsAlive { get; }
}
publicclassHealth : MonoBehaviour, IDamageable
{
[SerializeField] privateint maxHealth = 100;
publicint Current { get; privateset; }
publicbool IsAlive => Current > 0;
public UnityEvent<int, int> OnHealthChanged; // current, maxpublic UnityEvent OnDeath;
privatevoidStart() { Current = maxHealth; OnHealthChanged?.Invoke(Current, maxHealth); }
publicvoidTakeDamage(int amount)
{
if (!IsAlive) return;
Current = Mathf.Max(0, Current - amount);
OnHealthChanged?.Invoke(Current, maxHealth);
if (Current <= 0) OnDeath?.Invoke();
}
publicvoidHeal(int amount)
{
if (!IsAlive) return;
Current = Mathf.Min(maxHealth, Current + amount);
OnHealthChanged?.Invoke(Current, maxHealth);
}
}
Always use the new Input System package. Define actions in .inputactions asset, not hardcoded KeyCode checks.
Physics Basics
// Move Rigidbody in FixedUpdate onlyprivatevoidFixedUpdate()
{
rb.MovePosition(rb.position + moveDirection * speed * Time.fixedDeltaTime);
}
// Collision detection (requires Collider + Rigidbody on at least one)privatevoidOnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Enemy"))
{
var damageable = collision.gameObject.GetComponent<IDamageable>();
damageable?.TakeDamage(10);
}
}
// Trigger detection (Collider with isTrigger = true)privatevoidOnTriggerEnter(Collider other)
{
if (other.CompareTag("Pickup"))
CollectItem(other.gameObject);
}
Rules: Rigidbody movement in FixedUpdate. Use layers to filter collisions. Prefer CompareTag over string comparison. Set Rigidbody interpolation for smooth rendering.
UI guidelines: Use TextMeshPro for all text (never legacy UI.Text). Anchor UI elements properly for responsive layouts. Use Canvas Groups for fade effects. Keep UI logic in dedicated controllers, not game logic scripts.
ScriptableObjects
[CreateAssetMenu(fileName = "New Item", menuName = "Game/Items/Item Data")]
publicclassItemData : ScriptableObject
{
[Header("Basic Info")]
publicstring itemName;
[TextArea(3, 5)] publicstring description;
public Sprite icon;
public ItemType itemType;
public Rarity rarity;
[Header("Properties")]
publicint maxStack = 99;
publicint buyPrice;
publicint sellPrice;
}
Use ScriptableObjects for: item definitions, enemy configs, game settings, event channels, audio libraries. They live as .asset files, are editable in the Inspector, and shared across scenes without singletons.
Wire listeners in OnEnable/OnDisable. This decouples systems completely -- the publisher does not know about subscribers.
Object Pooling
publicclassObjectPool<T> whereT : Component
{
privatereadonly T prefab;
privatereadonly Transform parent;
privatereadonly Queue<T> pool = new();
publicObjectPool(T prefab, Transform parent, int initialSize)
{
this.prefab = prefab;
this.parent = parent;
for (int i = 0; i < initialSize; i++) pool.Enqueue(CreateInstance());
}
public T Get(Vector3 pos, Quaternion rot)
{
var obj = pool.Count > 0 ? pool.Dequeue() : CreateInstance();
obj.transform.SetPositionAndRotation(pos, rot);
obj.gameObject.SetActive(true);
return obj;
}
publicvoidReturn(T obj) { obj.gameObject.SetActive(false); pool.Enqueue(obj); }
private T CreateInstance()
{
var obj = Object.Instantiate(prefab, parent);
obj.gameObject.SetActive(false);
return obj;
}
}
Pool bullets, particles, enemies -- anything spawned frequently. Never call Instantiate/Destroy in tight loops.
Testing
Edit Mode Tests (Pure Logic)
using NUnit.Framework;
[TestFixture]
publicclassInventoryTests
{
[Test]
publicvoidAddItem_WhenSlotAvailable_ReturnsTrue()
{
var inventory = new Inventory(maxSlots: 10);
Assert.IsTrue(inventory.AddItem(itemData, quantity: 1));
}
[Test]
publicvoidAddItem_WhenFull_ReturnsFalse()
{
var inventory = new Inventory(maxSlots: 0);
Assert.IsFalse(inventory.AddItem(itemData, quantity: 1));
}
}
Play Mode Tests (MonoBehaviour)
using System.Collections;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
[TestFixture]
publicclassHealthTests
{
[UnityTest]
public IEnumerator TakeDamage_ReducesCurrentHealth()
{
var go = new GameObject();
var health = go.AddComponent<Health>();
yieldreturnnull; // Wait for Start()
health.TakeDamage(25);
Assert.AreEqual(75, health.Current);
Object.Destroy(go);
}
}
Testing rules: Edit Mode for pure logic (no MonoBehaviour dependency). Play Mode for component behavior that requires the Unity lifecycle. Always Destroy test GameObjects in TearDown or inline.