วิธีการสร้างและเขียน 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” ใน InspectorOnTriggerEnter(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:
- สร้าง C# Scripts:
- ใน Project Window, คลิกขวา > Create > C# Script แล้วตั้งชื่อว่า
ScoreManager
,ScoreBooster
, และScorePunisher
- คัดลอกโค้ดข้างต้นไปวางใน Script ที่เกี่ยวข้อง
- ใน Project Window, คลิกขวา > Create > C# Script แล้วตั้งชื่อว่า
- ตั้งค่า 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
- ตั้งค่า Player Tag:
- เลือก GameObject ผู้เล่นของคุณใน Hierarchy
- ใน Inspector ตรงส่วน Tag, คลิกที่ Dropdown และเลือก “Add Tag…”
- คลิกเครื่องหมาย + และพิมพ์ “Player” แล้ว Save
- กลับไปที่ GameObject ผู้เล่นของคุณ แล้วเลือก Tag เป็น “Player”
- สร้าง 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
คะแนนก็จะมีการเปลี่ยนแปลงตามที่คุณตั้งค่าไว้ครับ