Physics
Game physics simulates motion, collisions, forces. Most engines bundle a physics library (Unity: PhysX, Godot: GodotPhysics / Jolt, Unreal: Chaos). The pieces you wire up: rigid bodies, colliders, gravity, joints, raycasts.
Rigid bodies, collisions, raycasts (Unity)
EXAMPLE
using UnityEngine;
// 1) Make something physical — add Rigidbody + Collider
// Inspector: add Rigidbody (mass, drag, gravity) + a Collider (Box, Sphere, Capsule, Mesh)
public class Ball : MonoBehaviour
{
Rigidbody rb;
[SerializeField] float jumpForce = 8f;
void Awake() => rb = GetComponent<Rigidbody>();
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
}
// 2) Continuous vs discrete collision detection
// rb.collisionDetectionMode = CollisionDetectionMode.Continuous; // for fast-moving objects (bullets)
// Discrete = cheaper, occasional tunneling. Continuous = no tunneling, costlier.
// 3) Use FixedUpdate for physics — runs at the physics tick (default 50 Hz)
void FixedUpdate()
{
rb.MovePosition(rb.position + transform.forward * speed * Time.fixedDeltaTime);
}
// 4) Forces vs velocities
rb.AddForce(Vector3.right * 10); // affected by mass + drag
rb.AddForce(Vector3.up * 10, ForceMode.Impulse); // instant velocity change
rb.velocity = Vector3.zero; // hard reset
rb.AddTorque(Vector3.up * 5); // rotational force
// 5) Collision callbacks
void OnCollisionEnter(Collision c)
{
if (c.gameObject.CompareTag("Enemy"))
TakeDamage();
var impact = c.relativeVelocity.magnitude;
audio.PlayOneShot(thudSound, Mathf.Clamp01(impact / 10f));
}
void OnCollisionStay(Collision c) { /* still touching */ }
void OnCollisionExit(Collision c) { /* separated */ }
// 6) Triggers — detect overlap WITHOUT physical response
void OnTriggerEnter(Collider c)
{
if (c.CompareTag("Pickup"))
{
Destroy(c.gameObject);
score += 10;
}
}
// Trigger requires: collider.isTrigger = true on at least one of the colliders
// 7) Layers + Layer Collision Matrix
// Edit → Project Settings → Physics → Layer Collision Matrix
// Lets you say "Player layer doesn't collide with Pickup layer" — big perf win
// 8) Raycast — line of sight, picking, ground check
bool grounded;
void CheckGrounded()
{
grounded = Physics.Raycast(transform.position, Vector3.down, out var hit, 1.1f);
if (grounded) Debug.DrawLine(transform.position, hit.point, Color.green);
}
RaycastHit hit;
if (Physics.Raycast(camera.position, camera.forward, out hit, 100f, enemyLayer))
{
hit.collider.GetComponent<Enemy>().Hit();
}
// 9) OverlapSphere / Box — find everything in a radius
Collider[] inRange = Physics.OverlapSphere(transform.position, 5f, enemyLayer);
foreach (var c in inRange) c.GetComponent<Enemy>().Aggro();
// 10) Joints — connect rigid bodies
var hinge = gameObject.AddComponent<HingeJoint>();
hinge.connectedBody = otherRigidbody;
hinge.anchor = new Vector3(0, 0.5f, 0);
hinge.axis = Vector3.up;
// 11) Kinematic — physics object you move manually
rb.isKinematic = true; // gravity off, no forces; you control position/rotation
// Useful for moving platforms, animated objects that need to collide
// 12) Common pitfalls
// - Moving with transform.position bypasses physics — use rb.MovePosition
// - Calling AddForce in Update can be frame-rate dependent — use FixedUpdate or pass Time.fixedDeltaTime
// - Tiny / huge masses break the solver — keep within 0.1..100 range
// - High velocity + Discrete CCD = tunneling through walls — switch to Continuous
// - Using mesh colliders on moving objects — convex MeshCollider with isConvex=true
// 13) Physics in Godot (similar pattern)
// extends RigidBody3D
// func _physics_process(delta):
// if Input.is_action_just_pressed("jump"):
// apply_central_impulse(Vector3.UP * 8)
// func _on_body_entered(body): pass
// 14) When to skip physics
// - Static obstacles: just use colliders, no Rigidbody
// - UI / 2D widget interactions: events, not physics
// - Custom motion (platformer-style precise control) — implement your own character controller with raycasts
// (Unity has CharacterController and ThirdPersonController templates)
Why it matters
Use Rigidbody.MovePosition + FixedUpdate for physics motion; use raycasts for ground checks and aiming. Mixing transform.position writes and physics solving is the source of 80% of janky game feel.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
// Use a real physics engine for non-trivial games: // 2D: Matter.js (web), Box2D, Chipmunk // 3D: Rapier, Cannon-es, PhysX (Unity), Jolt (Godot 4) // Roll your own only for highly stylised, simple games.Try it Yourself »
Discussion
Loading…