วิธีการสร้างและเขียน Script การให้คะแนน แบบ 3 มิติ

โดยการแยกโค้ดออกเป็นหลาย Class เพื่อให้การจัดการโปรเจกต์ให้เป็นระเบียบและง่ายต่อการบำรุงรักษา (Modular Design)


1. Class สำหรับแสดงผลคะแนน (ScoreManager)

Class นี้จะรับผิดชอบในการเก็บคะแนนปัจจุบันและแสดงผลบน UI (เช่น Text Component).

C#

using UnityEngine;
using TMPro; // ถ้าใช้ TextMeshPro
using System; // สำหรับ Action, หากต้องการ Event

public class ScoreManager : MonoBehaviour
{
    // ใช้ TextMeshProUGUI ถ้าคุณใช้ TextMeshPro ในโปรเจกต์ของคุณ
    // ถ้าใช้ UI.Text ปกติ ให้เปลี่ยนเป็น public Text scoreText;
    public TextMeshProUGUI scoreText; 
    public int currentScore = 0;

    // Event สำหรับแจ้งเตือนเมื่อคะแนนมีการเปลี่ยนแปลง (ไม่จำเป็นแต่มีประโยชน์)
    public static event Action<int> OnScoreChanged;

    void Start()
    {
        UpdateScoreDisplay(); // อัปเดตคะแนนเริ่มต้นเมื่อเกมเริ่ม
    }

    // เมธอดสำหรับเพิ่มคะแนน
    public void AddScore(int amount)
    {
        currentScore += amount;
        UpdateScoreDisplay();
        OnScoreChanged?.Invoke(currentScore); // เรียกใช้ Event เมื่อคะแนนเปลี่ยน
    }

    // เมธอดสำหรับลดคะแนน
    public void DeductScore(int amount)
    {
        currentScore -= amount;
        if (currentScore < 0) // ไม่ให้คะแนนติดลบ (ปรับเปลี่ยนได้ตามต้องการ)
        {
            currentScore = 0;
        }
        UpdateScoreDisplay();
        OnScoreChanged?.Invoke(currentScore); // เรียกใช้ Event เมื่อคะแนนเปลี่ยน
    }

    // เมธอดสำหรับอัปเดตการแสดงผลคะแนนบน UI
    void UpdateScoreDisplay()
    {
        if (scoreText != null)
        {
            scoreText.text = "Score: " + currentScore.ToString();
        }
    }
}

คำอธิบาย:

  • using TMPro;: บรรทัดนี้จำเป็นถ้าคุณใช้ TextMeshPro สำหรับแสดงข้อความ ซึ่งเป็นที่นิยมมากกว่า UI.Text แบบเก่า
  • public TextMeshProUGUI scoreText;: ตัวแปรนี้จะใช้เชื่อมต่อกับ GameObject ที่มี Component TextMeshProUGUI (หรือ Text) เพื่อแสดงผลคะแนน
  • public int currentScore = 0;: เก็บค่าคะแนนปัจจุบัน
  • public static event Action<int> OnScoreChanged;: นี่คือ Event ที่จะถูกเรียกเมื่อคะแนนมีการเปลี่ยนแปลง ทำให้ Class อื่นๆ สามารถ “ฟัง” การเปลี่ยนแปลงนี้ได้ (เช่น เมื่อคะแนนเปลี่ยน ให้แสดง Effect บางอย่าง)
  • AddScore(int amount): เมธอดสำหรับเพิ่มคะแนน โดยรับค่า amount ที่ต้องการเพิ่ม
  • DeductScore(int amount): เมธอดสำหรับลดคะแนน โดยรับค่า amount ที่ต้องการลด มีการตรวจสอบไม่ให้คะแนนติดลบ
  • UpdateScoreDisplay(): อัปเดตข้อความบน UI ให้ตรงกับ currentScore ปัจจุบัน

2. Class Object ที่ถูกชนคะแนนเพิ่ม (ScoreBooster)

Class นี้จะถูกแนบไปกับ GameObject ที่เมื่อผู้เล่นชนแล้วคะแนนจะเพิ่มขึ้น

C#

using UnityEngine;

public class ScoreBooster : MonoBehaviour
{
    public int scoreToGive = 10; // คะแนนที่จะเพิ่มให้เมื่อชน
    public string playerTag = "Player"; // Tag ของผู้เล่นที่ชน

    // เรียกเมื่อมีการชนกัน (สำหรับ Trigger Collider)
    void OnTriggerEnter(Collider other)
    {
        // ตรวจสอบว่าวัตถุที่ชนมี Tag ตรงกับ playerTag หรือไม่
        if (other.CompareTag(playerTag))
        {
            // ค้นหา ScoreManager ใน Scene
            ScoreManager scoreManager = FindObjectOfType<ScoreManager>();
            if (scoreManager != null)
            {
                scoreManager.AddScore(scoreToGive); // เพิ่มคะแนน
                Destroy(gameObject); // ทำลาย Object นี้หลังจากชน (หรือซ่อน/ปิดใช้งาน)
            }
            else
            {
                Debug.LogWarning("ScoreManager not found in the scene!");
            }
        }
    }

    // ถ้าใช้ OnCollisionEnter (สำหรับ Non-Trigger Collider)
    /*
    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag(playerTag))
        {
            ScoreManager scoreManager = FindObjectOfType<ScoreManager>();
            if (scoreManager != null)
            {
                scoreManager.AddScore(scoreToGive);
                Destroy(gameObject);
            }
            else
            {
                Debug.LogWarning("ScoreManager not found in the scene!");
            }
        }
    }
    */
}

คำอธิบาย:

  • public int scoreToGive = 10;: กำหนดจำนวนคะแนนที่จะได้รับ
  • public string playerTag = "Player";: ใช้เพื่อระบุว่าวัตถุที่ชนนั้นคือผู้เล่น โดยผู้เล่นของคุณจะต้องตั้งค่า Tag เป็น “Player” ใน Inspector
  • OnTriggerEnter(Collider other): เมธอดนี้จะถูกเรียกเมื่อ GameObject ที่มี Script นี้และมี Collider แบบ Is Trigger (ถูกติ๊กใน Inspector) ชนกับ Collider อื่น
  • other.CompareTag(playerTag): ตรวจสอบว่า Collider ที่ชนกันนั้นมี Tag ตรงกับ playerTag ที่เรากำหนดไว้หรือไม่
  • FindObjectOfType<ScoreManager>(): ค้นหา Instance ของ ScoreManager ใน Scene เพื่อเรียกใช้เมธอด AddScore()
  • Destroy(gameObject);: ทำลาย GameObject ของ ScoreBooster นี้หลังจากถูกชน เพื่อไม่ให้เพิ่มคะแนนซ้ำ หรือคุณอาจจะเลือกที่จะปิดการใช้งาน ( gameObject.SetActive(false);) แทนก็ได้

3. Class Object ที่ถูกชนคะแนนลด (ScorePunisher)

Class นี้จะถูกแนบไปกับ GameObject ที่เมื่อผู้เล่นชนแล้วคะแนนจะลดลง

C#

using UnityEngine;

public class ScorePunisher : MonoBehaviour
{
    public int scoreToDeduct = 5; // คะแนนที่จะลดเมื่อชน
    public string playerTag = "Player"; // Tag ของผู้เล่นที่ชน

    // เรียกเมื่อมีการชนกัน (สำหรับ Trigger Collider)
    void OnTriggerEnter(Collider other)
    {
        // ตรวจสอบว่าวัตถุที่ชนมี Tag ตรงกับ playerTag หรือไม่
        if (other.CompareTag(playerTag))
        {
            // ค้นหา ScoreManager ใน Scene
            ScoreManager scoreManager = FindObjectOfType<ScoreManager>();
            if (scoreManager != null)
            {
                scoreManager.DeductScore(scoreToDeduct); // ลดคะแนน
                // ไม่ได้ทำลาย Object นี้ เพื่อให้สามารถชนได้อีก (ปรับเปลี่ยนได้)
            }
            else
            {
                Debug.LogWarning("ScoreManager not found in the scene!");
            }
        }
    }

    // ถ้าใช้ OnCollisionEnter (สำหรับ Non-Trigger Collider)
    /*
    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag(playerTag))
        {
            ScoreManager scoreManager = FindObjectOfType<ScoreManager>();
            if (scoreManager != null)
            {
                scoreManager.DeductScore(scoreToDeduct);
            }
            else
            {
                Debug.LogWarning("ScoreManager not found in the scene!");
            }
        }
    }
    */
}

คำอธิบาย:

  • public int scoreToDeduct = 5;: กำหนดจำนวนคะแนนที่จะถูกลด
  • การทำงานส่วนใหญ่คล้ายกับ ScoreBooster เพียงแต่เรียกใช้เมธอด DeductScore() ของ ScoreManager แทน
  • ในตัวอย่างนี้ ผมไม่ได้ใส่ Destroy(gameObject) ใน ScorePunisher เพื่อให้ผู้เล่นสามารถถูกลดคะแนนได้อีกครั้งเมื่อชน Object เดิม (เช่น หลุมอันตราย) แต่คุณสามารถเพิ่มได้ถ้าต้องการให้ Object นั้นหายไปหลังชน

วิธีการนำไปใช้งานใน Unity Editor:

  1. สร้าง C# Scripts:
    • ใน Project Window, คลิกขวา > Create > C# Script แล้วตั้งชื่อว่า ScoreManager, ScoreBooster, และ ScorePunisher
    • คัดลอกโค้ดข้างต้นไปวางใน Script ที่เกี่ยวข้อง
  2. ตั้งค่า UI สำหรับแสดงคะแนน:
    • ใน Hierarchy Window, คลิกขวา > UI > Text – TextMeshPro (ถ้าใช้ TextMeshPro) หรือ Text (Legacy) (ถ้าใช้ UI.Text ปกติ)
    • ติดตั้ง TMP Essentials (ถ้ามี Pop-up ขึ้นมาสำหรับ TextMeshPro)
    • ปรับตำแหน่งและขนาดของ Text ตามต้องการ
    • สร้าง GameObject เปล่า (Empty GameObject) ใน Hierarchy ตั้งชื่อว่า “GameManager”
    • ลาก Script ScoreManager ไปวางบน GameObject “GameManager”
    • ใน Inspector ของ “GameManager” ลาก Component TextMeshProUGUI (หรือ Text) ที่คุณสร้างไว้ ไปใส่ในช่อง Score Text ของ ScoreManager
  3. ตั้งค่า Player Tag:
    • เลือก GameObject ผู้เล่นของคุณใน Hierarchy
    • ใน Inspector ตรงส่วน Tag, คลิกที่ Dropdown และเลือก “Add Tag…”
    • คลิกเครื่องหมาย + และพิมพ์ “Player” แล้ว Save
    • กลับไปที่ GameObject ผู้เล่นของคุณ แล้วเลือก Tag เป็น “Player”
  4. สร้าง Object ที่เพิ่ม/ลดคะแนน:
    • สร้าง Cube (หรือ Object อื่นๆ) ใน Scene
    • เพิ่ม Component Collider (เช่น Box Collider) และ Rigidbody ให้กับ Object นั้น
    • สำหรับ ScoreBooster และ ScorePunisher:
      • ถ้าต้องการใช้ OnTriggerEnter (ซึ่งแนะนำสำหรับการเก็บ/ลดคะแนนแบบไม่ชนจริง): ให้ติ๊กช่อง Is Trigger ใน Collider Component
      • ถ้าต้องการใช้ OnCollisionEnter (สำหรับวัตถุที่ชนแล้วเกิดแรงกระทำด้วย): ไม่ต้องติ๊ก Is Trigger
    • ลาก Script ScoreBooster หรือ ScorePunisher ไปวางบน Object นั้น
    • ปรับค่า Score To Give หรือ Score To Deduct ตามต้องการใน Inspector

ตอนนี้เมื่อผู้เล่น (ที่มี Tag เป็น “Player” และมี Collider/Rigidbody) ชนกับ Object ที่มี Script ScoreBooster หรือ ScorePunisher คะแนนก็จะมีการเปลี่ยนแปลงตามที่คุณตั้งค่าไว้ครับ

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

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

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

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

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