EP 3 C# Script Unity101

Unity ใช้ C# เป็นภาษาหลักในการพัฒนาสคริปต์เพื่อควบคุมการทำงานต่าง ๆ ในเกม เช่น การควบคุมตัวละคร, การโต้ตอบกับวัตถุ, และการจัดการการเล่นเกม สำหรับบทความนี้จะกล่าวถึงการสร้างสคริปต์เพื่อใช้ร่วมกับ Unity และผนวกสคริปต์เข้ากับ GameObject อันเป็นวัตถุพื้นฐานของ Unity โดยใช้ตั้วอย่างการเคลื่อนของวัตถุ หรือผู้เล่น ให้รองรับการเคลื่อนที่ไปทางซ้าย ขวา หน้า และหลัง

ใช้ Unity Hub เพื่อจัดการเวอร์ชันของ Unity รวมถึงการสร้างโปรเจกต์ใหม่ และ Visual Studio เป็นตัวแก้ไขโค้ดที่มีการเชื่อมต่อกับ Unity อย่างดี คุณสามารถแก้ไขโค้ด C# ได้ใน Visual Studio

  1. เปิด Unity Hub และคลิกที่ปุ่ม “New Project”
  2. เลือกแม่แบบ (Template) ของโปรเจกต์ที่คุณต้องการ เช่น 3D หรือ 2D
  3. ตั้งชื่อโปรเจกต์ของคุณ และเลือกที่เก็บไฟล์ จากนั้นคลิก “Create Project”

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

Unity สร้างไฟล์ C# ในลักษณะของ “สคริปต์” ซึ่งแต่ละสคริปต์จะผูกกับวัตถุในเกม (GameObject)

  1. ไปที่ Project Window และคลิกขวาที่ Assets → Create → Scripting → MonoBehaviour Script
  2. ตั้งชื่อสคริปต์เป็น PlayerMovement.cs โดยการคลิกขวาที่ไอคอนของสคริปต์แล้วเลือก Rename หลังจากนั้นเปลี่ยนชื่อเป้น PlayerMovement
  3. ดับเบิ้ลคลิกไฟล์นั้นเพื่อเปิดใน Visual Studio

ภาพไอคอนของสคริปต์ที่สร้างขึ้น

ให้คลิกขวาที่ NreMonoBehaviourScript เพื่อเลือกเมนู Rename

เปลี่ยนชื่อเป็น PlayerMovement

เมื่อเปิดสคริปต์ PlayerMovement.cs จะเห็นโครงสร้างพื้นฐานแบบนี้

ให้เปลี่ยนชื่อคลาสจาก NreMonoBehaviourScript เป็น PlayerMovement โค้ดใหม่ข้างล่างนี้ เนื่องจากชื่อคลาสจะต้องเป็นชื่อเดียวกับชื่อไฟล์ และตอนที่สร้างสคริปต์นั้นตัวโปรแกรม Unity สร้างชื่ออัตรโนมัติมาให้เป็น NreMonoBehaviourScript แต่ในหัวข้อก่อนหน้านี้ได้ทำการเปลี่ยนชื่อไฟล์เป็น PlayerMovement จึงต้องเปลี่ยนชื่อของคลาสให้ตรงกัน หลังจากนั้นให้ทำการสั่งบันทึก

using UnityEngine; 

public class PlayerMovement : MonoBehaviour 
{
    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start() {
     // คำสั่งสำหรับเรียกใช้งานเมื่อเริ่มเกม (ทำงานเพียงครั้งเดียว)
    } 
    // Update is called once per frame
    void Update() {
     // คำสั่งที่ต้องการเรียกใช้งานทุกเฟรม
   }
 }  

จากคลาสหลักที่ชื่อ PlayerMovement จะมีขั้นตอนการทำงานดังผังงาน คือ

จากภาพด้านบนจะพบว่า เมื่อฉากถูกโหลดเข้าหน่วยความจำแล้วเริ่มทำงานจะเรียก Start() ให้ทำงาน เมื่อทำงานเสร็จจะเรียก Update() ฒาทำงานในทุกเฟรม

  • Start(): ฟังก์ชันนี้จะถูกเรียกครั้งเดียวเมื่อเกมเริ่มต้น คุณสามารถใช้เพื่อกำหนดค่าเริ่มต้นสำหรับวัตถุหรือองค์ประกอบในเกม
  • Update(): ฟังก์ชันนี้จะถูกเรียกทุกๆ เฟรม ซึ่งเหมาะสำหรับการควบคุมพฤติกรรมที่เปลี่ยนแปลงบ่อย เช่น การตรวจสอบการเคลื่อนไหว

สมมติว่าคุณมีตัวละครในเกมที่ต้องการควบคุมให้เคลื่อนที่ คุณสามารถใช้โค้ดดังนี้ [อ่านเพิ่มเติมได้จากบทความการเคลื่อนที่ 2 มิติ และการเคลื่อนที่ #2] เมื่อปรับแก้โค้ดเสร็จให้ทำการบันทึกอีกครั้ง

using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public float speed = 5.0f; // ความเร็วในการเคลื่อนไหวของตัวละคร
    void Start()
    {
        Debug.Log("Game Started");
    }

    void Update()
    {
        // รับข้อมูลการกดปุ่มลูกศรหรือ WASD เพื่อควบคุมการเคลื่อนที่
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");
        // สร้างเวกเตอร์การเคลื่อนที่
        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
        // เคลื่อนที่ตัวละครตามเวกเตอร์
        transform.Translate(movement * speed * Time.deltaTime);
    }
}
  • Input.GetAxis(“Horizontal”) รับค่าจากปุ่มที่ใช้ในการควบคุมทิศทางในแนวนอน ได้แก่ A, D, ลูกศรซ้าย หรือลูกศรขวา
  • Input.GetAxis(“Vertical”): รับค่าจากปุ่มที่ใช้ในการควบคุมทิศทางในแนวตั้ง ได้แก่ W, S, ลูกศรขึ้น หรือลูกศรลง
  • transform.Translate() ใช้สำหรับเลื่อนตำแหน่งของวัตถุในเกม (GameObject) ตามเวกเตอร์ movement
  • Time.deltaTime ใช้สำหรับคำนวณเวลาในแต่ละเฟรมเพื่อทำให้การเคลื่อนที่ราบรื่น

จาก Visual Studio ให้กลับไปยังโปรแกรม Unity แล้วสร้างส่วนของพื้น และตัวผู้เล่น โดยเริ่มจากการสร้างตัวละครและพื้นในฉากหลัก ด้วยการคลิกขวาที่ส่วนของ Hierachy แล้วเลือกรายการ GameObject -> 3D Object ->Cube แล้วปรับขนาดให้ให้เป็นส่วนของพื้น

เมื่อเปลี่ยนการแสดงผลเป็น Tab ชื่อ Game จะมองเห็นเป็นดังภาพด้านล่าง

ให้เปลี่ยนชื่อจาก Cube เป็น TheFloor โดยการคลิกขวาแล้วเลือก Rename

หลังจากนั้นเปลี่ยนชื่อของ Cube เป็น TheFloor

ขั้นตอนต่อไปเป็นการเพิ่ม GameObject ประเภท Cube แต่ให้กำหนดตำแหน่งอยู่เหลือ TheFloor และเปลี่ยนชื่อเป็น Player

ให้ลากลากสคริปต์ที่สร้างขึ้น เช่น PlayerMovement.cs ไปวางบน GameObject ที่ต้องการควบคุม เช่น ตัวละครในเกม หลังจากนั้นจะปรากฎฟิลด์ speed ใน Inspector ซึ่งคุณสามารถปรับความเร็วได้ตามต้องการ

เมื่อตั้งค่าและเขียนโค้ดต่าง ๆ เรียบร้อยให้ทดลองรันโปรแกรมได้ แต่ถ้าหากโค้ดไม่ทำงานตามที่คาดหวัง หรือมีข้อผิดพลาด คุณสามารถใช้ Debug.Log() เพื่อแสดงข้อมูลใน Console ของ Unity เพื่อช่วยในการแก้ไขปัญหา

Debug.Log("This is a debug message");

นอกจากนี้ สามารถเพิ่มฟังก์ชันเพิ่มเติมได้ เช่น การกระโดด (Jump), การหมุนตัวละคร, หรือการใช้ฟิสิกส์ (Physics) ในการควบคุมการชนกันของวัตถุ (รายละเอียดเขียนไว้ในบทความ การเคลื่อนที่ #2)

public float jumpForce = 10.0f;
private bool isGrounded = true;  // ตรวจสอบว่าตัวละครอยู่บนพื้น

void Update() {    // ตรวจสอบปุ่มกระโดด    
    if (Input.GetButtonDown("Jump") && isGrounded)    {            
        GetComponent<Rigidbody>().AddForce(Vector3.up * jumpForce, 
                                           ForceMode.Impulse);        
        isGrounded = false; // ตัวละครลอยอยู่   
    }
}

void OnCollisionEnter(Collision collision){
    // ตรวจสอบว่าตัวละครชนกับพื้นหรือไม่   
    if (collision.gameObject.tag == "Ground")    {        
      isGrounded = true;    
   }
}

จากบทความนี้ ผู้อ่านจะเห็นภาพรวมของการนำโค้ดภาษา C# ผนวกเข้ากับ GameObject อันเป็นวัตถุใด ๆ ที่ถูกใช้ใน Unity โดยโค้ดที่เขียนนั้นมีหน้าที่ทำงาน และสามารถตอบสนองกับเหตุการณ์ต่าง ๆ ที่ทาง Unity เตรียมไว้ให้ เช่น OnCollisionStay() ที่เอาไว้ใช้ตอบสนองเหตุการณ์ที่เกิดการชนกันของวัตถุ หรือ OnCollisionExit() สำหรับทำงานเมื่อเกิดเหตุการณ์สิ้นสุดการชนกันของวัตถุ ทำให้สามารถออกเกมหรือให้เกมทำงานที่ซับซ้อนมากยิ่งขึ้นเมื่อนำไปผนวกการจำแนกประเภทวัตถุตาม tag ที่กำหนด

สุดท้ายนี้ขอให้สนุกกับการเขียนเกมครับ

(C) 2024, โดย จารุต บุศราทิจ
DcG.IT@PBRU

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *