Unity
Unity is a C#-scripted, component-based engine. GameObjects hold MonoBehaviour components; the engine calls Awake / Start / Update / FixedUpdate at well-defined times.
A player controller from scratch
EXAMPLE
using UnityEngine;
using UnityEngine.InputSystem;
[RequireComponent(typeof(CharacterController))]
public class PlayerController : MonoBehaviour
{
[SerializeField] float moveSpeed = 5f;
[SerializeField] float jumpHeight = 1.5f;
[SerializeField] float gravity = -9.81f * 2;
[SerializeField] Transform cameraTransform;
CharacterController controller;
Vector2 moveInput;
Vector3 velocity;
bool wantJump;
bool grounded;
void Awake() => controller = GetComponent<CharacterController>();
// Input System callbacks — bound via PlayerInput component
public void OnMove(InputAction.CallbackContext ctx) => moveInput = ctx.ReadValue<Vector2>();
public void OnJump(InputAction.CallbackContext ctx)
{
if (ctx.performed) wantJump = true;
}
void Update()
{
grounded = controller.isGrounded;
if (grounded && velocity.y < 0) velocity.y = -2f; // small downforce keeps it grounded
// 1) Plan horizontal movement
Vector3 forward = cameraTransform.forward; forward.y = 0; forward.Normalize();
Vector3 right = cameraTransform.right; right.y = 0; right.Normalize();
Vector3 desired = (right * moveInput.x + forward * moveInput.y) * moveSpeed;
// 2) Jump
if (wantJump && grounded)
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
wantJump = false;
}
// 3) Apply gravity
velocity.y += gravity * Time.deltaTime;
// 4) Move — combine planar + vertical
Vector3 move = desired * Time.deltaTime + new Vector3(0, velocity.y, 0) * Time.deltaTime;
controller.Move(move);
// 5) Face direction of travel (when planar)
if (desired.sqrMagnitude > 0.01f)
{
Quaternion target = Quaternion.LookRotation(desired);
transform.rotation = Quaternion.Slerp(transform.rotation, target, 12f * Time.deltaTime);
}
}
}
// 6) Lifecycle order (most-used)
// Awake : once per object, before any Start
// OnEnable : whenever component becomes enabled
// Start : once, before first Update
// Update : every rendered frame (variable dt)
// FixedUpdate : every physics tick (50Hz by default)
// LateUpdate : after all Updates — camera follow lives here
// OnDisable / OnDestroy : symmetric to OnEnable / Awake
// 7) Performance tips
// • Cache GetComponent in Awake — don't call in Update
// • Reuse Vector / Quaternion structs (they're value types — cheap)
// • Avoid GameObject.Find / SendMessage in hot paths
// • Use the new Input System (com.unity.inputsystem) — old Input.GetAxis is legacy
// • Object pooling for bullets / enemies / particle bursts
Why it matters
The new Input System replaces the legacy Input class entirely — declarative actions, multiple devices, rebinding for free. Use it on every new project; the migration on a shipping game is painful but bounded.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
// MonoBehaviour script (drop on a GameObject)
using UnityEngine;
public class Mover : MonoBehaviour {
public float speed = 5f;
void Update() {
float h = Input.GetAxis("Horizontal");
transform.Translate(Vector3.right * h * speed * Time.deltaTime);
}
}
Try it Yourself »
Exercise
Unity per-frame callback.
void
() { /* every frame */ }
PascalCase.
Discussion
Loading…