Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การแก้ไขปัญหา >> Android

วิธีสร้างเกม Android พื้นฐานด้วย Unity

ในคำแนะนำก่อนหน้าของ Appual "วิธีสร้างเกม Platform พื้นฐานด้วย Unity" (และ part 2) เราได้กล่าวถึงการใช้ Unity และ built-in WebGL plug-in สร้างเกม browser แบบ HTML5 เรียบง่าย - ในคำแนะนำคล้ายกันนี้ เราจะกล่าวถึงวิธีสร้างเกม Android พื้นฐานด้วย Unity

ข้อกำหนดเบื้องต้น:

  • Unity
  • Text editor ดีๆ เช่น NotePad++ (Optional แต่แนะนำ)
  • Android SDK

หากยังไม่มี ควรเริ่มด้วยการดาวน์โหลดและติดตั้ง Unity SDK และ Android SDK เราต้องการ Android SDK เพื่อทดสอบ APK ของเกมในสภาพแวดล้อม Android

เปิด Unity สร้างโปรเจกต์ใหม่ ทำเป็นโปรเจกต์ 2D

มีหลายแผงที่ต้องคุ้นเคย - Hierarchy panel จะมี scene elements ทั้งหมด (scene = "level" ที่กำลังทำงาน) มี Game tab ใช้เล่น/ทดสอบเกมขณะอยู่ใน editor และด้านขวาคือ Inspector panel ที่จะแก้ไข lighting, physics ฯลฯ

ขั้นแรก สร้าง sprite - จะเป็น main character (ที่เราควบคุม) สามารถวาด sprite เอง เช่น วาดสี่เหลี่ยมมีตา หรือดึง sprite จากอินเทอร์เน็ต - ต้องเป็นไฟล์ .PNG (พื้นหลังโปร่งใส)

ลากวาง sprite ลงใน main scene window (หน้าต่างใหญ่ที่สุด) จะปรากฏใน Hierarchy panel ด้านซ้าย

ตอนนี้สร้าง platforms เล็กน้อย - สามารถเป็นสี่เหลี่ยมง่ายๆ เพราะ resize ได้ง่ายเพื่อทำกำแพงและ platform อื่นๆ

สร้าง "sprite" สี่เหลี่ยมใหม่ ลากวางลง Scene window เหมือนกับ sprite character

ตอนนี้สั่ง Unity ให้ physics กับ main character - คลิกที่ main sprite character (ควรไฮไลท์สีน้ำเงินใน Scene window) แล้วใน Inspector panel หา "GameObjects"

กด "Add Component > Physics 2D > RigidBody2D" จะเพิ่ม physics ให้ sprite อัตโนมัติ ซึ่งไม่เช่นนั้นต้องสคริปต์เองใน SDK อื่น

วิธีสร้างเกม Android พื้นฐานด้วย Unity

เราต้องการป้องกัน main sprite character จากการหมุนวนควบคุมไม่ได้ - หา Constraints tab ใน Inspector panel (กับ main sprite ที่ยังไฮไลท์) และติ๊ก "Freeze Rotation Z"

หากกด "Play" main sprite character ควรตกจากท้องฟ้าและตกไปเรื่อยๆ - เราจะแก้ภายหลัง แต่สังเกตว่าเราเพิ่ม physics ได้ง่ายแค่ไหน Physics ที่เพิ่มขึ้นอยู่กับรูปทรงที่นำไปใช้ - หากเพิ่ม physics เดียวกันให้ sphere จะลูกกลิ้ง

เรายังต้องการ fix orientation ป้องกันตัวละครหมุนและ freewheeling หา 'constraints' ใน inspector กับ player ที่เลือก และติ๊ก freeze rotation Z ตอนนี้กด play อีกครั้ง ควรพบ player ตกจากท้องฟ้าสู่ความสิ้นหวังอันไม่มีที่สิ้นสุด

เพื่อหยุด main sprite character จากการตกไปเรื่อยๆ ต้องเพิ่ม collider นี่คือ solid outline ของรูปทรงที่เราจะเพิ่มให้ main sprite character ไฮไลท์ main sprite character กด "Add Component > Physics 2D > BoxCollider2D

ทำเดียวกันกับ platform ที่สร้างก่อนหน้า main sprite character ควร "collide" กับ platform และอยู่ได้

ตอนนี้ให้ camera ตาม main sprite character - ใน scene ควรมี camera object อยู่แล้ว ต้องลาก บน main sprite character

สิ่งนี้สำคัญมากหากสร้าง 3D based runner เช่น Slope ที่ต้องการ camera อยู่ด้านหลัง primary game object (main sprite character) ตลอดเวลา

วิธีสร้างเกม Android พื้นฐานด้วย Unity

ไปที่ Hierarchy panel ในรายการ GameObjects ลาก camera ใต้ main sprite character (Player GameObject) จะทำให้ main sprite character เป็น 'parent' ของ camera ดังนั้นเมื่อ Player GameObject เคลื่อนที่บนหน้าจอ camera ควรจะตามไป

สำหรับคำแนะนำเกมนี้ เราจะสร้าง endless runner แบบพื้นฐาน เช่น Run 3 ที่ main character วิ่งข้ามหน้าจอและหลีกเลี่ยง obstacles (หรือ "game over" หากชน) จะใช้ scripts หลายตัว ซึ่งส่วนใหญ่จะให้ในคำแนะนำนี้

Right click โฟลเดอร์ "Assets" สร้างโฟลเดอร์ใหม่ ชื่อ Scripts Right click โฟลเดอร์ใหม่นี้ กด "Create > C# Script" ชื่อ PlayerControls สคริปต์นี้จะกำหนดพฤติกรรมของ main sprite character

Double click สคริปต์ใหม่นี้ ควรเปิดใน Visual Studio - ทางเลือกอื่น (และความชอบส่วนตัว) แก้ไขใน NotePad++

ไฟล์สคริปต์ควรมี "boiler plate" code อยู่แล้ว - คือโค้ดที่ต้องทิ้งไว้หรือปรับให้เหมาะสม จะประหยัดเวลามาก เราจะเพิ่ม object ใหม่

เหนือบรรทัด void Start():

วิธีสร้างเกม Android พื้นฐานด้วย Unity

public Rigidbody2D rb;

โค้ดต่อไปจะไปใน Start() ใช้หา rigidbody - เราสั่ง Unity หา physics ที่ attach ไปที่ GameObjects (main sprite character) และ Start() จะรันเมื่อ object หรือ script ใหม่ถูกสร้าง

หา physics object

rb = GetComponent<Rigidbody2D>();

เพิ่มบรรทัดนี้ใน Update()

rb.velocity = new Vector2(3, rb.velocity.y);

Update() ทำหน้าที่ refresh ตลอดเวลา โค้ดที่เพิ่มในนั้นจะรันต่อเนื่อง (หาก object ไม่ถูก destroy) เราสั่ง script ให้ rigidbody มี vector ใหม่ใช้ความเร็วเดียวกันบนแกน Y (rb.velocity.y) แต่ความเร็ว 3 บนแกนแนวนอน ในอนาคตใช้ 'FixedUpdate()' ซึ่งคล้ายแตกต่าง เพราะควบคุม update/refresh amount ของ script ได้

เซฟสคริปต์ กลับไป Unity คลิก main sprite character ไฮไลท์ ใน Inspector panel ไป Add Component > Scripts เพิ่มสคริปต์ที่เซฟ ตอนนี้กด Play main sprite character ควรเคลื่อนที่ต่อเนื่องไปขอบ platform

การสร้าง Player Input Controls

เพราะเป็น endless runner style กับ obstacles ต้องเพิ่ม controls เช่น 'jump' button

เปิดสคริปต์เดิม เพิ่มโค้ดเพิ่มเติม:

if (Input.GetMouseButtonDown(0)) { rb.velocity = new Vector2(rb.velocity.x, 5); }

วางใน Update() method ทำงานคือเมื่อผู้เล่นคลิกเมาส์ (แปลงเป็น screen tap บน Android) main sprite character จะ "jump" เพราะเราเพิ่ม velocity บนแกน Y ค่า 5 (ค่าสูงกว่า = กระโดดสูงกว่า)

หากไม่คุ้นเคย coding เราใช้ If statement เพราะ If คือคำสั่ง "ทำหรือไม่ทำ" - บอกว่า IF นี้เกิดขึ้น ทำคำสั่งนี้ หากผู้เล่นไม่คลิกเมาส์ (หรือแตะหน้าจอ Android) สคริปต์จะไม่รัน

กด "Play" ทดสอบให้ทำงานถูกต้องก่อนต่อ

ต่อไปเพิ่ม obstacles (ที่ "destroy" main character sprite), game score, และ "game over" menu

หากทดสอบเกมจนตรงนี้ ปัญหาคือการกด "jump" button ที่สร้างจะกระโดดได้ตลอดเวลา ไม่ว่าจะ grounded หรือไม่ - นี้คือ Flappy Birds ไม่ใช่ runner ที่เราอยากได้ แต่เราจะแก้

ในสคริปต์ เพิ่มโค้ดนี้ เหนือ Update() method:

public Transform groundCheck; public Transform startPosition; public float groundCheckRadius; public LayerMask whatIsGround; private bool onGround; และเพิ่มบรรทัดนี้ใน Update method เหนือ if statement: onGround = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround); และเปลี่ยนบรรทัดต่อไปนี้ให้รวม "&& onGround" if (Input.GetMouseButtonDown(0) && onGround) { ดังนั้นสคริปต์ทั้งหมดควรเป็นแบบนี้: public class PlayerControls : MonoBehaviour { public Rigidbody2D rb; public Transform groundCheck; public Transform startPosition; public float groundCheckRadius; public LayerMask whatIsGround; private bool onGround; void Start() { rb = GetComponent<Rigidbody2D>(); } void Update() { rb.velocity = new Vector2(3, rb.velocity.y); onGround = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround); if (Input.GetMouseButtonDown(0) && onGround) { rb.velocity = new Vector2(rb.velocity.x, 5); } } }

อธิบายสิ่งที่ทำ: เราสร้าง "transform" ใหม่ คือตำแหน่งในพื้นที่โลกเกม ตั้ง radius และสั่ง Unity ตรวจสอบว่า radius ทับซ้อนกับ layer "ground" หรือไม่ - หาก radius sync กับ "ground" ตัวละครควรกระโดดได้ และหากอยู่ในอากาศจากการกระโดดแล้ว ไม่ควรกระโดดซ้ำ โดยพื้นฐาน onGround จะเป็น true ถ้า transform ชื่อ groundCheck ทับซ้อนกับ ground layer หวังว่าจะเข้าใจ

เซฟสคริปต์ กลับ Unity จะเห็นตัวเลือกเพิ่มใน Inspector หลังไฮไลท์ player นี่คือ public variables ปรับได้ตามใจชอบ

Right-click Hierarchy สร้าง empty object ใหม่ ลากให้อยู่ใต้ main character sprite ใน Scene window วาง empty object ที่ต้องการตรวจจับพื้น เปลี่ยนชื่อเป็น "Check Ground" ลากใต้ player's game object เหมือน camera (สร้าง parent-child relationship) ตอนนี้ empty object จะตาม main character sprite เหมือน camera และตรวจสอบระยะพื้นต่อเนื่อง

เลือก main character sprite ไป Inspector panel ลาก Check Ground object ไปที่ช่อง "groundCheck" 'transform' position ควรเท่ากับตำแหน่ง object นี้ ที่ "Radius" ทำเป็น 0.1

ต้องกำหนด ground layer เลือก ground terrain ใน Inspector หาปุ่ม "Layer: Default" (dropdown) เลือก "Add Layer"

เลือก "ground" เป็น layer สำหรับ platform ทำซ้ำสำหรับ platform อื่นๆ ใน game window ที่ "What is Ground" บน main character sprite เลือก ground layer ด้วย

เราสั่ง player script ตรวจสอบ - ถ้า จุดเล็กบนหน้าจอทับซ้อนกับอะไรที่ match layer ตัวละครจะกระโดดก็ต่อเมื่อเป็นจริง

Game Over เมื่อชนและ Game Menu

เพื่อปิดท้าย สิ่งสุดท้ายคือ A: ทำให้ชน obstacles = game over และ B: สร้างหน้าจอ "game over" พร้อมปุ่ม play again

สิ่งที่ต้องทำ:

  1. เพิ่ม object Player กำหนด rigidbody และ collider ที่ต้องการ
  2. เพิ่ม object Enemy กำหนด rigidbody และ collider ที่ต้องการ (optional เพิ่ม tag "Enemy")
  3. สร้าง C# script ใหม่ เพิ่มเป็น component ให้ Player (หรือใช้ script ที่ attach กับ player อยู่แล้ว ไม่ต้องสร้างใหม่หากมีอยู่)
  4. เพิ่มในสคริปต์:
void OnCollisionEnter(Collision coll){ Debug.Log("Collision"); //ตรวจสอบว่าลงทะเบียน collision ได้หรือไม่ หากได้สามารถลบบรรทัดนี้ if(coll.gameobject.tag == "Enemy"){ //ดูว่าอbject ที่ player ชนมี tag "Enemy" แทนที่ได้ด้วย if(coll.gameobject.name == ... แต่ tag ง่ายกว่า //เพิ่มโค้ดที่นี่ เช่น: Application.LoadLevel("GameOver"); Debug.Log("Working"); //หากทำงาน ลบบรรทัดนี้ }

เล่นกับตัวอย่างสคริปต์นี้ - ด้วย trial and error จะได้ผลที่ต้องการ

สำหรับวิธีสร้าง GameOver "level" พร้อม Play button ดูส่วนท้ายของคำแนะนำ Appual "วิธีสร้างเกม Platform พื้นฐานด้วย Unity Pt. 2"