iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

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 */ }

Discussion

Loading…