การสร้าง Player Controller 3D พร้อม Rigidbody ใน Unity
การสร้างสคริปต์ Unity Player Controller 3D สำหรับตัวละครที่มี Rigidbody โดยมีคุณสมบัติดังนี้:
- ตัวละครจะ เดินและวิ่ง ไปในทิศทางที่ตัวละครกำลังหันหน้าไป
- ตัวละครสามารถ กระโดด ได้
- การ ตรวจสอบการสัมผัสพื้น จะใช้
OnCollisionEnter.CompareTag("Ground")
นี่คือคำอธิบายและการแนะนำโค้ดเบื้องต้นเป็นภาษาไทย:

การสร้าง Player Controller 3D พร้อม Rigidbody ใน Unity
แนวคิดหลักในการสร้าง Player Controller แบบนี้คือการใช้คอมโพเนนต์ Rigidbody เพื่อจัดการฟิสิกส์และการเคลื่อนที่ของตัวละคร ซึ่งจะทำให้การชนและการตอบสนองต่อแรงต่างๆ เป็นไปตามหลักฟิสิกส์ของเกม
1. การตั้งค่าตัวละคร (GameObject)
- สร้าง GameObject ที่เป็นตัวละครของคุณ (เช่น Capsule, Cube หรือ Model ที่คุณนำเข้า)
- เพิ่ม Rigidbody Component: เลือก GameObject ตัวละครของคุณใน Hierarchy, จากนั้นกด “Add Component” และค้นหา “Rigidbody”
- ข้อสำคัญ: ใน Rigidbody Component, ตรวจสอบให้แน่ใจว่าได้ Freeze Rotation บนแกน X และ Z (และอาจจะ Y ด้วย หากไม่ต้องการให้ตัวละครหมุนเอง) เพื่อป้องกันไม่ให้ตัวละครล้มหรือหมุนกลิ้งไปมาโดยไม่ตั้งใจ
- เพิ่ม Collider Component: ตัวละครของคุณควรมี Collider (เช่น Capsule Collider) ที่เหมาะสมกับรูปร่าง เพื่อใช้ในการชนกับวัตถุอื่นๆ และพื้น
- ตั้งค่า Tag “Ground”: สร้าง Tag ชื่อ “Ground” ใน Unity (ไปที่ Tags & Layers -> Tags -> Add Tag…) และกำหนด Tag นี้ให้กับ GameObject ที่เป็นพื้นหรือแพลตฟอร์มที่คุณต้องการให้ตัวละครรับรู้ว่าคือพื้น
2. สคริปต์ Player Controller (C#)
นี่คือโครงสร้างของสคริปต์ C# สำหรับควบคุมตัวละครของคุณ:
C#
using UnityEngine;
public class PlayerController3D : MonoBehaviour
{
public float moveSpeed = 5f; // ความเร็วในการเดิน/วิ่ง
public float jumpForce = 8f; // แรงกระโดด
public Transform playerCamera; // อ้างอิงถึงกล้อง (ถ้ากล้องอยู่ภายใต้ตัวละคร)
private Rigidbody rb;
private bool isGrounded; // สถานะว่าตัวละครอยู่บนพื้นหรือไม่
void Start()
{
rb = GetComponent<Rigidbody>();
// ตรึงการหมุนของ Rigidbody เพื่อไม่ให้ตัวละครล้มง่าย
rb.freezeRotation = true;
}
void Update()
{
HandleMovementInput();
HandleJumpInput();
}
void HandleMovementInput()
{
// รับค่า input จากแกนแนวนอน (A/D หรือลูกศรซ้าย/ขวา)
float horizontalInput = Input.GetAxis("Horizontal");
// รับค่า input จากแกนแนวตั้ง (W/S หรือลูกศรขึ้น/ลง)
float verticalInput = Input.GetAxis("Vertical");
// คำนวณทิศทางการเคลื่อนที่ตามทิศที่ตัวละครหันหน้า
Vector3 moveDirection = transform.forward * verticalInput + transform.right * horizontalInput;
moveDirection.Normalize(); // ทำให้เวกเตอร์มีขนาด 1 เพื่อให้ความเร็วคงที่ในทุกทิศทาง
// ใช้ Rigidbody.velocity เพื่อควบคุมการเคลื่อนที่
// รักษาความเร็วในแกน Y เดิมไว้ (แรงโน้มถ่วงหรือการกระโดด)
rb.velocity = new Vector3(moveDirection.x * moveSpeed, rb.velocity.y, moveDirection.z * moveSpeed);
}
void HandleJumpInput()
{
// ตรวจสอบว่ากดปุ่ม Spacebar และตัวละครอยู่บนพื้น
if (Input.GetButtonDown("Jump") && isGrounded)
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse); // ใช้ ForceMode.Impulse เพื่อให้กระโดดทันที
isGrounded = false; // กำหนดให้ไม่ลงพื้นทันทีหลังกระโดด
}
}
// ฟังก์ชันนี้จะถูกเรียกเมื่อ Collider ของตัวละครชนกับ Collider อื่น
void OnCollisionEnter(Collision collision)
{
// ตรวจสอบว่าวัตถุที่ชนมี Tag เป็น "Ground" หรือไม่
if (collision.gameObject.CompareTag("Ground"))
{
isGrounded = true; // ตั้งค่าว่าตัวละครอยู่บนพื้น
}
}
// ฟังก์ชันนี้จะถูกเรียกเมื่อ Collider ของตัวละครหยุดชนกับ Collider อื่น
void OnCollisionExit(Collision collision)
{
if (collision.gameObject.CompareTag("Ground"))
{
isGrounded = false; // ตั้งค่าว่าตัวละครไม่ได้อยู่บนพื้นแล้ว
}
}
}
คำอธิบายโค้ดโดยละเอียด:
public float moveSpeed = 5f;
: กำหนดความเร็วในการเคลื่อนที่ของตัวละครpublic float jumpForce = 8f;
: กำหนดแรงที่ใช้ในการกระโดดpublic Transform playerCamera;
: (ตัวเลือก) หากคุณต้องการให้ตัวละครเคลื่อนที่สัมพันธ์กับทิศทางกล้อง คุณจะต้องอ้างอิงถึงกล้องตรงนี้ แต่ในโค้ดตัวอย่างนี้ ตัวละครจะเคลื่อนที่ตามทิศทางที่ตัวมันหันหน้า (Local Space)private Rigidbody rb;
: ตัวแปรสำหรับเก็บ Rigidbody Component ของตัวละครprivate bool isGrounded;
: ตัวแปร Boolean สำหรับตรวจสอบว่าตัวละครกำลังยืนอยู่บนพื้นหรือไม่Start()
:rb = GetComponent<Rigidbody>();
: ดึง Rigidbody Component มาเก็บไว้ในตัวแปรrb
rb.freezeRotation = true;
: สำคัญมาก เพื่อป้องกันไม่ให้ Rigidbody หมุนเมื่อชนกับวัตถุอื่น
Update()
:HandleMovementInput()
: จัดการการรับ Input สำหรับการเดิน/วิ่งHandleJumpInput()
: จัดการการรับ Input สำหรับการกระโดด
HandleMovementInput()
:Input.GetAxis("Horizontal")
และInput.GetAxis("Vertical")
: รับค่าจากปุ่ม A/D/ลูกศรซ้าย/ขวา และ W/S/ลูกศรขึ้น/ลง ตามลำดับ ค่าที่ได้จะอยู่ระหว่าง -1 ถึง 1transform.forward * verticalInput + transform.right * horizontalInput;
: คำนวณทิศทางการเคลื่อนที่โดยอิงตามทิศทางที่ตัวละครหันหน้า (Local Space)transform.forward
คือทิศทางด้านหน้าของตัวละคร และtransform.right
คือทิศทางด้านขวาของตัวละครmoveDirection.Normalize();
: ทำให้เวกเตอร์ทิศทางมีขนาด 1 เพื่อให้ความเร็วในการเคลื่อนที่เฉียงไม่เร็วกว่าการเคลื่อนที่ตรงrb.velocity = new Vector3(moveDirection.x * moveSpeed, rb.velocity.y, moveDirection.z * moveSpeed);
: กำหนดความเร็วของ Rigidbody ในแกน X และ Z ตามทิศทางและmoveSpeed
โดยที่ รักษาความเร็วในแกน Y เดิมไว้ เพื่อให้แรงโน้มถ่วงและการกระโดดยังคงทำงาน
HandleJumpInput()
:Input.GetButtonDown("Jump")
: ตรวจสอบว่ากดปุ่ม “Jump” (โดยปกติคือ Spacebar) ในเฟรมปัจจุบันisGrounded
: ตรวจสอบว่าตัวละครอยู่บนพื้นก่อนที่จะกระโดดrb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
: เพิ่มแรงในทิศทางขึ้น (แกน Y) ให้กับ Rigidbody เพื่อให้ตัวละครกระโดดForceMode.Impulse
จะเป็นการเพิ่มแรงทันทีisGrounded = false;
: ตั้งค่าเป็น false ทันทีหลังกระโดด เพื่อป้องกันการกระโดดซ้ำกลางอากาศ
OnCollisionEnter(Collision collision)
:- ฟังก์ชันนี้จะถูกเรียกโดย Unity เมื่อ Collider ของ GameObject นี้ เริ่มชน กับ Collider ของ GameObject อื่น
collision.gameObject.CompareTag("Ground")
: ตรวจสอบว่า GameObject ที่ชนด้วยมี Tag เป็น “Ground” หรือไม่- ถ้าชนกับ “Ground” ก็จะตั้งค่า
isGrounded
เป็นtrue
OnCollisionExit(Collision collision)
:- ฟังก์ชันนี้จะถูกเรียกโดย Unity เมื่อ Collider ของ GameObject นี้ หยุดชน กับ Collider ของ GameObject อื่น
- ถ้าหยุดชนกับ “Ground” ก็จะตั้งค่า
isGrounded
เป็นfalse
วิธีใช้งานใน Unity:
- สร้างสคริปต์ C# ใหม่ (เช่น
PlayerController3D
) แล้วคัดลอกโค้ดข้างต้นไปวาง - ลากสคริปต์นี้ไปวางบน GameObject ตัวละครของคุณใน Hierarchy
- ตรวจสอบให้แน่ใจว่าได้ตั้งค่า Rigidbody และ Collider บนตัวละครของคุณแล้ว
- ตรวจสอบว่าพื้นหรือแพลตฟอร์มของคุณมี Collider และตั้ง Tag เป็น “Ground” แล้ว
- ปรับค่า
moveSpeed
และjumpForce
ใน Inspector ให้เหมาะสมกับเกมของคุณ