Phỏng vấn lập trình viên game Unity: C#, vòng đời MonoBehaviour và tối ưu hiệu năng

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Unity là một trong những engine phổ biến nhất cho game di động và game độc lập, vì vậy vị trí lập trình viên Unity luôn có nhu cầu. Phỏng vấn thường kiểm tra C#, hiểu biết về vòng đời đối tượng trong Unity, vật lý, hiệu năng và khả năng làm gameplay hoàn chỉnh. Bài này tổng hợp những chủ đề chính.

C# nền tảng trong bối cảnh game

  • Kiểu giá trị và kiểu tham chiếu: struct (như Vector3) là kiểu giá trị, class là kiểu tham chiếu. Hiểu điều này giúp tránh lỗi khi truyền và sao chép dữ liệu.
  • Interface và abstract class: dùng để thiết kế hệ thống vũ khí, kẻ địch, vật phẩm dễ mở rộng.
  • Delegate, event và UnityEvent: giao tiếp giữa các thành phần mà không phụ thuộc chặt.
  • Collections: List, Dictionary, Queue, HashSet và khi nào dùng.
  • Coroutine: tác vụ chạy qua nhiều khung hình, ví dụ chờ vài giây hoặc làm mờ dần.

Vòng đời MonoBehaviour

HàmKhi nào gọi
AwakeKhi đối tượng được nạp, trước mọi Start
OnEnableMỗi khi đối tượng được bật
StartTrước khung hình đầu tiên mà đối tượng hoạt động
UpdateMỗi khung hình
FixedUpdateTheo bước thời gian cố định, dùng cho vật lý
LateUpdateSau mọi Update, thường dùng cho camera đi theo
OnDisable, OnDestroyKhi bị tắt hoặc hủy, dọn dẹp tài nguyên

Câu hỏi kinh điển: khi nào dùng Update và khi nào dùng FixedUpdate? Đưa đầu vào và logic hiển thị vào Update, còn lực và di chuyển bằng Rigidbody vào FixedUpdate để kết quả vật lý ổn định, không phụ thuộc tốc độ khung hình.

Delta time

using UnityEngine;public class Mover : MonoBehaviour{    [SerializeField] private float speed = 5f;    void Update()    {        float h = Input.GetAxis("Horizontal");        transform.Translate(Vector3.right * h * speed * Time.deltaTime);    }}

Nhân với Time.deltaTime để chuyển động độc lập với tốc độ khung hình, nếu không máy mạnh chạy nhanh hơn máy yếu.

Vật lý và va chạm

  • Collider và Rigidbody: collider xác định hình dạng va chạm, Rigidbody cho phép chịu tác động của vật lý.
  • Trigger và Collision: trigger không gây phản lực, dùng để phát hiện vùng như nhặt vật phẩm (OnTriggerEnter); collision là va chạm vật lý thật (OnCollisionEnter).
  • Raycast: bắn tia để phát hiện vật cản, dùng cho ngắm bắn, kiểm tra mặt đất.
  • Layer và ma trận va chạm: tối ưu bằng cách chỉ cho phép các layer cần thiết va chạm với nhau.

Tối ưu hiệu năng

  • Object pooling: tái sử dụng đối tượng như đạn, hiệu ứng thay vì liên tục tạo và hủy, giảm áp lực bộ thu gom rác.
  • Tránh cấp phát bộ nhớ trong Update: không tạo chuỗi, danh sách, new liên tục mỗi khung hình.
  • Cache tham chiếu: gọi GetComponent một lần trong Awake thay vì mỗi khung hình; tránh Find trong vòng lặp.
  • Giảm draw call: gộp vật liệu, dùng atlas, batching.
  • Profiler: đo trước khi tối ưu, xác định điểm nghẽn là CPU, GPU hay bộ nhớ.
private Rigidbody rb;void Awake(){    rb = GetComponent<Rigidbody>(); // cache một lần}

Kiến trúc trong game

Unity dùng mô hình thành phần: một GameObject gồm nhiều Component. Hãy ưu tiên các script nhỏ, mỗi script một trách nhiệm. Dùng ScriptableObject để lưu dữ liệu cấu hình như chỉ số kẻ địch, vật phẩm, giúp dữ liệu tách khỏi code và dễ chỉnh bởi designer. Dùng sự kiện để giảm phụ thuộc giữa các hệ thống như điểm số, giao diện, âm thanh. Với dự án lớn, các mẫu thiết kế như State Machine cho nhân vật và AI, Observer cho sự kiện, Singleton có kiểm soát hoặc Service Locator thường được nhắc đến.

Giao diện, âm thanh và dữ liệu

  • UI: Canvas, các chế độ Render, neo (anchor) cho nhiều tỉ lệ màn hình.
  • Animation: Animator, State Machine, tham số điều khiển chuyển trạng thái.
  • Lưu dữ liệu: PlayerPrefs cho giá trị nhỏ, JSON hoặc file cho dữ liệu lớn hơn.
  • Âm thanh: AudioSource, AudioMixer.

Câu hỏi về dự án và kinh nghiệm

Nhà tuyển dụng game rất chuộng việc xem sản phẩm thật. Hãy chuẩn bị bản demo chạy được, dù nhỏ, kèm video ngắn hoặc bản build. Sẵn sàng trả lời: vòng lặp gameplay chính là gì, bạn gặp lỗi khó nhất nào, bạn tối ưu thế nào cho thiết bị yếu, nếu thêm một loại kẻ địch mới thì cần sửa gì. Việc tham gia game jam là cách rất tốt để có sản phẩm hoàn chỉnh trong thời gian ngắn và có chuyện để kể.

Kết luận

Lập trình game đòi hỏi vừa nắm vững C# vừa hiểu cách engine hoạt động. Hãy hoàn thành ít nhất một game nhỏ từ đầu đến cuối rồi tự mổ xẻ nó: kiến trúc, hiệu năng, những điều muốn làm lại. Đó là phần chuẩn bị tốt nhất cho phỏng vấn.

Nếu bạn muốn học Unity qua dự án thực hành, hãy xem các khóa game tại codebem.com.

author_photo
Nguyễn Đình Cường

0 comment