Rigidbody
Rigidbody trao GameObject cho physics engine — trọng lực, lực tác dụng, vận tốc và va chạm đều do Unity Physics tính toán, không phải vòng Update của bạn.
Hãy tưởng tượng...
Rigidbody giống như linh hồn vật lý của đồ vật. Trước khi có Rigidbody, một cái hộp chỉ là hình ảnh đứng yên trong không trung. Sau khi thêm Rigidbody, nó trở thành vật thể có khối lượng thực — bị hút xuống bởi trọng lực, bật lại khi va chạm, trượt khi có lực. Bạn tương tác với nó qua `AddForce()` như tay đẩy, không phải chỉnh `transform.position` trực tiếp.
Khái niệm chi tiết
Rigidbody đăng ký GameObject với Unity Physics Engine.
Các thuộc tính chính: mass (kg), drag (cản không khí),
angularDrag (cản xoay), useGravity, isKinematic.
ForceMode: Force (liên tục, tính mass),
Acceleration (liên tục, bỏ qua mass), Impulse (tức thời, tính mass —
dùng cho jump), VelocityChange (tức thời, bỏ qua mass).
Kinematic Rigidbody:
isKinematic = true — vẫn tham gia collision detection nhưng không bị lực/trọng lực
tác động. Di chuyển qua MovePosition(). Dùng cho moving platforms, animated
objects.
Lưu ý quan trọng: Không gọi
transform.position trực tiếp trên Rigidbody non-kinematic — sẽ teleport và phá vỡ
physics simulation. Luôn dùng AddForce() hoặc velocity.
Sơ đồ: Forces & ForceMode
ForceMode Types
Force
Liên tục, tính mass. Dùng cho rocket engine, wind...
rb.AddForce(dir * 10f)Impulse
Tức thời, tính mass. Dùng cho jump, explosion knockback
rb.AddForce(Vector3.up * 5f, ForceMode.Impulse)VelocityChange
Tức thời, bỏ qua mass. Đặt velocity trực tiếp
rb.AddForce(dir, ForceMode.VelocityChange)Rigidbody Properties
Constraints (Freeze)
Hướng dẫn thực hành
Thêm Rigidbody Component
Inspector → Add Component → Physics → Rigidbody. Cũng cần thêm Collider để có va chạm.
Cache Rigidbody trong Awake
_rb = GetComponent<Rigidbody>() — dùng trong FixedUpdate.
Di chuyển qua forces trong FixedUpdate
Không dùng transform.position. Dùng AddForce() hoặc set velocity.
Freeze Rotation cho 2D top-down
Inspector → Constraints → Freeze Rotation X, Y, Z để tránh object xoay khi va chạm.
Dùng isKinematic cho Moving Platforms
Platform di chuyển theo animation → isKinematic = true + MovePosition().
Trình mô phỏng tương tác
Click canvas để spawn object. Điều chỉnh Gravity, Mass, Drag và xem vật lý thay đổi. Nhấn Force Up để thêm lực.
Ví dụ Code
Cơ bảnDi chuyển và jump với Rigidbody.
using UnityEngine;
public class PhysicsPlayer : MonoBehaviour
{
[SerializeField] private float moveForce = 10f;
[SerializeField] private float jumpForce = 7f;
[SerializeField] private float maxSpeed = 8f;
private Rigidbody _rb;
private Vector3 _input;
private bool _grounded;
void Awake() => _rb = GetComponent<Rigidbody>();
void Update()
{
_input = new Vector3(Input.GetAxisRaw("Horizontal"), 0,
Input.GetAxisRaw("Vertical"));
if (Input.GetButtonDown("Jump") && _grounded)
_rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
void FixedUpdate()
{
// Giới hạn tốc độ theo mặt phẳng ngang
Vector3 flatVel = new Vector3(_rb.velocity.x, 0f, _rb.velocity.z);
if (flatVel.magnitude > maxSpeed)
_rb.velocity = flatVel.normalized * maxSpeed + Vector3.up * _rb.velocity.y;
_rb.AddForce(_input.normalized * moveForce, ForceMode.Force);
}
private void OnCollisionEnter(Collision col)
=> _grounded = col.gameObject.CompareTag("Ground");
private void OnCollisionExit(Collision col)
=> _grounded = false;
}Ví dụ Code
Nâng caoExplosion force với AddExplosionForce — ném vật thể theo hướng tâm vụ nổ.
using UnityEngine;
public class Explosion : MonoBehaviour
{
[SerializeField] private float force = 500f;
[SerializeField] private float radius = 5f;
[SerializeField] private float upModifier = 0.5f;
public void Explode()
{
// Tìm tất cả Collider trong bán kính
Collider[] cols = Physics.OverlapSphere(transform.position, radius);
foreach (var col in cols)
{
var rb = col.GetComponent<Rigidbody>();
if (rb == null) continue;
// Unity tự tính lực theo khoảng cách
rb.AddExplosionForce(force, transform.position, radius, upModifier);
}
// Visual effect + destroy
GetComponent<ParticleSystem>()?.Play();
Destroy(gameObject, 2f);
}
}📌 Ghi nhớ nhanh
- ▸Forces → FixedUpdate; Input → Update
- ▸Jump:
AddForce(up, ForceMode.Impulse) - ▸Không gọi
transform.positiontrên non-kinematic RB - ▸Moving platform → isKinematic + MovePosition
⚠️ Lỗi thường gặp
❌ transform.position trực tiếp trên Rigidbody
Teleport — phá vỡ physics, xuyên tường, glitch collision
✅ rb.MovePosition() hoặc velocity
❌ Physics code trong Update thay vì FixedUpdate
Không đồng bộ với physics timestep → jitter, tunneling
✅ Mọi AddForce/velocity → FixedUpdate