การสร้าง Player Controller 3D พร้อม Rigidbody ใน Unity

การสร้างสคริปต์ Unity Player Controller 3D สำหรับตัวละครที่มี Rigidbody โดยมีคุณสมบัติดังนี้:

  • ตัวละครจะ เดินและวิ่ง ไปในทิศทางที่ตัวละครกำลังหันหน้าไป
  • ตัวละครสามารถ กระโดด ได้
  • การ ตรวจสอบการสัมผัสพื้น จะใช้ OnCollisionEnter.CompareTag("Ground")

นี่คือคำอธิบายและการแนะนำโค้ดเบื้องต้นเป็นภาษาไทย:


การสร้าง Player Controller 3D พร้อม Rigidbody ใน Unity

แนวคิดหลักในการสร้าง Player Controller แบบนี้คือการใช้คอมโพเนนต์ Rigidbody เพื่อจัดการฟิสิกส์และการเคลื่อนที่ของตัวละคร ซึ่งจะทำให้การชนและการตอบสนองต่อแรงต่างๆ เป็นไปตามหลักฟิสิกส์ของเกม

1. การตั้งค่าตัวละคร (GameObject)

  1. สร้าง GameObject ที่เป็นตัวละครของคุณ (เช่น Capsule, Cube หรือ Model ที่คุณนำเข้า)
  2. เพิ่ม Rigidbody Component: เลือก GameObject ตัวละครของคุณใน Hierarchy, จากนั้นกด “Add Component” และค้นหา “Rigidbody”
    • ข้อสำคัญ: ใน Rigidbody Component, ตรวจสอบให้แน่ใจว่าได้ Freeze Rotation บนแกน X และ Z (และอาจจะ Y ด้วย หากไม่ต้องการให้ตัวละครหมุนเอง) เพื่อป้องกันไม่ให้ตัวละครล้มหรือหมุนกลิ้งไปมาโดยไม่ตั้งใจ
  3. เพิ่ม Collider Component: ตัวละครของคุณควรมี Collider (เช่น Capsule Collider) ที่เหมาะสมกับรูปร่าง เพื่อใช้ในการชนกับวัตถุอื่นๆ และพื้น
  4. ตั้งค่า 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 ถึง 1
    • transform.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:

  1. สร้างสคริปต์ C# ใหม่ (เช่น PlayerController3D) แล้วคัดลอกโค้ดข้างต้นไปวาง
  2. ลากสคริปต์นี้ไปวางบน GameObject ตัวละครของคุณใน Hierarchy
  3. ตรวจสอบให้แน่ใจว่าได้ตั้งค่า Rigidbody และ Collider บนตัวละครของคุณแล้ว
  4. ตรวจสอบว่าพื้นหรือแพลตฟอร์มของคุณมี Collider และตั้ง Tag เป็น “Ground” แล้ว
  5. ปรับค่า moveSpeed และ jumpForce ใน Inspector ให้เหมาะสมกับเกมของคุณ

เราใช้คุกกี้เพื่อพัฒนาประสิทธิภาพ และประสบการณ์ที่ดีในการใช้เว็บไซต์ของคุณ คุณสามารถศึกษารายละเอียดได้ที่ นโยบายความเป็นส่วนตัว และสามารถจัดการความเป็นส่วนตัวเองได้ของคุณได้เองโดยคลิกที่ ตั้งค่า

ตั้งค่าความเป็นส่วนตัว

คุณสามารถเลือกการตั้งค่าคุกกี้โดยเปิด/ปิด คุกกี้ในแต่ละประเภทได้ตามความต้องการ ยกเว้น คุกกี้ที่จำเป็น

ยอมรับทั้งหมด
จัดการความเป็นส่วนตัว
  • เปิดใช้งานตลอด

บันทึกการตั้งค่า