unity-fundamentals
from cryptorabea/claude_unity_dev_plugin
No description
npx skills add https://github.com/cryptorabea/claude_unity_dev_plugin --skill unity-fundamentalsSKILL.md
Unity Fundamentals
Comprehensive guidance on Unity's core systems, MonoBehaviour lifecycle, serialization, component architecture, and prefab workflows.
Overview
Unity development centers around MonoBehaviour components, the Component pattern, and a specific lifecycle of callback methods. Understanding these fundamentals is critical for writing correct, performant Unity code. This skill covers:
- MonoBehaviour lifecycle methods and their proper usage
- Serialization system and Inspector integration
- Component-based architecture and GetComponent patterns
- Prefab workflows and best practices
MonoBehaviour Lifecycle
Unity calls specific methods on MonoBehaviour scripts in a predetermined order. Using the wrong method leads to bugs, null references, and poor performance.
Initialization Methods
Awake()
Called when the script instance loads, before any Start() calls. Use for initializing this object's state.
private void Awake()
{
// Cache component references on THIS GameObject
rigidbody = GetComponent<Rigidbody>();
animator = GetComponent<Animator>();
// Initialize private state
currentHealth = maxHealth;
inventory = new List<Item>();
// DON'T reference other objects - they may not be initialized yet
}
Use Awake() for:
- Caching component references
- Initializing private fields
- Setting up internal state
- Creating singletons/managers
Don't use Awake() for:
- Referencing other GameObjects (use Start instead)
- Performing operations that depend on other scripts being ready
Start()
Called before the first Update(), after all Awake() calls complete. Use for setup that references other objects.
private void Start()
{
// Safe to reference other GameObjects - they're initialized
playerTransform = GameObject.FindWithTag("Player").transform;
gameManager = FindObjectOfType<GameManager>();
// Register with managers or systems
GameManager.Instance.RegisterEnemy(this);
// Perform initialization that depends on other components
SetupWeapon(gameManager.GetStartingWeapon());
}
Use Start() for:
- Finding and referencing other GameObjects
- Calling initialization methods on other components
- Registering with managers or systems
- Setup that depends on scene being fully initialized
Common Pattern:
private Camera mainCamera; // Cache in Awake
private Transform target; // Find in Start
private void Awake()
{
mainCamera = Camera.main; // Cache expensive lookup
}
private void Start()
{
target = GameObject.FindWithTag("Target").transform; // Find after scene loads
}
OnEnable() / OnDisable()
Called when GameObject becomes active/inactive. Use for subscribing/unsubscribing from events.
private void OnEnable()
{
// Subscribe to events
GameEvents.OnPlayerDied += HandlePlayerDeath;
InputManager.OnJumpPressed += HandleJump;
// Re-enable functionality
StartCoroutine(SpawnEnemies());
}
private void OnDisable()
{
// Unsubscribe from events (prevents memory leaks!)
GameEvents.OnPlayerDied -= HandlePlayerDeath;
InputManager.OnJumpPressed -= HandleJump;
// Clean up temporary state
StopAllCoroutines();
}
Critical: Always unsubscribe in OnDisable() to prevent memory leaks.
Update Methods
Update()
Called every frame. Use sparingly - performance critical.
private void Update()
{
// Input handling
if (Input.GetKeyDown(KeyCode.Space))
Jump();
// Frame-dependent logic
UpdateUI();
// AVOID expensive operations here
// DON'T call GetComponent every frame
// DON'T use Find methods
}
Avoid Update() when possible. Prefer event-driven approaches.
FixedUpdate()
Called at fixed timestep (default 50 FPS). Use for physics operations only.
private void FixedUpdate()
{
// Physics operations
rigidbody.AddForce(moveDirection * moveSpeed);
// Physics-based movement
rigidbody.MovePosition(transform.position + velocity * Time.fixedDeltaTime);
// DON'T handle input here (use Update)
// DON'T update UI here (use Update or LateUpdate)
}
Rule: If it touches Rigidbody or physics, use FixedUpdate(). Everything else uses Update() or event-driven approaches.
LateUpdate()
Called after all Update() calls. Use for camera follow and final adjustments.
private void LateUpdate()
{
// Camera follow (after player moved in Update)
transform.position = target.position + offset;
// Final position adjustments
ClampToBounds();
// UI updates that depend on world state
UpdateHealthBar();
}
Destruction Methods
OnDestroy()
Called when GameObject is destroyed. Use for final cleanup.
private void OnDestroy()
{
// Unsubscribe from static events
GameEvents.OnPlayerDied -= HandlePlayerDeath;
// Release resources
if (texture
...