วันอังคารที่ 1 กันยายน พ.ศ. 2558

[Unity 2D] สร้างเกมง่ายๆ Tappy Plane ตอนที่ 9 : ตัวจัดการการวนลูป

สร้างตัวจัดการวนลูปพื้นหลัง

คลิกที่เกมออบเจ็ค Main Camera คลิกขวาเลือก Empty Game Object จะเห็นได้ว่าเกมออบเจ็คใหม่ที่สร้างอยู่ข้างในของ Main Camera อีกที ซึ่งเราจะเรียกได้ว่าเกมออบเจ็คตัวนี้เป็น Child หรือลูกของ Main Camera นั่นเอง
ให้ตั้งชื่อเกมออบเจ็คนี้ว่าตั้งชื่อว่า BGLooper ซึ่งเกมออบเจ็คตัวนี้จะเป็นตัวจัดการการวนลูปของฉากพื้นหลัง

ทำไมต้องให้ BGLooper เป็นลูกของ Main Camera? คำตอบคือเพราะเราอยากให้ BGLooper เคลื่อนที่ติดตาม Main Camera ไปตลอดโดยไม่ต้องเขียนโค้ดนั่นเอง

แล้วทำไมในตอนก่อนหน้านี้เรื่อง Camera ติดตามเครื่องบิน เราถึงไม่ให้ Camera เป็นลูกของเกมออบเจ็ค Plane ละ? นั่นก็เพราะว่าเมื่อเครื่องบินมีการชนจะมีการหมุนเกิดขึ้นตามกฏฟิสิกส์ เราไม่ต้องการให้กล้องแสดงผลหมุนไปด้วย

กลับมาที่ BGLooper ทำการเพิ่ม BoxCollider2D ให้กับเกมออบเจ็คเนื่องจากเราจะเช็คการชนของเกมออบเจ็ค ที่ Size X กำหนดขนาดให้เท่ากับ 2 และ Size Y เท่ากับ 12 ขนาดสามารถปรับเปลี่ยนได้ตามความเหมาะสม เป้าหมายคือเราต้องการจะนำเกมออบเจ็คนี้มาตรวจสอบการชนเท่านั้น คือถ้าเกมออบเจ็ค BGLooper ทำการชนกับฉากพื้นหลังเราจะมาเขียนโค้ดเปลี่ยนตำแหน่งให้ฉากหลังทางด้านซ้ายไปต่อทางด้านขวา
กำหนดตำแหน่ง X ของ BGLooper ให้เท่ากับ -40 ตำแหน่งตรงนี้สามารถเปลี่ยนได้ตามความเหมาะสมเช่นกัน จะต้องให้ฉากหลังทางด้านซ้ายสุดวิ่งออกจากกล้องแล้วถึงจะมาชนกับ BGLooper เพื่อให้การแสดงผลฉากหลังต่อเนื่อง

ในหน้าต่าง Scene จะได้ผลลัพธ์ดังนี้
กลับมาที่หน้าต่าง Inspector ที่ Component BoxCollider2D ตรงค่า Is Trigger ให้ติ๊กถูกด้วย

อะไรคือ Is Trigger

โดยปกติถ้าเราไม่ติ๊ก IsTrigger วัตถุ 2 วัตถุที่มี Collider และ Rigidbody กระทบกันจะเกิดการชนและมีผลทางฟิสิกส์เกิดขึ้นซึ่งจะทำให้ไม่สามารถวิ่งทะลุผ่านกันได้ แต่ในที่นี้เราต้องการให้ BGLooper วิ่งผ่านเพื่อเช็คและทำการวนลูปฉากพื้นหลังเฉยๆ การติ๊ก Is Trigger จะทำให้วัตถุที่มี Collider เมื่อมีการชนจะสามารถวิ่งทะลุกันได้
ต่อไปให้เพิ่ม Component Rigidbody2D ให้กับ BGLooper เราไม่ต้องการให้ BGLooper มีผลกระทบทางฟิสิกส์เกิดขึ้น เช่น แรงโน้นถ่วง ดังนั้นให้เซ็ทค่า Gravity Scale เป็น 0
สาเหตุที่ต้องเพิ่ม Rigidbody2D ทั้งๆที่เราไม่ต้องการให้ BGLooper มีฟิสิกส์ เนื่องจากเพราะเราต้องการใช้ฟังก์ชั่นทางฟิสิกส์ของนั่นก็คือ OnTriggerEnter2D เพื่อใช้เช็คการผ่านกันของ BGLooper และฉากหลังนั่นเอง

เริ่มโค้ดการวนลูป

สร้าง Script C#  ในที่นี้ตั้งชื่อว่า Looper หลังจากนั้นให้เปิด Script ที่สร้างขึ้นมา

สร้างตัวแปร  public int _NumberObject; ใช้สำหรับเก็บจำนวนวัตถุที่ต้องเช็ค ในที่นี้คือฉากหลัง
จากนั้นให้สร้างตัวแปร public string _TagName; ใช้เพื่อเช็คชนิดของ Tag

อะไรคือ Tag

สาเหตที่ต้องเช็ค Tag เพราะในเกมเราอาจจะมีเกมออบเจ็คอื่นๆที่ไม่ใช่สิ่งที่เราอยากจะทำการวนลูป ซึ่งจะทำให้เกมทำงานผิดพลาด

การสร้าง Tag ทำได้โดยไปที่หน้าต่าง Inspector ทางด้านซ้ายมีบนจะเห็น Tag ให้คลิกที่ตรง Untagged จะมี Add Tag มาให้เลือก
จะเห็นเห็นหน้าต่าง Tag & Layers ให้ทำการคลิกที่เครื่องหมายบวก จากนั้นที่ Tag 0 ให้ใส่ชื่อแท็กเป็น Background
จากนั้นคลิกเลือกเกมออบเจ็ค Background2 ที่หน้าต่าง Inspector คลิกที่ Untagged จะเห็นว่ามี Tag Background ที่เราสร้างขึ้นเมื่อสักครู่นี้มาให้เลือกแล้ว ให้ทำการเลือก Tag Background
จากนั้นที่ Prefab ตรงข้างล่าง Tag ให้กดปุ่ม Apply ทางด้านขวามือ จากนั้นให้เลือกที่เกมออบเจ็ค Background1 จะเห็นว่าที่เกมออบเจ็ค Background1 จะมี Tag เป็น Background แล้วเหมือนกัน นี้คือข้อดีของการสร้างออบเจ็คเป็น Prefab ที่ได้กล่าวถึงแล้วในตอนที่แล้ว ให้ลองเช็คเกมออบเจ็ค Background3 ด้วย
มาต่อกันที่โค้ด หลายๆคนคงจะสงสัยว่าทำไมต้องสร้างตัวแปร _NumberObject และ _TagName ทำไมไม่กำหนดไปในโค้ดเลยให้เป็น 3 กับ Background เลย คำตอบคือเพราะเราจะนำโค้ดนี้ไป Reuse ใช้กับการวนลูปของพื้น และสิ่งกีดขวางด้วยเช่นกัน เนื่องจากคอนเซ๊ปของ Unity คือการ Reuse

กลับไปที่ Unity ให้เพิ่ม Script Looper ให้กับเกมออบเจ็ค BGLooper ที่หน้าต่าง Inspector ตรง Script Looper จะมีค่า Number Object ให้ใส่ ในที่นี้ให้ใส่ 3 เนื่องจากฉากหลังเรามี 3 อัน และที่ Tag Name ให้ใส่ Background เนื่องจาก BGLooper จะทำหน้าที่วนลูปเกมออบเจ็คพื้นหลังที่เราได้ทำการติด Tag Background ให้เรียบร้อยแล้ว
เมื่อมีการชนโดยไม่คิดกฏฟิสิกส์เกิดขึ้นเนื่องจากเลือก Is Trigger จะทำให้ฟังชั่น OnTriggerEnter2D ทำงาน ดังนั้นเราจะวนลูปฉากพื้นหลังในฟังก์ชั่นนี้โดยใช้การเปลี่ยนตำแหน่งดังที่สอนไปแล้วในตอนก่อนๆนี้ จะได้โค้ดดังนี้

public class Looper : MonoBehaviour
{
  public int _NumberObject;
  public string _TagName;

  public void OnTriggerEnter2D(Collider2D collider)
  {
    if (collider.gameObject.tag == _TagName)
    {
      //คำนวณความกว้างของของพื้นหลัง
      float width = collider.GetComponent<BoxCollider2D>().size.x * collider.transform.localScale.x;

      Vector3 pos = collider.transform.position;
      pos.x += width * _NumberObject;
      collider.transform.position = pos;
    }
  }
}

กดรันเกมเพื่อทดสอบจะเห็นว่าเครื่องบินหายไป เนื่องจากตำแหน่งในแกน Z ให้เปลี่ยน Position Z ของเกมออบเจ็ค Plane เป็น -5
ในหน้าต่าง Scene ในกดปุ่ม 2D เพื่อเปลี่ยนโหมดเป็น 3D ดูจะเห็นว่าเครื่องบินมาอยู่ข้างหน้าพื้นหลังแล้ว
หลังจากนั้นให้กดรันและทดสอบเกมอีกครั้งจะเห็นว่าเรามีฉากหลังแบบ Infinity แล้ว

ไม่มีความคิดเห็น:

แสดงความคิดเห็น