วันจันทร์ที่ 9 พฤศจิกายน พ.ศ. 2558

Unity Engine & Tools

Game Engine & Tools

- Unity
- Visual Studio หรือ MonoDevelop
Visual Studio
MonoDevelop
- SVN

Unity Game Engine

ทำไมต้อง Unity

- Free Download

- สามารถ Publish เกมหรือ Application ที่สร้างขึ้นจาก Unity Free Version ได้ ในกรณีที่รายได้ต่อปีไม่ถึง US$100,000

- Multiplatform
- มีการใช้งานอย่างกว้างขวาง
ที่มา : https://www.facebook.com/GlobalGameJam/

ตัวอย่างเกมที่ใช้ Unity

สลาฟในแดนมหัศจรรย์
Blogic
หมากฮอสขั้นเทพ
เมื่อวันที่ 6 พฤจิกายน 2558 เกมหมากฮอสขั้นเทพได้ขึ้นเป็นอันดับ 1 เกมปริศนายอดนิยม

Unity Plugin

Facebook SDK

- Login
- App Invites
- Share
- App Links

iTween


Unity Objects and Component

ที่มา :  http://www.rivellomultimediaconsulting.com/wp-content/uploads/2013/05/unity14_diagram-500x243.png

วันอังคารที่ 3 พฤศจิกายน พ.ศ. 2558

[Unity 2D] สร้างเกมง่ายๆ Tappy Plane ตอนที่ 16 : ใส่เสียงให้เกม [จบ]

เตรียมไฟล์เสียง

ผู้เรียนสามารถหาไฟล์เสียงตามที่ต้องการได้ตามเว็บฟรีต่างๆ เช่น

ในตัวอย่างโปรเจ็คนี้จะผู้เขียนจะดาวน์โหลดเสียงทั้งหมดมาจากเว็บไซต์ http://www.freesfx.co.uk/ โดยจะต้องทำการสมัครสมาชิก และล็อกอินก่อนจากนั้นจึงจะสามารถดาวน์โหลดได้

โดยในเกมจะมีเสียงหลักๆ ดังนี้
เสียงดนตรี ดาวน์โหลดที่นี่
เสียงบินขึ้น ดาวน์โหลดที่นี่
เสียงคลิกปุ่ม ดาวน์โหลดที่นี่

หลังจากนั้นให้สร้างโฟลเดอร์ชื่อ Sounds เพื่อใช้สำหรับจัดระเบียบไฟล์เสียง และนำไฟล์เสียงที่ดาวน์โหลดมาทั้งหมดจัดเก็บไว้ในโฟลเดอร์นี้

ใส่เสียงดนตรี

สร้างเกมออบเจ็คใหม่ขึ้นมา โดยคลิกขวาเลือก Create Empty ในที่นี้ตั้งชื่อว่า SoundManager
จากนั้นทำการเพิ่ม Component Audio Source ให้กับเกมออบเจ็คที่เราเพิ่งจะสร้างขึ้น โดยการคลิกที่ Add Component -> Audio -> Audio Source
ใส่เสียงดนตรีให้กับ Audio Source โดยใช้เสียง psyche_up หรือจะเป็นเสียงดนตรีที่ผู้อ่านหามาเองก็ได้
จากนั้นลองทดสอบโดยการรันเกมจะเห็นว่าเกมมีเสียงดนตรีเรียบร้อยแล้ว

จัดการเสียงเอฟเฟค

สร้าง C# Script ขึ้นมาใหม่ ในที่นี้จะตั้งชื่อว่า SoundManager จากนั้นให้เพิ่ม Script SoundManager ให้กับเกมออบเจ็ค SoundManager ดังภาพ
กลับมาที่ Script SoundManager ให้สร้าง Array ของ AudioClip ขึ้นมาเพื่อใช้อ้างอิงกับเสียงเอฟเฟคทั้งหมดที่ใช้ภายในเกม ดังนี้

public class SoundManager : MonoBehaviour
{
  public AudioClip[] _Sounds;
}

จากนั้นให้กลับไปที่ Scene Game ที่ Script SoundManager จะเห็นว่ามีค่า Sounds เกิดขึ้น ดังภาพ
ให้ใส่ตัวเลข 3 เข้าไป เนื่องจากเสียงเอฟเฟคเรามีทั้งหมด 3 เสียง ได้แก่ เสียงชน บินขึ้น และคลิกปุ่ม

จากนั้นจะเห็นว่ามี Element Audio Clip ขึ้นมา 3 ตัว ให้เราเพิ่มไฟล์เสียงเอฟเฟคเข้าไป ดังนี้
กลับไปที่ Script SoundManager ให้เพิ่มฟังก์ชั่น PlayAudioClip สำหรับการเล่นเสียงเอฟเฟค ดังนี้

private void PlayAudioClip(int index)
{
     GameObject go = new GameObject("AudioClip"); //สร้างเกมออบเจ็คใหม่ โดยตั้งชื่อว่า AudioClip
     MonoBehaviour.DontDestroyOnLoad(go); //เมื่อมีการโหลดซีนใหม่เกมออบเจ็คจะไม่ถูกทำลาย
     AudioSource source = go.AddComponent<AudioSource>(); //เพิ่ม Component AudioSource ให้กับเกมออบเจ็ค
     source.clip = _Sounds[index]; //เพิ่ม Clip เสียงโดยอ้างอิงจาก index
     source.Play(); //สั่งเล่นไฟล์เสียง
     MonoBehaviour.Destroy(go, _Sounds[index].length); //ทำลายเกมออบเจ็คเมื่อเล่นไฟล์เสียงจบ
}

จากนั้นสร้างฟังก์ชั่นสำหรับการเล่นเสียงเอฟเฟคประเภทต่างๆโดยอ้างอิงจาก index ดังนี้

public void PlaySoundCrash()
{
        PlayAudioClip(0);
}

public void PlaySoundUp()
{
        PlayAudioClip(1);
}

public void PlaySoundClick()
{
        PlayAudioClip(2);
}

ใส่เสียงชน

กลับไปที่ PlaneMovement Script เพิ่ม code ดังนี้

public GameObject _SoundManager;

เพื่อใช้สำหรับอ้างอิงกับออบเจ็ค SoundManager

จากนั้นที่ Scene Game เลือกที่เกมออบเจ็ค Plane ที่ Component Plane Movement ให้ใส่เกมออบเจ็ค SoundManager ลงไป
กลับไปที่ PlaneMovement Script อีกครั้ง ที่ฟังก์ชั่น OnCollisionEnter2D เพิ่ม code เพิ่มเติมดังนี้
if (!_IsDead) _SoundManager.GetComponent<SoundManager>().PlaySoundCrash();

public void OnCollisionEnter2D(Collision2D collision)
{
    if (!_IsDead) _SoundManager.GetComponent<SoundManager>().PlaySoundCrash();
 
    _IsDead = true;
    GetComponent<Animator>().SetBool("IsDead", true);

    _CanvasGameOver.gameObject.SetActive(true);
}

รันและทดสอบเสียงชน

ใส่เสียงบินขึ้น

ที่ PlaneMovement Script ฟังก์ชั่น Update
ให้ใส่โค้ด _SoundManager.GetComponent<SoundManager>().PlaySoundUp(); เมื่อผู้เล่นคลิกหรือแตะหน้าจอ

private void Update()
{
    if (_IsDead) return;

    if (_IsStart)
    {
      Vector3 pos = new Vector3(_Speed, 0, 0);
      transform.position += pos;
    }
 
    if (Input.GetMouseButtonDown(0))
    {
      _SoundManager.GetComponent<SoundManager>().PlaySoundUp(); //เล่นเสียงเมื่อบินขึ้น

      if (!_IsStart)
      {
        _CanvasGameStart.gameObject.SetActive(false);
        GetComponent<Rigidbody2D>().isKinematic = false;
        _IsStart = true;
      }
      else
      {
        GetComponent<Rigidbody2D>().AddForce(Vector2.up * _TabSpeed);
      }
    }
}

รันและทดสอบเกม

ใส่เสียงคลิกปุ่ม

ไปที่ UI Script เพิ่มโค้ด ดังนี้
public GameObject _SoundManager;
เพื่อใช้อ้างอิงกับเกมออบเจ็ค SoundManager

ที่ Scene Game คลิกที่เกมออบเจ็ค CanvasGameOver ที่ Script UI Component ให้เพิ่มเกมออบเจ็ค SoundManager เข้าไป
จากนั้นที่ฟังก์ชั่น Retry ให้เพิ่มโค้ดการเล่นเสียงคลิกปุ่ม ดังนี้

public void Retry()
{
    _SoundManager.GetComponent<SoundManager>().PlaySoundClick();
    Application.LoadLevel("Game");
}

รันและทดสอบเกม

เพียงเท่านี้เราก็ได้เกม Tappy Plane ที่เสร็จสมบูรณ์แล้ว ขอให้สนุกกับการทำเกมนะคะ

วันอังคารที่ 27 ตุลาคม พ.ศ. 2558

[Unity 2D] สร้างเกมง่ายๆ Tappy Plane ตอนที่ 15 : นับคะแนน

UI แสดงคะแนน

สร้างเกมออบเจ็ค Canvas ขึ้นมาใหม่ ในที่นี้จะตั้งชื่อว่า CanvasScore เพื่อใช้แสดง UI สำหรับนับคะแนนเมื่อเครื่องบินได้ทำการบินผ่านสิ่งกีดขวางได้สำเร็จ

จากนั้นให้ปรับค่า Reference Resolution X เท่ากับ 1280 และ Y เท่ากับ 720
สร้างเกมออบเจ็ค Text ขึ้นมาให้เป็น Child ของ CanvasScore ในที่นี้จะตั้งชื่อว่า TxtScore
ที่หน้าต่าง Inspector เปลี่ยน Font เป็น kenvector_future จากนั้นตั้งค่าให้ Alignment เป็นกึ่งกลาง ติ๊กถูกที่ Best Fit และตั้งค่าให้ Min Size เท่ากับ 10 และ Max Size เท่ากับ 100 ที่ Color เปลี่ยนสีตัวอักษรให้เป็นสีขาว
ที่ตำแหน่ง Y เปลี่ยนค่าเป็น 179 และกำหนด Width เป็น 200 และ Height เป็น 300
ต่อไปเราจะมาเพิ่มมิติให้กับตัวอักษรด้วยการใส่เงา ดังนี้ Add Component -> UI ->Effects -> Shadow
โดยที่เราจะใส่ Shadow 2 ชั้นเพื่อความมีมิติมากขึ้น สีแรกจะเป็นโทนสีเหลืองโทนเดียวกับภาพ Get Ready บน UI Game Start
ใส่เงานอีกสีหนึ่งเป็นสีเทา
ในหน้าต่าง Inspector มี Component Shadow 2 ตัวดังภาพ
จะได้ผลลัพธ์ดังนี้
จากนั้นลบข้อความใน Text ออก เนื่องจากในส่วนแสดงผลคะแนนเราจะทำที่โค้ดในภายหลังกัน

การนับคะแนน

ไปที่เกมออบเจ็ค Rock1 สร้างเกมออบเจ็คขึ้นมาใหม่ให้เป็นลูกของ Rock1 โดยการคลิกขวาที่เกมออบเจ็ค Rock1 จากนั้นเลือก Create Empty ในที่นี้จะตั้งชื่อเกมออบเจ็คนี้ว่า Score
จากนั้นทำการเพิ่ม Component BoxCollider2D ให้กับเกมออบเจ็ค Score

ติ๊กถูกที่ IsTrigger เนื่องจากเมื่อเครื่องบินมีการบินผ่านเกมออบเจ็คเช็คคะแนนอันนี้แสดงว่าบินผ่านสิ่งกีดขวางสำเร็จ เราจะทำการบวกคะแนนให้และแสดง UI คะแนนในภายหลัง
ที่ขนาดของ BoxCollider2D ให้ X เป็น 1 และ Y เป็น 5 จากนั้นปรับตำแหน่ง X ให้เท่ากับ 1 จะได้ผลลัพธ์ ดังภาพ
สร้าง Layer ใหม่ชื่อว่า Score

สร้าง Tag ใหม่ชื่อว่า Score
ที่เกมออบเจ็ค Rock1 ไปที่เกมออบเจ็คลูกที่ชื่อ Score เลือก Tag และ Layer ให้เป็น Score ที่ได้ทำการสร้างไว้เมื่อสักครู่
คลิก Apply ที่ Prefab จากนั้นตรวจสอบดูที่เกมออบเจ็ค Rock ทุกๆตัวว่ามีเกมออบเจ็ค Score เรียบร้อยดีหรือไม่

ไปที่ Edit -> Project Settings -> Physics 2D
จากนั้นให้ทำการตั้งค่าการ Collision ของ Layer Score ให้เกิดขึ้นกับ Layer Plane เท่านั้น ดังภาพ
สร้าง C# Script ในที่นี้ให้ใช้ชื่อว่า Score

สร้างตัวแปรสำหรับนับคะแนน
private int _Score = 0;

จากนั้นสร้างฟังก์ชั่น OnTriggerEnter2D ขึ้นมา เมื่อเครื่องบินมีการบินผ่านเกมออบเจ็คที่ใช้สำหรับเช็คคะแนนจะทำการเพิ่มคะแนนให้กับตัวแปร _Score 1 คะแนน

public void OnTriggerEnter2D(Collider2D collider)
  {
    if (collider.gameObject.tag == "Score")
    {
      _Score++;
    }
  }

เพิ่ม Code ดังต่อไปนี้ที่ด้านบนสุด เนื่องจากเราจะทำการเรียกใช้คลาส Text ของ UnityEngine.UI
using UnityEngine.UI;

จากนั้นสร้างตัวแปร publish Text ขึ้นมา เพื่อใช้แสดงคะแนน
public Text _TxtScore;

กลับไปที่ Scene Game ที่เกมออบเจ็ค Plane ให้ทำการเพิ่ม Component Score Script ที่เราทำการสร้างเมื่อสักครู่นี้เข้าไป
ที่ Txt Score ให้ใส่เกมออบเจ็ค TxtScore ของ CanvasScore
จากนั้นให้กลับไปที่ Script Score ทำการเซ็ท _TxtScore ให้แสดง Text เท่ากับจำนวนคะแนนในปัจจุบัน ดังนี้
_TxtScore.text = _Score.ToString();

จะได้ Code ทั้งหมด ดังนี้
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class Score : MonoBehaviour
{
  private int _Score = 0;

  public Text _TxtScore;

  public void OnTriggerEnter2D(Collider2D collider)
  {
    if (collider.gameObject.tag == "Score")
    {
      _Score++;
      _TxtScore.text = _Score.ToString(); //แปลง int เป็น string
    }
  }
}

ลองทดสอบโดยการรันเกมจะเห็นว่าเมื่อบินผ่านสิ่งกีดขวางจะมีคะแนนแสดงขึ้นมาเรียบร้อย
แต่เมื่อขึ้น UI Game Over คะแนนยังไม่แสดงผล ดังนั้นต่อไปเราจะมาทำให้ UI Game Over แสดงผลคะแนนให้ถูกต้อง
ใน Script Score ให้เพิ่มตัวแปร public Text _TxtScoreGameOver; เพื่อใช้อ้างอิงถึงเกมออบเจ็ค Text ที่จะใช้แสดงผลคะแนนใน UI Game Over

จากนั้นให้เพิ่ม _TxtScoreGameOver.text = "Score : " + _Score; ในฟังก์ชั่น OnTriggerEnter2D ดังนี้

public void OnTriggerEnter2D(Collider2D collider)
  {
    if (collider.gameObject.tag == "Score")
    {
      _Score++;
      _TxtScore.text = _Score.ToString();
      _TxtScoreGameOver.text = "Score : " + _Score;
    }
  }

กลับไปที่ Scene Game คลิกที่เกมออบเจ็ค Plane ไปที่ Component Score จากนั้นที่ Txt Score Game Over ให้เพิ่มเกมออบเจ็ค TxtScore ที่อยู่ใน CanvasGameOver เข้าไป
รันและทดสอบจะเห็นว่า UI Game Over แสดงผลคะแนนเรียบร้อยแล้ว

บันทึก Best Score ด้วย PlayerPrefs

PlayerPrefs ใช้สำหรับบันทึกค่าต่างๆของเกม โดยจะสามารบันทึกได้ในรูปแบบของ float int และ string

ไปที่ C# Script ที่ชื่อว่า Score จากนั้นให้เพิ่ม

public Text _TxtBestScoreGameOver;

เพื่อใช้สำหรับอ้างอิง text ใน Canvas Game Over ที่จะใช้แสดงผลคะแนนสูงสุดที่เคยทำได้

จากนั้นให้เพิ่มฟังก์ชั่น OnCollisionEnter2D ขึ้นมาเพื่อใช้สำหรับเช็คค่าการชน คือเมื่อเครื่องบินมีการชนจะมีการเช็คว่าคะแนนปัจจุบันที่ทำได้มากกว่าคะแนนสูงสุดที่เคยบันทึกไว้หรือไม่ ถ้าคะแนนของรอบนี้สูงกว่าก็ให้ทำการบันทึกคะแนนสูงสุดไว้ด้วย PlayerPrefs จะได้ code ดังนี้

public void OnCollisionEnter2D(Collision2D collision)
  {
    //อ่านค่าจาก PlayerPref ที่มีคีย์คือ BestScore
    //ในกรณีที่ยังไม่มีการบันทึกโดยใช้คีย์นี้เกิดขึ้น จะกำหนดให้ค่า default ที่อ่านได้เป็น 0

    int bestScore = PlayerPrefs.GetInt("BestScore", 0);
    if (_Score > bestScore)
    {
      PlayerPrefs.SetInt("BestScore", _Score); //บันทึกค่าเป็น int และใช้คีย์ชื่อว่า BestScore
    }

   //แสดงผลคะแนนที่ดีที่สุด
    _TxtBestScoreGameOver.text = "Best Score : " + PlayerPrefs.GetInt("BestScore", 0);
  }

จากนั้นกลับไปที่ Scene Game เลือกที่เกมออบเจ็ค Plane ที่ Component Score ให้เพิ่ม TxtBestScore ใน CanvasGameOver เข้าไป ดังภาพ
รันและทดสอบเกมจะเห็นว่าเกมได้ทำการบันทึกและแสดงผล Best Score เรียบร้อยแล้ว

วันอาทิตย์ที่ 27 กันยายน พ.ศ. 2558

[Unity 2D] สร้างเกมง่ายๆ Tappy Plane ตอนที่ 14 : ซ่อน/แสดง UI และเริ่มเกมใหม่ด้วย LoadLevel

ซ่อน CanvasGameOver

คลิกที่แคนวาส จากนั้นไปที่หน้าต่าง Inspector ที่มุมบนซ้ายให้ติ๊กเครื่องหมายถูกออก

แสดง CanvasGameOver เมื่อเครื่องบินตาย

ไปที่ Script PlaneMovement ให้เพิ่มตัวแปรแคนวาสดังนี้ public Canvas _CanvasGameOver;
เพื่อทำการอ้างถึงตัว CanvasGameOver จากนั้นลากออบเจ็ค CanvasGameOver มาใส่ดังภาพ
เมื่อเครื่องบินมีการชนเกิดขึ้นจะเซ็ทให้ CanvasGameOver แสดงขึ้นมาได้ดังโค้ด

public void OnCollisionEnter2D(Collision2D collision)
  {
    _IsDead = true;
    GetComponent<Animator>().SetBool("IsDead", true);

    _CanvasGameOver.gameObject.SetActive(true);
  }

หลังจากรันและทดสอบเกมจะเห็นว่าเมื่อเครื่องบินชนจะมี UI Game Over แสดงผลขึ้นมาโดยเล่นแอนิเมชั่นที่เราได้ทำการสร้างไว้ก่อนหน้านี้ด้วย

เริ่มเกมใหม่ด้วย LoadLevel

สร้าง C# Script ขึ้นมาใหม่ ในที่นี้ตั้งชื่อว่า UI จากนั้นสร้างฟังก์ชั่น Retry สำหรับทำหน้าที่ในการเริ่มเกมใหม่ ดังนี้

public class UI : MonoBehaviour
{
  public void Retry()
  {
    Application.LoadLevel("Game");
  }
}

คำสั่ง Application.LoadLevel("Game"); จะทำหน้าที่ในการโหลดซีนที่มีชื่อว่า "Game" ขึ้นมาใหม่ ให้ใส่ชื่อซีนที่ต้องการเข้าไป

กรณีผู้อ่านใช้ Unity 5.3 ขึ้นไปให้ใช้ SceneManager.LoadScene("Game") แทน

จากนั้นที่เกมออบเจ็ค CanvasGameOver ให้เพิ่ม Component UI Script เข้าไป
กลับไปที่เกมออบเจ็ค BtnRetry ที่หน้าต่าง Inspector ไปที่ Component Button จะเห็นว่ามีอีเว้นท์ On Click อยู่ ให้ลากเกมออบเจ็ค CanvasGameOver ไปใส่ เนื่องจากเราต้องการจะเรียกใช้ฟังก์ชั่น Retry ใน UI Script

เมื่อใส่เกมออบเจ็ค CanvasGameOver เรียบร้อยแล้ว ให้คลิกที่ No Function จะเห็นว่ามีป๊อปอัพขึ้นมา ให้เลือก UI จากนั้นเลือกฟังก์ชั่น Retry()
จะได้ผลลัพธ์ดังนี้
ทดสอบโดยการรันเกมเมื่อเครื่องบินชนจะมีป๊อปอัพ GameOver เปิดขึ้น จากนั้นเมื่อกดปุ่ม Retry จะเห็นว่าเกมได้ทำการเริ่มใหม่เรียบร้อย

UI Game Start


สร้างเกมออบเจ็ค Canvas ขึ้นมาใหม่ ในที่นี้จะตั้งชื่อให้เป็น CanvasStart จากนั้นตั้ง Reference Resolution X เป็น 1280 และ Y เป็น 720
สร้างเกมออบเจ็คในที่นี้ตั้งชื่อว่า GetReady โดยขวาที่ CanvasStart จากนั้นไปที่ UI -> Image
จากนั้น ที่ Source Image ให้นำภาพ textGetReady มาใส่ ที่ตำแหน่ง Pos Y ในที่นี้ให้เป็น 54
สร้าง UI -> Image ขึ้นมาอีก ในที่นี้ตั้งชื่อว่า TapLeft จากนั้นนำภาพ tapLeft มาใส่ กำหนดตำแหน่ง X เป็น -160 และตำแหน่ง Y เป็น -30
ทำแบบเดียวกันเพื่อสร้างเกมออบเจ็ค TapRight แต่ให้ตั้งค่าให้ตำแหน่ง X เป็น 160 แทน
สร้างเกมออบเจ็ค UI -> Image ในที่นี้ตั้งชื่อว่า Hand นำภาพ tap ใส่ใน Source Image ตั้งค่าตำแหน่งใหเ X เท่ากับ 200 และ Y เท่ากับ 120 จากนั้นเพิ่ม Component Animator
เนื่องจากเราจะให้ผู้เล่นรู้ว่าเมื่อคลิกจะเป็นการเริ่มเกม เราจะทำแอนิเมชั่นคลิกให้กับเกมออบเจ็ครูปมือนี้ เริ่มจากคลิกที่เกมออบเจ็ค Hand จากนั้นไปที่หน้าต่างการทำงานของ Animation คลิก Create เพื่อสร้างคลิปแอนิเมชั่น ในที่นี้ตั้งชื่อว่า Hand
ปรับ Samples ให้เท่ากับ 12 ที่เฟรม 0 ให้ลากภาพ tap เข้ามา
จากนั้นไปที่เฟรม 1 ให้ลากภาพ tapTick เข้ามา
ให้ทดสอบโดยการกดรันแอนิเมชั่นดูจะเห็นว่าที่รูปมือมีแอนิเมชั่นคลิกเรียบร้อย

คลิกเพื่อเริ่มเกม

เมื่อลองรันเกมดูจะเห็นว่าเกมจะเริ่มเล่นทันที ส่วน UI Game Start จะขึ้นมาตั้งแต่เริ่มรันซีน และยังอยู่ในขณะที่เล่นเกมจนกระทั่งจบเกม

ดังนั้นในส่วนนี้เราจะมาเขียนโค้ดให้แสดง UI Start Game และตัวเครื่องบินจะต้องยังไม่เริ่มบินทันทีในตอนเริ่มต้น แต่เมื่อผู้เล่นทำการคลิกเราจะทำการซ่อน UI Start Game และสั่งให้เครื่องบินบิน

เปิด Script PlaneMovement ขึ้นมา
สร้างตัวแปรสำหรับเช็คว่าเกมเริ่มหรือยัง โดยใช้ค่าเริ่มต้นเป็น false

private bool _IsStart = false;

สร้างฟังก์ชั่น Start() ขึ้นมาใช้สำหรับกำหนดค่าเริ่มต้นให้ค่า isKinematic เป็น true ซึ่งหมายความว่า Collision และ Rigidbody จะไม่ส่งผล ทำให้เครื่องบินไม่บินตกลงไปตามแรงโน้มถ่วง

private void Start()
  {
    GetComponent<Rigidbody2D>().isKinematic = true;
  }

ในฟังก์ชั่น Update() เพิ่มการเช็ค _IsStart ถ้าเกมเริ่มแล้วถึงจะให้เครื่องบินบินไปทางขวา

 private void Update()
  {
    if (_IsDead) return;

    if (_IsStart)
    {
      Vector3 pos = new Vector3(_Speed, 0, 0);
      transform.position += pos;
    }
 
    if (Input.GetMouseButtonDown(0))
    {
      GetComponent<Rigidbody2D>().AddForce(new Vector2(0, 1) * _TabSpeed);
    }
  }

ทดลองรันเกมจะเห็นได้ว่า เมื่อเริ่มเกมเครื่องบินจะหยุดอยู่กับที่ และแสดง UI Game Start เรียบร้อย

จากนั้นเราจะมาทำให้เมื่อเกิดการคลิกเกิดขึ้นให้ซ่อน UI Game Start และให้เครื่องบินตามปกติ ดังนี้
สร้างตัวแปร public Canvas เพื่อใช้อ้างอิงถึง UI Game Start

public Canvas _CanvasGameStart;

เลือกที่เกมออบเจ็ค Plane ที่ PlaneMovement Script จะเห็นว่ามี Canvas Game Start ขึ้นมา ให้ลากเกมออบเจ็ค CanvasGameStart ที่เราทำการสร้างเอาไว้ก่อนหน้านี้มาใส่
จากนั้นที่ฟังก์ชั่น Start() ให้เพิ่มโค้ดเพื่อแสดง UI Game Start เข้าไป
_CanvasGameStart.gameObject.SetActive(true);

จะได้ดังนี้

  private void Start()
  {
    GetComponent<Rigidbody2D>().isKinematic = true;
    _CanvasGameStart.gameObject.SetActive(true);
  }

ในฟังก์ชั่น Update() ตรงส่วนการเช็คอีเว้นท์คลิกให้ทำการแก้ไขดังนี้

if (Input.GetMouseButtonDown(0))
{
      if (!_IsStart)
      {
        _CanvasGameStart.gameObject.SetActive(false);
        GetComponent<Rigidbody2D>().isKinematic = false;
        _IsStart = true;
      }
      else
      {
        GetComponent<Rigidbody2D>().AddForce(Vector2.up * _TabSpeed);
      }
}

หมายความว่าถ้าเกมยังไม่เริ่มและมีการคลิกเกิดขึ้น โปรแกรมจะวิ่งเข้าไปทำโค้ดดังต่อไปนี้

 _CanvasGameStart.gameObject.SetActive(false); //ซ่อน UI Game Start
 GetComponent<Rigidbody2D>().isKinematic = false; //กำหนดให้ Collision และ Rigidbody มีผลต่อเกมออบเจ็คนี้
 _IsStart = true; //ให้ตัวแปรเช็คเป็น true แสดงว่าเกมเริ่มแล้ว

หลังจากเกมเริ่มแล้วและผู้เล่นได้ทำการคลิกจะทำให้โปรแกรมลงมาทำงานที่บรรทัดดังต่อไปนี้
GetComponent<Rigidbody2D>().AddForce(Vector2.up * _TabSpeed); //ให้เครื่องบินบินขึ้นเมื่อมีการคลิก

ลองทดสอบโดยการรันและเล่นเกมจะเห็นว่าเราได้ UI เกมครบ Flow แล้ว คือ
- แสดง UI Game Start
- คลิกเพื่อเริ่มเกม -> ซ่อน UI Game Start -> เกมเริ่มเล่น
- เมื่อตาย แสดง UI Game Over
- คลิก Retry -> ซ่อน UI Game Over -> โหลดเกมใหม่