smithery.ai

unity-csharp-fundamentals

Unity C# fundamental patterns including TryGetComponent, SerializeField, RequireComponent, and safe coding practices. Essential patterns for robust Unity development. Use PROACTIVELY for any Unity C# code to ensure best practices.

First seen Apr 22, 2026

Installation

$ npx skills add https://smithery.ai

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery.ai · top by installs.

npx skills add https://smithery.ai

Browse all from smithery.ai

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 4,669 B
  • docs SUMMARY.md 263 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

Unity C# Fundamentals - Essential Coding Patterns

Overview

Core Unity C# patterns for safe, maintainable code. Not optimizations but fundamental practices.

Foundation Required: C# basics, Unity MonoBehaviour lifecycle

Core Topics: TryGetComponent, SerializeField, RequireComponent, Null-safe patterns, Lifecycle management

Essential Patterns

TryGetComponent (Required)

Always use TryGetComponent instead of GetComponent:

// ❌ WRONG
Rigidbody rb = GetComponent<Rigidbody>();
rb.velocity = Vector3.zero;  // NullReferenceException!

// ✅ CORRECT
Rigidbody rb;
if (TryGetComponent(out rb))
{
    rb.velocity = Vector3.zero;
}

// ✅ Cache in Awake with validation
private Rigidbody mRb;

void Awake()
{
    if (!TryGetComponent(out mRb))
    {
        Debug.LogError($"Missing Rigidbody on {gameObject.name}", this);
    }
}

Global Object Search (Unity 2023.1+)

// ❌ OBSOLETE - DON'T USE
GameManager manager = FindObjectOfType<GameManager>();

// ✅ CORRECT - Fastest (unordered)
GameManager manager = FindAnyObjectByType<GameManager>();

// ✅ CORRECT - Ordered
GameManager manager = FindFirstObjectByType<GameManager>();

// ✅ Multiple objects
Enemy[] enemies = FindObjectsByType<Enemy>(FindObjectsSortMode.None);

SerializeField Pattern

// ❌ WRONG: Public field
public float speed;

// ✅ CORRECT: SerializeField + private
[SerializeField] private float mSpeed = 5f;

// ✅ With Inspector helpers
[SerializeField, Tooltip("Units/second"), Range(0f, 100f)]
private float mMoveSpeed = 5f;

public float Speed => mSpeed;  // Read-only access

RequireComponent

[RequireComponent(typeof(Rigidbody))]
[DisallowMultipleComponent]
public class PhysicsObject : MonoBehaviour
{
    private Rigidbody mRb;

    void Awake()
    {
        TryGetComponent(out mRb);  // Guaranteed to exist
    }
}

Unity Null Safety

// ❌ WRONG: C# null operators don't work with Unity Objects
Transform target = mCached ?? FindTarget();  // Broken!
mEnemy?.TakeDamage(10);  // May fail after Destroy

// ✅ CORRECT: Explicit null check
Transform target = mCached != null ? mCached : FindTarget();

if (mEnemy != null)
{
    mEnemy.TakeDamage(10);
}

Lifecycle Order

void Awake()     { /* 1. Self-init, cache components */ }
void OnEnable()  { /* 2. Subscribe events */ }
void Start()     { /* 3. Cross-object init */ }
void OnDisable() { /* 4. Unsubscribe events */ }
void OnDestroy() { /* 5. Final cleanup */ }

Unity C# 9.0 Limitations

Important: Unity's Mono/IL2CPP runtime lacks IsExternalInit.
init accessor causes compile error CS0518.

// ❌ COMPILE ERROR in Unity
public string Name { get; private init; }

// ✅ Use private set
public string Name { get; private set; }

// ✅ Or readonly field + property
private readonly string mName;
public string Name => mName;

Available: Pattern matching, switch expressions, covariant returns NOT Available: init, required (C# 11)

Quick Reference

Pattern Rule
Component access Always TryGetComponent, never bare GetComponent
Serialization [SerializeField] private, not public
Dependencies Use [RequireComponent] for guaranteed components
Null checks Explicit != null, not ?? or ?.
Caching Get in Awake, reuse everywhere
Events Subscribe in OnEnable, unsubscribe in OnDisable
Global search FindAnyObjectByType (fastest), not FindObjectOfType

Reference Documentation

[Component Access Patterns](references/component-access.md)

  • TryGetComponent variations and interface-based access
  • GetComponentInChildren/Parent patterns
  • Allocation-free multiple component access
  • Caching strategies and performance comparisons

[Attributes and Patterns](references/attributes-patterns.md)

  • Complete serialization attribute reference
  • Inspector customization (Header, Tooltip, Range)
  • Execution order control
  • Conditional compilation

[Language Limitations](references/language-limitations.md)

  • init accessor alternatives with code examples
  • Records in Unity (limitations and workarounds)
  • required modifier alternatives
  • Available C# 9.0 features in Unity