บทที่ 9: การสร้างระบบจัดการผู้เล่นหลายคน
การพัฒนาเกมที่มีระบบผู้เล่นหลายคน (Multiplayer) ช่วยเพิ่มความสนุกและความท้าทายให้กับเกม โดยให้ผู้เล่นสามารถเล่นและโต้ตอบกันได้ในโลกเดียวกัน การสร้างระบบนี้จำเป็นต้องใช้ความรู้เกี่ยวกับเครือข่าย (Networking) ใน Unity มีเครื่องมือที่ช่วยให้การพัฒนาเกมหลายผู้เล่นเป็นไปได้ง่ายขึ้น เช่น Unity Netcode for GameObjects และ Photon ซึ่งเป็น SDK ยอดนิยมที่ใช้ในการพัฒนาเกมแบบผู้เล่นหลายคน
ในบทนี้ เราจะเน้นไปที่การสร้างระบบผู้เล่นหลายคนแบบพื้นฐาน โดยใช้ Unity Netcode for GameObjects เพื่อให้ผู้เล่นสามารถเชื่อมต่อเข้ามาเล่นพร้อมกันได้ในเกมเดียว รวมถึงการจัดการการควบคุมผู้เล่นและการสื่อสารข้อมูลระหว่างผู้เล่นในเครือข่ายเดียวกัน
การติดตั้ง Unity Netcode for GameObjects
- เปิด Package Manager โดยไปที่ Window > Package Manager
- ในช่องค้นหา ให้พิมพ์ Netcode for GameObjects แล้วเลือกติดตั้งแพ็กเกจนี้
- เมื่อติดตั้งเสร็จเรียบร้อย Unity จะพร้อมใช้งานระบบ Netcode เพื่อสร้างเกมหลายผู้เล่น
การตั้งค่าเซิร์ฟเวอร์และผู้เล่น (Server and Client Setup)
การสร้างเกมหลายผู้เล่นจำเป็นต้องมีการตั้งค่าเซิร์ฟเวอร์เพื่อรองรับการเชื่อมต่อจากผู้เล่นหลายคน เซิร์ฟเวอร์จะทำหน้าที่เป็นตัวกลางที่ควบคุมการแลกเปลี่ยนข้อมูลระหว่างผู้เล่น ในขณะที่ผู้เล่นแต่ละคนจะเชื่อมต่อในฐานะ Client
ขั้นตอนการสร้างเซิร์ฟเวอร์และ Client ใน Unity
- สร้างสคริปต์ใหม่ชื่อ MultiplayerManager.cs และใช้เพื่อจัดการการเชื่อมต่อเซิร์ฟเวอร์และ Client
- ใช้คลาส NetworkManager ซึ่งเป็นคอมโพเนนต์หลักในการจัดการระบบเครือข่ายของ Unity
ตัวอย่างโค้ดการตั้งค่าเซิร์ฟเวอร์และ Client
using UnityEngine;
using Unity.Netcode;
public class MultiplayerManager : MonoBehaviour
{
void OnGUI()
{
if (!NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsServer)
{
if (GUILayout.Button("Host"))
{
NetworkManager.Singleton.StartHost(); // เริ่มเซิร์ฟเวอร์
}
if (GUILayout.Button("Join"))
{
NetworkManager.Singleton.StartClient(); // เข้าร่วมเป็น Client
}
}
}
}
คำอธิบายโค้ด
- NetworkManager.Singleton.StartHost() จะเริ่มเซิร์ฟเวอร์และทำให้เครื่องที่รันกลายเป็นโฮสต์
- NetworkManager.Singleton.StartClient() จะทำให้เครื่องที่รันกลายเป็นผู้เล่นที่เข้าร่วม (Client) โดยเชื่อมต่อไปยังเซิร์ฟเวอร์ที่กำหนด
การควบคุมผู้เล่นหลายคน (Multiplayer Player Control)
เมื่อตั้งค่าเซิร์ฟเวอร์และ Client แล้ว เราจำเป็นต้องสร้างตัวละครสำหรับผู้เล่นแต่ละคน และทำให้สามารถควบคุมตัวละครของตนเองได้ โดยใช้ฟังก์ชัน NetworkBehaviour ที่ช่วยให้เราจัดการกับการควบคุมตัวละครในเครือข่ายได้
ขั้นตอนการสร้างตัวละครที่สามารถควบคุมได้
- สร้างตัวละครที่เป็น Prefab เช่น PlayerPrefab
- เพิ่มคอมโพเนนต์ NetworkObject ให้กับ Prefab ตัวละครนี้ เพื่อให้สามารถควบคุมผ่านระบบเครือข่ายได้
- เขียนสคริปต์ควบคุมการเคลื่อนไหวของตัวละครโดยใช้ NetworkBehaviour
ตัวอย่างโค้ดการควบคุมตัวละครของผู้เล่นในเครือข่าย
using UnityEngine;
using Unity.Netcode;
public class PlayerController : NetworkBehaviour
{
public float moveSpeed = 5f;
void Update()
{
if (!IsOwner) return; // ตรวจสอบว่าเป็นผู้เล่นที่ควบคุมตัวละครนี้หรือไม่
float moveX = Input.GetAxis("Horizontal") * moveSpeed * Time.deltaTime;
float moveZ = Input.GetAxis("Vertical") * moveSpeed * Time.deltaTime;
transform.Translate(new Vector3(moveX, 0, moveZ)); // การเคลื่อนที่ของผู้เล่น
}
}
คำอธิบายโค้ด
- IsOwner ใช้ตรวจสอบว่าผู้เล่นที่ควบคุมตัวละครนี้เป็นเจ้าของตัวละครจริงหรือไม่ เพื่อป้องกันการควบคุมตัวละครของผู้เล่นอื่น
- การเคลื่อนไหวของตัวละครใช้ฟังก์ชัน Translate() ในการเลื่อนตำแหน่งตามทิศทางที่ผู้เล่นกดปุ่ม
การสื่อสารข้อมูลระหว่างผู้เล่น (Data Synchronization)
การสื่อสารข้อมูลในระบบผู้เล่นหลายคนเป็นเรื่องสำคัญ เช่น การส่งข้อมูลตำแหน่ง, สถานะของตัวละคร, หรือการกระทำต่าง ๆ ระหว่างผู้เล่น ใน Unity เราสามารถใช้ NetworkVariable เพื่อทำการซิงโครไนซ์ข้อมูลระหว่างผู้เล่นได้
ตัวอย่างโค้ดการซิงโครไนซ์ข้อมูลตำแหน่งของผู้เล่น
using UnityEngine;
using Unity.Netcode;
public class PlayerPositionSync : NetworkBehaviour
{
public NetworkVariable position = new NetworkVariable();
void Update()
{
if (IsOwner)
{
// ส่งตำแหน่งของผู้เล่นไปยังเครือข่าย
position.Value = transform.position;
}
else
{
// รับข้อมูลตำแหน่งจากเครือข่าย
transform.position = position.Value;
}
}
}
คำอธิบายโค้ด
- NetworkVariable<Vector3> ใช้เพื่อเก็บตำแหน่งของผู้เล่นในรูปแบบ 3D และทำการซิงโครไนซ์ตำแหน่งกับผู้เล่นอื่น ๆ
- ตัวแปร position.Value จะถูกอัปเดตและส่งข้อมูลไปยังผู้เล่นคนอื่นเมื่อเจ้าของตัวละครเคลื่อนไหว
การจัดการการแสดงผลผู้เล่นหลายคน (Multiplayer Visualization)
เมื่อผู้เล่นเข้าร่วมเกม ระบบต้องทำการแสดงผลตัวละครของผู้เล่นแต่ละคน เราสามารถใช้ NetworkManager ในการสร้างตัวละครผู้เล่นใหม่ทุกครั้งที่มีการเชื่อมต่อเข้ามา
ตัวอย่างโค้ดการสร้างตัวละครใหม่เมื่อมีผู้เล่นเข้าร่วม
using UnityEngine;
using Unity.Netcode;
public class GameManager : MonoBehaviour
{
public GameObject playerPrefab;
void Start()
{
NetworkManager.Singleton.OnClientConnectedCallback += (clientId) =>
{
if (NetworkManager.Singleton.IsHost && NetworkManager.Singleton.LocalClientId == clientId)
{
SpawnPlayer();
}
};
}
void SpawnPlayer()
{
GameObject player = Instantiate(playerPrefab);
player.GetComponent().SpawnAsPlayerObject(NetworkManager.Singleton.LocalClientId); // สร้างตัวละครสำหรับผู้เล่นใหม่
}
}
คำอธิบายโค้ด
- เมื่อมีผู้เล่นเชื่อมต่อเข้ามาใหม่ ระบบจะสร้างตัวละครใหม่ให้กับผู้เล่นนั้นโดยใช้ SpawnAsPlayerObject()
- ตัวละครใหม่จะถูกสร้างจาก Prefab ที่กำหนดไว้
การทดสอบระบบผู้เล่นหลายคน
การทดสอบระบบผู้เล่นหลายคนสามารถทำได้โดยการรันเกมในโหมดผู้เล่นหลายคนแบบท้องถิ่น (Local Multiplayer) หรือใช้หลายเครื่องในการเชื่อมต่อเกมเดียวกัน โดยสามารถทำได้ดังนี้:
- เปิดหลายหน้าต่างของ Unity Editor และรันเกมในแต่ละหน้าต่างในโหมด Host หรือ Client เพื่อจำลองผู้เล่นหลายคน
- หรือทดสอบผ่านเครือข่ายท้องถิ่น (LAN) เพื่อให้หลายเครื่องสามารถเชื่อมต่อกันและเล่นในเกมเดียวกันได้
บทที่ 9 นี้ช่วยให้นักเรียนได้เรียนรู้วิธีการสร้างระบบผู้เล่นหลายคนในเกม Unity ตั้งแต่การตั้งค่าเซิร์ฟเวอร์และ Client, การควบคุมผู้เล่นหลายคน, การซิงโครไนซ์ข้อมูลระหว่างผู้เล่น, ไปจนถึงการจัดการการแสดงผลตัวละครสำหรับผู้เล่นแต่ละคน การเรียนรู้การพัฒนาระบบผู้เล่นหลายคนจะเปิดโอกาสให้เกมของนักเรียนมีความท้าทายและน่าสนใจยิ่งขึ้น