FeaturedGame DevelopmentUnity 3D

Unity 2.5D สร้างเกมเดินต่อสู้ Beat Em Up ตอนที่ 1

บทเรียนการพัฒนาเกมแนว 2.5D แบบ Side Scrolling ร่วมกับโมเดล 3 มิติกับแนวเกมเดินต่อสู้ด้านข้าง หรือแนว Beat Em Up ด้วย Unity 3D เวอร์ชัน 5 กับการควบคุมตัวละคร

เกมแนว Beat Em Up เป็นเกมแนว Old School ที่มีการพัฒนามานานในระบบเกมรุ่นเก่าๆ ในยุคหลังๆ เนื่องจากจะประหยัดการใช้ Sprite Sheet 2มิติที่ต้องทำทีละเฟรม นักพัฒนาจึงนิยมปั้น โมเดล 3 มิติแล้วใช้การปรับแกนของมุมมองให้เป็น ระนาบแกน X,Y ออกไปแล้ให้ความสำคัญของระนาบแกน Z น้อยลง เลยกลายเป็นเกมแนว 2.5D หรือกึ่งๆ 3 มิติ

ตัวอย่างนี้จะเป็นการเริ่มต้นในการปรับมุมกล้องเพื่อทดสอบการทำ Workshop นี้โดยจะเริ่มที่การใช้เครื่องมือควบคุมตัวละครให้กดปุ่มเดินหน้า และถอยหลังๆ ได้อย่างปรกติอย่างที่ ตัวละครควรจะเป็นครับ

เริ่มต้นให้เปิด Project Unity ขึ้นมาได้เลยครับ

Screen Shot 2558-07-06 at 9.49.08 PM

หลังจากนั้นให้สร้าง Plane ขึ้นมาปรับ Inspector ดังนี้ครับ

Screen Shot 2558-07-06 at 9.49.14 PM

ตัวละครผมไปดาวน์โหลดมาจากชุดแจกฟรี Free Learning  ของเว็บไซต์ Mixamo.com ก็ต้องนำมา Rig ตัวโมเดลผ่าน Unity ให้เป็น Humaniod กันสักเล็กน้อย (วิธี Rig อ่านได้ที่ https://www.daydev.com/2015/unity-3d-model-humanoid-import.html)

Screen Shot 2558-07-06 at 9.50.09 PM

ทำการวางตัวละครลงไปใน Scene ครับแล้วหมุนกล้อง Main Camera ของเราแบบ Rotate ในด้านข้างเพื่อปรับระดับการฉายภาพของกล้อง พร้อมทั้งตั้งค่าระยะให้เหมาะสม

Screen Shot 2558-07-06 at 9.49.33 PM

ตั้ง Inspector ตามนี้ได้ครับ

Screen Shot 2558-07-06 at 9.49.37 PM

หากตั้งค่าระยะของกล้องได้เหมาะสมแล้วจะเห็น Preview ใน Game Scene ประมาณนี้

Screen Shot 2558-07-06 at 9.49.56 PM

ทำการควบคุมตัวละครกันสักเล็กน้อยครับ โดยการใส่ Physics->RigidBody (ไม่ต้องใส่ Gravity), ส่วนของ Physics -> Character Controller และ Physics -> Capsule Collider พร้อมกับปรับขนาดของ Capsule และ Controller ให้พอดีตัวละครของเรา อย่าลืม Is Trigger ใน Capsule Collider ด้วยครับ

Screen Shot 2558-07-06 at 9.49.51 PM

ไปหา Animation จาก Asset Store ที่เราคิดว่าจะนำมาใช้มาตั้งค่าของ Animator Controller ครับ (อ่านย้อนหลังได้ที่ https://www.daydev.com/2015/unity-animator-controller.html)

Screen Shot 2558-07-06 at 9.50.22 PM

 

จะเห็นว่าตั้ง Bool ใน Parameters ของ Animator Controller ไว้ชื่อว่า “IsRunning” ไว้เช็คกับโปรแกรมภาษา C# ครับ (เอา Has Exit Times ออกด้วยนะครับตอนทำ Transition ของ State – อ่านย้อนหลังได้ที่ https://www.daydev.com/2015/unity-animator-controller.html)

Screen Shot 2558-07-06 at 9.50.30 PM

ทดสอบว่า Animator ทำงานหรือเปล่า

Screen Shot 2558-07-06 at 9.50.52 PM

เอาล่ะถ้าครบแล้วเรามาเขียน Code กันสร้าง C# ชื่อ Player.cs ขึ้นมาครับในตอนนี้จะเป็นการควบคุมตัวละครของเราให้เดินไปมาในฉาก หากใช้ Code

CharacterController controller = GetComponent<CharacterController>();
if (controller.isGrounded) {
  moveDirection = new Vector3(-(Input.GetAxis("Horizontal")), 0, Input.GetAxis("Vertical"));
    if (Input.GetButton("Jump"))
      moveDirection.y = jumpSpeed;
      moveDirection = transform.TransformDirection(-moveDirection);
      moveDirection *= speed;
}

มันจะกลายเป็นว่าตัวละครของเราจะกด W เป็นเดินไปทางขวากด S เป็นเดินไปทางซ้ายซ้ำยังไม่หันหลังกลับด้านในทิศที่ต้องการไปอีกต่างหาก (เดินถอยหลัง ปุ่มบังคับผิด)

Code ไฟล์ Player.cs ต้องมีการเปลี่ยนส่วนของการควบคุมเป็นแบบนี้ครับ

if (controller.isGrounded) {
   moveDirection = new Vector3(-(Input.GetAxis("Vertical")), 0, Input.GetAxis("Horizontal"));
}

เป็นการสลับปุ่มให้ A,D เป็น เดินไปซ้าย และ ขวา และ W,S เป็นเดินเลื่อนขึ้น และ เดินเลื่อนลงมาแทนครับ แต่ปัญหาที่พบคือจะเห็นว่าตัวละครเมื่อกด A จะเดินถอยหลังไม่สามารถหมุนตัวละครกลับไปด้านซ้ายได้ เราเลยต้องมีการเขียน Code เพิ่มเข้ามาคือการรับค่า Quaternion เพื่อ Rotate ตัวละครของเราแล้วนำไปคำนวณกับ Speed ของการเดินอ้าง Direction ที่เป็นค่า (-1,1) คือ Transform ตัว GameObject ไปทางซ้ายพร้อมหันหน้า 180 องศา และทางขวาในรูปแบบเดียวกันครับ อ้างด้วยเครื่องหมาย -1 เป็นการกลับด้านของ Game Object

การเขียนไฟล์ C# Player.cs จึงต้องเป็นไปตามขั้นตอนนี้ครับ

ประกาศตัวแปรดังต่อไปนี้ครับ

Animator anim;
public float smooth = 1f;
public float speed = 6.0F;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
private Quaternion lookLeft;
private Quaternion lookRight;
private Vector3 moveDirection = Vector3.zero;

สังเกตที่

private Quaternion lookLeft;
private Quaternion lookRight;

เป็นการกำหนด สถานะของการหมุน Object ด้วยตัวแปร lookLeft และ lookRight เพื่อให้หมุนหรือหันไปทิศที่ต้องการก่อนจะเคลื่อนไหว

void Start(){
  Cursor.visible = false;
  anim = GetComponent <Animator> ();
  Time.timeScale = 1;

  lookRight = transform.rotation;
  lookLeft = lookRight * Quaternion.Euler(0, 180, 0); 
}

ทำการเพิ่ม Method Start() โดยซ่อน Cursor Mouse ออกไปเมื่อเริ่มเกม ตามด้วยกำหนด Component Animator ที่เราสร้างไว้ใหตัวละครเก็บ State ต่างๆ ไว้ในตัวแปร anim

กำหนด lookRight เป็นค่า Rotation เริ่มต้นให้ตัวละครเริ่มจาก ซ้าย และหันหน้าไปทางขวาก่อน และตั้งค่า lookLeft เป็นการอ้าง lookRight เพียงแค่ปรับแกน y ของตัวละคร เป็น 180 เพื่อให้ Rotate หันหลัง

เพิ่ม Code ต่อไปนี้ใน Method Update()

void Update() {
  CharacterController controller = GetComponent<CharacterController>();
  if (controller.isGrounded) {
    moveDirection = new Vector3(-(Input.GetAxis("Vertical")), 0, Input.GetAxis("Horizontal"));

    if (Input.GetButton("Jump"))
	moveDirection.y = jumpSpeed;

     if (Input.GetKey(KeyCode.A)){
	transform.rotation = lookLeft;
	moveDirection = transform.TransformDirection(-moveDirection);
	moveDirection *= speed;
	anim.SetBool ("IsRunning", true);
      }else{
	anim.SetBool ("IsRunning", false);
      }

     if (Input.GetKey(KeyCode.D)){
	transform.rotation = lookRight;
	moveDirection = transform.TransformDirection(moveDirection);
	moveDirection *= speed;
	anim.SetBool ("IsRunning", true);
     }else{
	anim.SetBool ("IsRunning", false);
     }
			
  }
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
}

พิจารณาส่วนของการเคลื่อนไหวใน Method Update()

if (Input.GetKey(KeyCode.A)){
	transform.rotation = lookLeft;
	moveDirection = transform.TransformDirection(-moveDirection);
	moveDirection *= speed;
	anim.SetBool ("IsRunning", true);
      }else{
	anim.SetBool ("IsRunning", false);
      }

เมื่อมีการกดปุ่มคีย์บอร์ด A ตัวละครจะทำการ transform rotation ไปที่ค่าของ lookLeft (ค่า lookRight ที่ปรับแกน y เป็น 180) ดังนั้นค่า movedirection หรือการเคลื่อนตัวละคร ต้องให้ TransfromDirection() เป็นค่า -moveDirection เพราะต้องวิ่งไปฝั่งตรงข้ามของการหันหน้า (วิ่งไปทางซ้าย นั่นเอง ให้เราทำการแสดง Animator state ที่เราตั้ง Bool ไว้ว่า IsRunning เป็น true และเมื่อปล่อยปุ่มก็ให้เป็น false

เช่นกันถ้ากดปุ่ม D จะคล้ายคลึงกันแค่ transform rotation ไปที่ค่าของ lookRight และตัว TransfromDirection() เป็นค่า moveDirection ที่ไม่ติดลบครับ

Code ไฟล์นี้จะออกมาหน้าตาแบบนี้

using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour {
	Animator anim;
	public float smooth = 1f;
	public float speed = 6.0F;
	public float jumpSpeed = 8.0F;
	public float gravity = 20.0F;
	private Quaternion lookLeft;
	private Quaternion lookRight;
	private Vector3 moveDirection = Vector3.zero;

	void Start(){
		Cursor.visible = false;
		anim = GetComponent <Animator> ();
		Time.timeScale = 1;

		lookRight = transform.rotation;
		lookLeft = lookRight * Quaternion.Euler(0, 180, 0); 
	}

	void Update() {
		CharacterController controller = GetComponent<CharacterController>();
		if (controller.isGrounded) {
			moveDirection = new Vector3(-(Input.GetAxis("Vertical")), 0, Input.GetAxis("Horizontal"));


			if (Input.GetButton("Jump"))
				moveDirection.y = jumpSpeed;

			if (Input.GetKey(KeyCode.A)){

				transform.rotation = lookLeft;
				moveDirection = transform.TransformDirection(-moveDirection);
				moveDirection *= speed;
				anim.SetBool ("IsRunning", true);
			}else{
				anim.SetBool ("IsRunning", false);
			}

			if (Input.GetKey(KeyCode.D)){
				transform.rotation = lookRight;
				moveDirection = transform.TransformDirection(moveDirection);
				moveDirection *= speed;
				anim.SetBool ("IsRunning", true);
			}else{
				anim.SetBool ("IsRunning", false);
			}
			
		}
		moveDirection.y -= gravity * Time.deltaTime;
		controller.Move(moveDirection * Time.deltaTime);
	}
}

ทดสอบกดปุ่ม A และ D ครับ

Screen Shot 2558-07-06 at 9.51.34 PM

เดินหน้าถอยหลังได้แล้ว

Screen Shot 2558-07-06 at 9.51.51 PM

บทเรียนต่อไปจะเป็นการสร้าง Animation และการกำหนด Collider ของตัวละครเมื่อมีการต่อสู้ และ Trigger กันครับ

Tutorial Sample Project: ดาวน์โหลดได้ที่:

https://drive.google.com/file/d/0B1kwQ1abTIRrNUM3QW9JZlllUUU/view?usp=sharing

Asst. Prof. Banyapon Poolsawas

อาจารย์ประจำสาขาวิชาการออกแบบเชิงโต้ตอบ และการพัฒนาเกม วิทยาลัยครีเอทีฟดีไซน์ & เอ็นเตอร์เทนเมนต์เทคโนโลยี มหาวิทยาลัยธุรกิจบัณฑิตย์ ผู้ก่อตั้ง บริษัท Daydev Co., Ltd, (เดย์เดฟ จำกัด)

Related Articles

Back to top button

Adblock Detected

เราตรวจพบว่าคุณใช้ Adblock บนบราวเซอร์ของคุณ,กรุณาปิดระบบ Adblock ก่อนเข้าอ่าน Content ของเรานะครับ, ถือว่าช่วยเหลือกัน