บทเรียน Workshop การเขียนเกมแนว Temple Run ตอนที่ 5 ด้วย Unity 3D กับการเพิ่มเติมส่วนของ Pause Game และ ตกแต่ง GUI ภายในเกมให้สมบูรณ์
บทเรียนก่อนหน้านี้ให้ศึกษาอย่างถี่ถ้วนก่อนจะจบบทเรียนนี้
- Workshop เขียนเกมแนว Temple Run ด้วย Unity 3D ตอนที่ 1
- Workshop เขียนเกมแนว Temple Run ด้วย Unity 3D ตอนที่ 2
- Workshop เขียนเกมแนว Temple Run ด้วย Unity 3D ตอนที่ 3
- Workshop เขียนเกมแนว Temple Run ด้วย Unity 3D ตอนที่ 4
หลังจากที่เกมของเรามีการใส่ Game Logic เข้าไปแล้วต่อมาเราจะเรียนรู้เรื่องของ Pause หรือหยุดเกมของเราก่อน เงื่อนไขคือกด ESC แล้วเกมจะหยุดและพบกับเมนูของเกมว่า หยุดเกมหรือ Pause State และมีเมนู Resume กลับเข้าไปเล่นเกมต่อ
การสร้าง GUI Font สำหรับ Graphics Interface ของเกม ผมไปดาวน์โหลด Font สวยๆ ฟรีๆ จากเว็บไซต์มาหนึ่งเว็บไซต์
ดาวน์โหลดแล้วไปวางไว้ที่ Asset สร้าง folder มาเก็บไฟล์ไว้ชื่อว่า Fonts และ GUI
เพิ่ม GUI เข้ามาในเกม
วิธีเพิ่ม GUI ของเกมเข้าไปนั้นสามารถทำได้ง่ายๆ ครับโดยการคลิกสร้าง GUI ขึ้นมาเลยเลือกที่ Project แล้ว Create-> GUI Skin
เราจะได้ Skin ของเรา 1 ไฟล์ให้เปลี่ยนชื่อเป็น NormalSkin ครับ
คลิกที่ NormalSkin แล้วสังเกตที่ Inspector จะพบกับการตั้งค่าเบื้องต้นจอง GUI ของเรา
เราจะเน้นไปที่ Box ก่อน เป็นการสร้างหน้าต่าง Box ของ GUI ของเรา
ให้ลากไฟล์ Font ของเราไปวางที่ Font และออกแบบหน้าต่างข้อความของเรา เป็นไฟล์ PNG ผมได้ออกแบบไว้คือ
นำ boxback.png ไปวางใน Box>Normal>Background ครับ ปรับ Size ขนาด และสีตามในชอบ เช่นกันตั้งค่า Label ต่างๆ ในเกมของเรา พวกตัวอักษรต่างๆ ให้พอดีครับ
เมื่อเราใส่ Skin แล้วเราต้องไปแก้ไข GameLogic.cs ใหม่เล็กน้อย เพื่อปรับระยะของ ปุ่มต่างๆ ครับ ให้เปิดไฟล์ GameLogic.cs ขึ้นมา เพิ่มคำสั่งนี้ลงไป ส่วนของตัวแปร Public
public GUISkin NormalSkin;
ตำแหน่ง
using UnityEngine; using System.Collections; public class GameLogic : MonoBehaviour { public GUISkin NormalSkin;
ตามด้วยเพิ่มในฟังก์ชัน OnGUI()
void OnGUI() { GUI.skin=NormalSkin; //เพิ่มเข้ามา if(!isGameOver) {
ปรับระยะของ ปุ่ม และตัวอักษรใหม่ดังนี้
void OnGUI() { GUI.skin=NormalSkin; if(!isGameOver) { GUI.Label(new Rect(10, 10, Screen.width/5, Screen.height/6), "TIME LEFT: "+((int)timeRemaining).ToString()); GUI.Label(new Rect(Screen.width-(Screen.width/6), 10, Screen.width/6, Screen.height/6), "SCORE: "+((int)score).ToString()); } else { Time.timeScale = 0; //Show Total Score GUI.Box(new Rect(Screen.width/4, Screen.height/4+10, Screen.width/2, Screen.height/2), "\nGAME OVER\nTOTAL SCORE: "+(int)score); //Restart Game if (GUI.Button(new Rect(Screen.width/4+10, Screen.height/4+Screen.height/10+50, Screen.width/2-20, Screen.height/10), "RESTART")){ Application.LoadLevel(Application.loadedLevel); } }
***หมายเหตุแก้ไขเองนะครับ ดูส่วน ของตำแหน่งดีๆ (ขี้เกียจชี้นำว่าส่วนไหน เจอ Bug ก็แก้ Bug เอานะครับ)
ลาก NormalSkin ไปใส่ในช่อง Game Skin ใน Inspector ของ GameController
ลองเล่นเกมดูอีกครั้ง สังเกตการเปลี่ยนแปลง
การทำ Pause เกม หรือหยุดเกมชั่วคราวพร้อมเมนู
ให้เราสร้าง C# Script ขึ้นมาครับ ตั้งชื่อว่า Pause.cs นำไปลากวางใส่ที่ GameObject ของเราที่ชื่อว่า GameController ตัวเดิมของเราครับ
ทำการ Add component ตามนี้
เปิด Mono Develop ขึ้นมาเขียนคำสั่งดังนี้ ประกาศตัวแปรเป็น Public ไว้
public GUISkin gameSkin; public string levelToLoad; public bool gamePause = false;
เป็นตัวแปรเพื่อบอกว่า levelToLoad นั้นเป็นสถานะของเกมแบบไหน ถ้าจะเริ่มเล่นใหม่ใช้ levelToLoad เรียกตัวแปรขึ้นมาเลยครับ ต่อจากนั้นเขียนคำสั่งรับค่าจากปุ่ม ESC ก่อน เขียนเพิ่มในฟังก์ชัน Update();
if (Input.GetKey(KeyCode.Escape) ) { if (gamePause) gamePause = false; else gamePause = true; } if(gamePause) Time.timeScale = 0; else Time.timeScale = 1;
เพื่อบอกว่า ถ้าเงื่อนไขของเกมนั้นเป็น paused อยู่แล้ว ค่าการหยุดเกมเป็น False แต่ถ้าเกมไม่ได้หยุดให้ค่าการหยุดเกมเป็น True ขึ้นมา อ้างจากตัวแปร Boolean ที่ชื่อ gamePause
เพิ่มคำสั่ง ใน Start(); กำหนด timeScale ของเกม
Time.timeScale=1;
สร้าง GUI ของหน้าต่าง Pause ของเราเล็กน้อยให้มีปุ่ม กลับไปเล่นต่อ และปุ่ม Restart เริ่มเล่นเกมใหม่ ให้สร้างฟังก์ชัน OnGUI() ออกมาเหมือนบทเรียนก่อนๆ
private void OnGUI() { if (gamePause){ GUI.Box(new Rect(Screen.width/4, Screen.height/4, Screen.width/2, Screen.height/2), "PAUSED"); if (GUI.Button(new Rect(Screen.width/4+10, Screen.height/4+Screen.height/10+10, Screen.width/2-20, Screen.height/10), "RESUME")){ gamePause = false; } if (GUI.Button(new Rect(Screen.width/4+10, Screen.height/4+2*Screen.height/10+10, Screen.width/2-20, Screen.height/10), "RESTART")){ Application.LoadLevel(Application.loadedLevel); } if (GUI.Button(new Rect(Screen.width/4+10, Screen.height/4+3*Screen.height/10+10, Screen.width/2-20, Screen.height/10), "MAIN MENU")){ } } }
ทำการบันทึกแล้วกลับไปเล่นเกมของเรา แล้วลองกดปุ่ม Esc ระหว่างเกมครับ
ซึ่งเจ้า Pause Menu เราสามารถใส่ GUI ให้มันได้เหมือนกันโดยการเพิ่ม คำสั่งใน Pause.cs
using UnityEngine; using System.Collections; public class Pause : MonoBehaviour { public GUISkin gameSkin; //ตำแหน่งนี้
และ
private void OnGUI() { GUI.skin=gameSkin; //ตำแหน่งนี้ if (gamePause){
คำสั่ง Pause.cs ทั้งหมดจะเป็นแบบนี้
using UnityEngine; using System.Collections; public class Pause : MonoBehaviour { public GUISkin gameSkin; public string levelToLoad; public bool gamePause = false; // Use this for initialization void Start () { Time.timeScale=1; } // Update is called once per frame void Update () { if (Input.GetKey(KeyCode.Escape) ) { if (gamePause) gamePause = false; else gamePause = true; } if(gamePause) Time.timeScale = 0; else Time.timeScale = 1; } private void OnGUI() { GUI.skin=gameSkin; if (gamePause){ GUI.Box(new Rect(Screen.width/4, Screen.height/4, Screen.width/2, Screen.height/2), "PAUSED"); if (GUI.Button(new Rect(Screen.width/4+10, Screen.height/4+Screen.height/10+10, Screen.width/2-20, Screen.height/10), "RESUME")){ gamePause = false; } if (GUI.Button(new Rect(Screen.width/4+10, Screen.height/4+2*Screen.height/10+10, Screen.width/2-20, Screen.height/10), "RESTART")){ Application.LoadLevel(Application.loadedLevel); } if (GUI.Button(new Rect(Screen.width/4+10, Screen.height/4+3*Screen.height/10+10, Screen.width/2-20, Screen.height/10), "MAIN MENU")){ //Application.LoadLevel(levelToLoad); } } } }
ไปที่ Inspector ของ GameObject ที่ชื่อ GameController อีกครั้งครับ ลากเจ้า Normal Skin ไปใส่ในช่อง Game Skin ได้เลย
ลองเล่นเกมแล้วกด Pause จะพบว่า เกมหยุด และมีหน้าต่าง GUI สวยงามเกิดขึ้น
สิ่งที่ได้จากบทเรียนนี้คือการใส่ GUI ให้กับเกม และการสร้างฟังก์ชัน Pause เกมให้กับเกมของเราให้หยุดอยู่กับที่ครับ
ทบทวนบทเรียนก่อนๆ ได้ที่
- Workshop เขียนเกมแนว Temple Run ด้วย Unity 3D ตอนที่ 1
- Workshop เขียนเกมแนว Temple Run ด้วย Unity 3D ตอนที่ 2
- Workshop เขียนเกมแนว Temple Run ด้วย Unity 3D ตอนที่ 3
- Workshop เขียนเกมแนว Temple Run ด้วย Unity 3D ตอนที่ 4