GameObject
GameObject is Unity's most basic unit of existence in a Scene — an empty container with no logic of its own; all behavior comes from attached Components.
Imagine...
A GameObject is like an actor with no script standing on stage. On their own they do nothing — Components (Rigidbody, Collider, Script...) are the costume, weapons, and script that turn them into a character with real behavior.
The concept in detail
In Unity’s Entity-Component architecture, a
GameObject is the Entity — an identity with no logic of its own. All behavior
comes from Components attached to it.
Every GameObject always has a Transform — a component you cannot remove, which owns position, rotation, and scale. You can attach any other Component through Add Component in the Inspector.
GameObjects live in a tree-shaped Hierarchy. When you move a Parent, every Child moves with it — the mechanism that lets a complex character with many parts act as one unit.
On performance: GameObject.Find() walks the entire Scene. Always
cache the reference in Awake() and store
it in a private field.
Structure diagram
⚙ Transform
Position · Rotation · Scale
Required
⚙ Rigidbody
Mass · Drag · Gravity
⚙ Capsule Collider
Center · Radius · Height
⚙ PlayerCtrl (Script)
moveSpeed · jumpForce
Custom
Hands-on steps
Create a new GameObject
Hierarchy → right-click → Create Empty, or pick a built-in shape (Cube, Sphere...).
Name it and assign a Tag
Name it in the Inspector (e.g. Player), then assign a Tag so scripts can find it faster.
Attach Components
Inspector → Add Component → add a Rigidbody, a Collider, then your C# script.
Use it from code
Instantiate() clones, FindWithTag() finds, Destroy() removes.
Interactive simulator
Click a GameObject in the Hierarchy to inspect it. Try creating or destroying objects.
Hierarchy
← Select a GameObject
Code example
Basicusing UnityEngine;
public class GameObjectBasics : MonoBehaviour
{
public GameObject enemyPrefab;
void Start()
{
// Spawn an Enemy at (2, 0, 0)
GameObject newEnemy = Instantiate(enemyPrefab,
new Vector3(2f, 0f, 0f),
Quaternion.identity);
newEnemy.name = "Enemy_001";
// Find by Tag (faster than Find by name)
GameObject player = GameObject.FindWithTag("Player");
// Destroy the enemy after 5 seconds
Destroy(newEnemy, 5f);
}
}Code example
Advancedusing UnityEngine;
public class GameObjectAdvanced : MonoBehaviour
{
[SerializeField] private GameObject bulletPrefab;
[SerializeField] private Transform firePoint;
// Cache components — avoid GetComponent() in Update
private Rigidbody _rb;
private Animator _anim;
void Awake()
{
_rb = GetComponent<Rigidbody>();
_anim = GetComponent<Animator>();
}
public void SpawnBullet()
{
if (bulletPrefab == null) return;
GameObject bullet = Instantiate(bulletPrefab,
firePoint.position, firePoint.rotation);
// Keep Hierarchy tidy: parent the bullet under a container
GameObject pool = GameObject.Find("BulletContainer");
if (pool != null) bullet.transform.SetParent(pool.transform);
// Disable without freeing memory
gameObject.SetActive(false);
}
}📌 Quick recap
- ▸GameObject = empty container; behavior comes from Components
- ▸Every GO has a Transform — it cannot be removed
- ▸
SetActive(false)hides an object without freeing memory - ▸Use a Tag instead of a name for faster lookups
⚠️ Common mistakes
❌ GetComponent<>() inside Update()
Runs every frame — extremely expensive
✅ Cache it in a private field inside Awake()
❌ GameObject.Find() inside Update()
Walks the entire Hierarchy every frame
✅ Use [SerializeField] and drag the reference in the Editor