ตัวอย่างการเขียนเกมด้วย Unity 3D ร่วมกับ RidgidBody Control แบบ Physics ให้ลูกบอลกลิ้งเหมือนเกม Roll a Ball แบบง่ายด้วยภาษา C# และองค์ประกอบเงื่อนไขในฉากเกม
ออกแบบฉากด้วย Cube และ Sphere ดังตัวอย่างที่ปรากฏในภาพประกอบ โดยตั้งชื่อ Sphere เป็น “Ball” และใส่ Tag เป็น “Player”
ให้สร้าง New Project ขึ้นมาก่อนครับเป็นเกมแนว 3D แบบง่ายๆไปที่
Main Camera ใส่ Script นี้เข้าไปครับเป็น C# ชื่อ ControllCamera.cs
using UnityEngine; using System.Collections; public class ControlCamera : MonoBehaviour { public Transform target; float distance = -7f; float lift = 1.5f; void Update () { transform.position = target.position + (new Vector3(0, lift, distance)); transform.LookAt (target); } }
เราจะได้ค่าของ Camera control ให้วิ่งตามตัวละครของเราคือ ลูกบอล หรือ “Ball” ในระนาบ Side Scrolling ครับ ให้เรานำ Ball ไปไว้ใน Transform ของ Inspector ตัว ControlCamera ครับ
ต่อจากนั้นให้เราหา Model ที่มี animation เป็นวิ่งเรื่อยๆ มาวางไว้ในส่วนของ Main Camera ดังตัวอย่าง โดยหน้าที่คือแสดงผลเหมือนเดินบนลูกบอล (แต่จริงๆ ไม่ใช่) สร้าง Capsule Collider ครอบตัวละครคนไว้
สร้าง Plane ขึ้นมาให้ครอบคลุมฉากทั้งฉาก และตั้งค่าการ Trigger ไว้ให้เรียบร้อย ตั้งชื่อว่า “water” วางไว้ตำแหน่งล่างของฉากเพื่อตัวละครตกลงไปโดน
ต่อมาเราจะทำการเขียนคำสั่งบังคับลูกบอลของเราแล้ว ให้ตั้งค่า Inspector ของลูกบอลเราตามนี้
สร้างไฟล์ ControlBall.cs ขึ้นมา
using UnityEngine; using System.Collections; public class ControlBall : MonoBehaviour { float rotationSpeed = 1000f; int jumpHeight = 9; private bool playOnce = true; private bool isFalling = false; public float gravity = 20.0F; void Start () { } void Update () { Vector3 v = GetComponent<Rigidbody>().velocity; float rotation = Input.GetAxis ("Horizontal") * rotationSpeed; rotation *= Time.deltaTime; GetComponent<Rigidbody>().AddRelativeTorque (Vector3.back * rotation); if (Input.GetKeyDown(KeyCode.W) && isFalling == false) { v.y = jumpHeight; GetComponent<Rigidbody>().velocity = v; playOnceTrue(); v.y -= gravity * Time.deltaTime; } if (Input.GetKeyDown(KeyCode.F) && isFalling == false) { v.x = jumpHeight; GetComponent<Rigidbody>().velocity = v; playOnceTrue(); } isFalling = true; } void OnCollisionStay () { if (playOnce == true) { playOnce = false; } isFalling = false; } void playOnceTrue() { StartCoroutine (DelayGame()); } IEnumerator DelayGame() { while (true) { yield return new WaitForSeconds(0.2f); playOnce = true; } } }
คำสั่งในการเคลื่อนไหวจะเป็นแบบ RidgidBody Base ตามนี้ครับ
Vector3 v = GetComponent<Rigidbody>().velocity; float rotation = Input.GetAxis ("Horizontal") * rotationSpeed; rotation *= Time.deltaTime; GetComponent<Rigidbody>().AddRelativeTorque (Vector3.back * rotation); if (Input.GetKeyDown(KeyCode.W) && isFalling == false) { v.y = jumpHeight; GetComponent<Rigidbody>().velocity = v; playOnceTrue(); v.y -= gravity * Time.deltaTime; } if (Input.GetKeyDown(KeyCode.F) && isFalling == false) { v.x = jumpHeight; GetComponent<Rigidbody>().velocity = v; playOnceTrue(); } isFalling = true;
เมื่อกด W จะมีการกระโดด
if (Input.GetKeyDown(KeyCode.W) && isFalling == false) { v.y = jumpHeight; GetComponent<Rigidbody>().velocity = v; playOnceTrue(); v.y -= gravity * Time.deltaTime; }
เมื่อกด F จะมีการพุ่งไปข้างหน้า
if (Input.GetKeyDown(KeyCode.F) && isFalling == false) { v.x = jumpHeight; GetComponent<Rigidbody>().velocity = v; playOnceTrue(); }
ต่อมาให้เราไปที่ตัวละครคนครับ ใส่ C# ไฟล์ checkDead.cs ลงไป เพื่อเช็คว่าตกลงไปโดนน้ำ แล้วจะเคลียร์ gameObject ตัวคน หน่วงเวลาไว้ 1 วินาทีกว่าๆ แล้วก็หยุดเวลา
Time.timeScale = 0;
ไฟล์ checkDead.cs มีคำสั่งดังนี้
using UnityEngine; using System.Collections; public class checkDead : MonoBehaviour { public ParticleEmitter Explosion; void OnTriggerEnter(Collider theCollision){ if(theCollision.gameObject.name == "water"){ Instantiate(Explosion, transform.position, transform.rotation); StartCoroutine (DelayGame()); } } IEnumerator DelayGame() { while (true) { yield return new WaitForSeconds(0.17f); Time.timeScale = 0; Destroy(gameObject); } } }
ทดสอบการบังคับเกมกันหน่อย
ลองตกลงน้ำดู เกมก็จะหยุดค้างทันที, จบบทเรียนนี้แล้วครับ