DeveloperFeaturedGame DevelopmentGame DevelopmentUnity 3D

Unity 3D การ Movement ตัวละครทั้ง Run, Jump และ Attack

บทเรียนสำหรับควบคุมตัวละครของเราด้วย Unity 3D เขียนเกม 3 มิติให้ ตัวละครของเราเดินไปมาผ่านการ Input ด้วย Keyboard และ Mouse ไปจนถึงการโจมตีด้วย JavaScript

ก่อนจะศึกษาบทเรียนนี้ไปทบทวนบทเรียนเก่าๆ ก่อนที่

เราจะหยิบงานจากบทเรียนก่อนหน้านี้คือ การควบคุมมุมกล้องของเกมด้วย Mouse Movement บน Unity3D บทนี้มาปรับใช้เพิ่มเติมเล็กน้อยครับ เปิด Project เดิมขึ้นมา

Mouse ในมือมันสั่น
Mouse ในมือมันสั่น

เราจะ Control ตัวละครของเราให้เดินไปมาในฉากได้อิสระบน Terrain ที่สร้างขึ้นด้วยการกดปุ่ม Keyboard ครับ อย่างที่เคยบอกไว้ว่า คำสั่ง GetAxis คือ รับค่าการกดปุ่มลูกศร โดยการรับค่า Left & Right หรือ ซ้ายและขวา จะอ้างอิงผ่าน Input.GetAxis(“Horizontal”) และ บน ล่าง Up & Down คือ Input.GetAxis(“Vertical”) เราจะใช้แป้น Keyboard ของเรามาควบคุมคือปุ่มสำหรับควบคุมคือ W,A,S,D ครับ

เปิดไฟล์ Players.js ผ่าน Monodevelop ขึ้นมาครับ ใส่คำสั่งต่อไปนี้

ประกาศส่วน Header ก่อน

#pragma strict
var rotationSpeed : float = 10;
var walkspeed : float= 7;
var gravity : float = 50;
private var yRot : float;
var body : Transform;

เราจะตั้งค่า walkspeed ความเร็วของการเดินหรือวิ่งไว้ที่ 7 เป็นตัวเลข Interval ครับ สร้างตัวแปร Body สำหรับ Transform การเคลื่อนไหวกรณีกระโดด และเขียนคำสั่งต่อไปนี้เพิ่มเข้าไปที่ update()

if(Input.GetAxis("Vertical") || Input.GetAxis("Horizontal")){
		animation.CrossFade("Run",0.2);
		animation["Run"].speed = walkspeed/10;
		Controller.Move((vertical *(walkspeed * Input.GetAxis("Vertical"))) * Time.deltaTime);
		Controller.Move((horizontal *(walkspeed * Input.GetAxis("Horizontal"))) * Time.deltaTime);
	}else{
		animation.CrossFade("idle",0.2);
	}

เป็นคำสั่งที่เรารับค่าการเดินหน้า ถอยหลัง หรือซ้ายขวาผ่าน Keyboard แล้วตัวละครของเราจะเลือก Animation ที่ชื่อว่า Run มาทำงาน และเมื่อเอามือออกจากแป้น ตัวละครของเราก็จะกลับสู่สถานะ idle

Animation ของตัวละคร
Animation ของตัวละคร

หมายเหตุ: Asset Store ที่เราโหลดมาบางตัวไม่มี Animation มาให้ครับ ต้องไปสร้างเอง

สร้างฟังก์ชันมาใหม่ชื่อ LateUpdate ให้ตัวละครของเราหมุนหรือหันหน้าไปที่ ทิศที่เราจะมุ่งหน้าไปตามทิศของ Mouse

function LateUpdate(){
  if(Input.GetAxis("Vertical") == 0){
    if(Input.GetAxis("Horizontal") > 0){
      body.localEulerAngles.y = 180;
    }else if(Input.GetAxis("Horizontal") < 0){
      body.localEulerAngles.y = 0;
    }
  }else if(Input.GetAxis("Vertical") > 0){
    if(Input.GetAxis("Horizontal") > 0){
      body.localEulerAngles.y = 135;
    }else if(Input.GetAxis("Horizontal") < 0){
      body.localEulerAngles.y = 45;
    }
  }else if(Input.GetAxis("Vertical") < 0){
    if(Input.GetAxis("Horizontal") == 0){
      body.localEulerAngles.y = -90;
    }else if(Input.GetAxis("Horizontal") > 0){
      body.localEulerAngles.y = -135;
    }else if(Input.GetAxis("Horizontal") < 0){
      body.localEulerAngles.y = -45;
    }
  }
}

เพิ่มการกระโดดของตัวละครให้ไปที่ update() ครับใส่คำสั่งนี้ลงไป

if(Input.GetKeyDown("space")){
   PlayerJump();
}

และไปสร้างฟังก์ชัน PlayerJump() มาใหม่ แล้วใส่คำสั่งตามนี้

function PlayerJump (){
	gravity = 10;
	yield WaitForSeconds(0.5);
	gravity = -50;
}

แก้ไข คำสั่งของเก่าส่วนของ gravity จากเดิมคือ

transform.rotation = Quaternion.Euler(0, yRot, 0);
Controller.Move(height * -gravity * Time.deltaTime);

แก้ไขเป็น

transform.rotation = Quaternion.Euler(0, yRot, 0);
	//Controller.Move(height * -gravity * Time.deltaTime);
Controller.Move(height * gravity * Time.deltaTime);

ลอง Run ตัวเกมของเราครับ แล้ววิ่งเล่นดู

กล้องไม่วิ่งตามตัวละครทำไงดี
กล้องไม่วิ่งตามตัวละครทำไงดี

ถ้าสังเกตแล้วจะเห็นว่า Main camera ไม่ได้วิ่งตามตัวละครของเราเลย เพราะว่าโหมดของมันเป็น Global ครับ ให้ใช้วิธีทำให้มันเป็น Local ให้เลื่อนเจ้า Main Camera ที่ Hierarchy จากส่วนนอกสุดไปไว้ใต้ ตัวละครของเราครับ

เลื่อนไปเป็น Local
เลื่อนไปเป็น Local

วีดีโอ ตอน Run นะครับ

การใส่ค่าโจมตี เราต้องตรวจจให้แน่ชัดว่า ตัวละครใน asset Store ที่เราโหลดมามี Animation ของการโจมตีอยู่หรือเปล่า ถ้ามีใส่คำสั่งนี้ครับ

// Detects clicks from the mouse and prints a message
// depending on the click detected.
function Update() {
		if(Input.GetMouseButtonDown(0))
			Debug.Log("Pressed left click.");
		if(Input.GetMouseButtonDown(1))
			Debug.Log("Pressed right click.");
		if(Input.GetMouseButtonDown(2))
			Debug.Log("Pressed middle click.");
}

เป็นการรับค่าของ การคลิก Mouse นั่นเอง เราก็เอามาเขียนร่วมกับ Animation ดังนี้ครับ ให้คลิก Mouse ซ้ายแล้วจะโจมตีก็แล้วกัน เพิ่มใน update()

if(Input.GetMouseButtonDown(0))
	animation.Play("Attack");
if(Input.GetMouseButtonDown(1))
	Debug.Log("Pressed right click.");
if(Input.GetMouseButtonDown(2))
	Debug.Log("Pressed middle click.");

ทำการ Run เกมของเราครับ แล้วคลิก Mouse ยิกๆ ไปเลย

เอ้าฟันดาบ
เอ้าฟันดาบ

วีดีโอของการ attack นะครับ

ภาพรวมของคำสั่งใน Players.js ก็จะเป็นดังนี้ ตรวจสอบกันดู

#pragma strict
var rotationSpeed : float = 10;
var walkspeed : float= 7;
var gravity : float = 50;
private var yRot : float;
var body : Transform;

function Update () {
	var Controller : CharacterController = GetComponent(CharacterController);
	var vertical : Vector3 = transform.TransformDirection(Vector3.forward);
	var horizontal : Vector3 = transform.TransformDirection(Vector3.right);
	var height : Vector3 = transform.TransformDirection(Vector3.up);
	
	if(Input.GetKeyDown("space")){
		PlayerJump();
	}
	
		if(Input.GetMouseButtonDown(0))
			animation.Play("Attack");
		if(Input.GetMouseButtonDown(1))
			Debug.Log("Pressed right click.");
		if(Input.GetMouseButtonDown(2))
			Debug.Log("Pressed middle click.");
	
	if(Input.GetAxis("Vertical") || Input.GetAxis("Horizontal")){
		animation.CrossFade("Run",0.2);
		animation["Run"].speed = walkspeed/10;
		Controller.Move((vertical *(walkspeed * Input.GetAxis("Vertical"))) * Time.deltaTime);
		Controller.Move((horizontal *(walkspeed * Input.GetAxis("Horizontal"))) * Time.deltaTime);
	}else{
		animation.CrossFade("idle",0.2);
	}
	
	if(Input.GetAxis("Mouse X")){
		yRot += 10 * Input.GetAxis("Mouse X");
	}
	transform.rotation = Quaternion.Euler(0, yRot, 0);
	//Controller.Move(height * -gravity * Time.deltaTime);
	Controller.Move(height * gravity * Time.deltaTime);
}

function LateUpdate(){
  if(Input.GetAxis("Vertical") == 0){
    if(Input.GetAxis("Horizontal") > 0){
      body.localEulerAngles.y = 180;
    }else if(Input.GetAxis("Horizontal") < 0){
      body.localEulerAngles.y = 0;
    }
  }else if(Input.GetAxis("Vertical") > 0){
    if(Input.GetAxis("Horizontal") > 0){
      body.localEulerAngles.y = 135;
    }else if(Input.GetAxis("Horizontal") < 0){
      body.localEulerAngles.y = 45;
    }
  }else if(Input.GetAxis("Vertical") < 0){
    if(Input.GetAxis("Horizontal") == 0){
      body.localEulerAngles.y = -90;
    }else if(Input.GetAxis("Horizontal") > 0){
      body.localEulerAngles.y = -135;
    }else if(Input.GetAxis("Horizontal") < 0){
      body.localEulerAngles.y = -45;
    }
  }
}

function PlayerJump (){
	gravity = 10;
	yield WaitForSeconds(0.5);
	gravity = -50;
}

จบแล้วครับการ Movement ตัวละคร ของเราผ่าน Input

Asst. Prof. Banyapon Poolsawas

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

Related Articles

Back to top button

Adblock Detected

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