Android DeveloperDeveloperFeaturedGame DevelopmentUnity 3D

Unity 5 เขียนเกมวิ่งเก็บของบน Android หลักสูตรเร่งรัดเป็นเร็ว

วันนี้จะพาทุกคนเข้าสู่บทเรียนแบบ Step by Step สำหรับการใช้งาน Unity 5 สำหรับเขียนเกม 3D บนสมาร์ทโฟน แพลตฟอร์ม Android แบบ Step by Step ด้วย Javascript ครับ

วันนี้เราจะเริ่มต้นที่ Unity 5 ซึ่งผมจะขอละการติดตั้ง Unity 5 ออกไปเพราะคิดว่าคงอ่าน ภาษาอังกฤษกันเป็น วิธีการมันต้องทำ 2-3 ขั้นตอน ถ้าขยันอ่านก็คงทำกันได้ เราจะมาเริ่มต้นพัฒนาเกม วิ่งเก็บเหรียญ และกระโดดหลบก้อนหิน บังคับด้วยการแตะที่หน้าจออย่างเดียว เล่นบน สมาร์ทโฟน แพลตฟอร์ม Android ของ Google ดังนั้นโปรเจ็คนี้เมื่อเสร็จแล้วจะได้ไฟล์ APK มาครับ

หมายเหตุ: Assets ทั้งหมด และ Animation ทั้งหลายที่ปรากฏบน code ชุดนี้อาจจะไม่ตรงกับ Assets ของคุณเพราะผมซื้อมาจาก Asset Store เกมที่เราจะพัฒนามีชื่อว่า BoonMee (ลุงบุญมีระลึกชาติละมั้ง)

เปิด Unity 5 ขึ้นมาครับ

mobile-game-unity-1

ลากส่วนของ Assets ที่เรามีไปวางบน Project ของเราครับ ศึกษาพวก Animation ดีๆ ว่าเป็น Legacy หรือเปล่า

ตั้งค่าตำแหน่งกล้องของเราให้ดีครับ

mobile-game-unity-2

ในตัวอย่างกำหนด Viewport ให้อยู่ในขนาดของหน้าจอ Android มาตรฐาน ซึ่งประกอบไปด้วย 720×1280 ครับ

mobile-game-unity-3

 

แปลว่าเราจะสร้างเกมที่เป็นแนว Portrait แนวตั้งบน Android ครับ

ตั้งค่า Main Camera ของเราให้อยู่ในตำแหน่งที่เราจะ control ได้ง่ายตามตัวอย่างข้างล่าง คือ Position(0,1,-10)

mobile-game-unity-4

ต่อไปเราจะสร้าง พื้นให้เรา Create 3D Object อย่าง Cube ขึ้นมาครับ

mobile-game-unity-5

เปลี่ยนชื่อใน Inspector ใหม่ให้เข้าใจง่ายว่าเป็นพื้นครับ แล้วทำการปรับ Scale และ Position มันตามนี้

mobile-game-unity-6

ตั้งชื่อว่า Road ครับ หา Materials สวยๆ จาก Assets Store ฟรีๆ พวก Terrain Asset มาใช้ก็ดีครับ

mobile-game-unity-7

ลาก Material ใน folder ไปวางบน Cube ที่ชื่อ Road ของเราเลยครับ

mobile-game-unity-8

สร้าง Javascript ขึ้นมาใหม่ชื่อว่า Road.js ครับ ใส่ code ตามนี้

#pragma strict
var speed : float = 0.5f;
var offset : float;

function Start () {

}

function Update () {

	offset = Time.time * speed;
	GetComponent.<Renderer>().material.mainTextureOffset= new Vector2(0,-offset);

}

เป็นการบังคับให้ พื้น Material ของถนนเลื่อนเข้าหากล้องให้พื้นเคลื่อนไหวครับ

mobile-game-unity-9

สำหรับตัวละครผม ย้ำนะว่า Animation มีชื่อว่าอะไรบ้างให้จำไว้สำหรับเปลี่ยนใน code นะครับ พอดีผมไปซื้อมาชื่อ Farmer ผมก็ลาก Prefabs ที่เป็น Legacy ลงไปใน Scene View

mobile-game-unity-10

mobile-game-unity-12

 

ส่วนของ Animation ของ Models ของผมที่ซื้อมามี animation ตามนี้ให้จำชื่อไว้ใช้ใน Code

 

mobile-game-unity-13

 

ทำการเลือก Physics>Character controller และ Capsule Collider ไปคลอบตัวละครของเรา

mobile-game-unity-14

กำหนดค่าต่างๆ ให้ Capsule และ Character คลอบตัวละครพอดีไม่จมพื้นที่ยืนอยู่

mobile-game-unity-15

 

สร้าง Javascript มาใหม่ชื่อว่า PlayerMobile.js แล้วใส่ code ต่อไปนี้

#pragma strict

var speed : float = 6.0;
var jumpSpeed : float = 8.0;
var gravity : float = 20.0;
public var statejump : boolean = false;
private var isGrounded : boolean = false;
private var PlayerMoveDirection : Vector3 = Vector3.zero;

function Start () {
}

function Update () {
	
		var controller : CharacterController = GetComponent(CharacterController);
		GetComponent.<Animation>().CrossFade("MF_Walk",3);
		
		if (controller.isGrounded) {
			statejump = false;
			
			if(Input.GetMouseButtonDown(0)) {
				PlayerMoveDirection.y = jumpSpeed;
				statejump = true;
				
			}
		}
		PlayerMoveDirection.y -= gravity * Time.deltaTime;
		controller.Move(PlayerMoveDirection * Time.deltaTime);
		
}

คำสั่งบังคับให้ตัวละครเดินเมื่ออยู่บนพื้นคือ

GetComponent.<Animation>().CrossFade("MF_Walk",3);

และคำสั่งให้ตัวละครกระโดด เมื่อคลิกเมาส์ หรือแตะหน้าจอคือ

if (controller.isGrounded) {
			statejump = false;
			
			if(Input.GetMouseButtonDown(0)) {
				PlayerMoveDirection.y = jumpSpeed;
				statejump = true;
				
			}
		}

ทดสอบโดย ทำอะไรสักอย่างที่ว่ามาคือ แตะหน้าจอ หรือคลิกเมาส์

mobile-game-unity-16

ขั้นตอนต่อไปให้เราสร้าง HUD (หน้าจอ Interface ของเกม ซึ่งจะเป็นการบอกว่าเราเก็บเหรียญได้มากกี่เหรียญแล้ว) ให้ลาก Object Prefab รูปเหรียญไปวางบน Hierarchy แล้วลากไปไว้ใน Main Camera

mobile-game-unity-17

ต่อมาคือการสร้าง ระบบของเกมครับ ให้ Create Empty Object มาใหม่ตั้งชื่อว่า Gamesystem ครับ

mobile-game-unity-18

สร้างไฟล์ GamePlay.js แล้วเขียน code นี้ลงไปครับ

#pragma strict

var timeRemaining : float = 10;
var lifes : int = 3;
var timeExtension : float = 3f;
var timeDeduction : float = 2f;
var totalTimeElapsed : float = 0;
var score : int = 0;
public var isGameOver : boolean = false;

public var GameSkin : GUISkin;

function Start(){
	Time.timeScale = 1;
}

function Update () {
		
	if(isGameOver){
		return; 
	}
	if(lifes <= 0){
		isGameOver = true;
	}
}

function GetItems(){
	score=score+1;
	timeRemaining += timeExtension;
}

function CrashMonster(){
	lifes = lifes -1;
	timeRemaining -= timeDeduction;
}

function OnGUI () {
	var IntTimeRemaining : int = lifes;
	var IntScore : int = score;
	
	if(!isGameOver)    
		{			
			GUI.skin = GameSkin;
			GUI.Label(new Rect(Screen.width-(Screen.width/6), 30, Screen.width/6, 
			 Screen.height/6),""+IntTimeRemaining.ToString());
								
			GUI.Label(new Rect((Screen.width/5)+10, 30, Screen.width/5, 
			Screen.height/6),"  "+IntScore.ToString());			
		}else{
			Time.timeScale = 0;		
			
			GUI.Box (Rect (Screen.width/4,  Screen.height/4+10, Screen.width/2, 
			Screen.height/2), "\nGAME OVER\nTOTAL SCORE: "+IntScore);		
		// Replay Button
		if (GUI.Button (Rect (Screen.width/4+10,
			 Screen.height/4+Screen.height/10+60,
			 Screen.width/2-20,Screen.height/10), "Restart")) {
			 Application.LoadLevel ("GAME");
		}	
		// Exit Button
		if (GUI.Button (Rect (Screen.width/4+10,
			 Screen.height/4+Screen.height/10+130,
			 Screen.width/2-20,Screen.height/10), "Main Menu")) {
			 Application.Quit();
		}
	}
}

จะเป็นเงื่อนไข กรณีที่เรา Game Over ให้แสดงหน้าจอ GUI ถ้าไม่ก็จะแสดงคะแนน และชีวิตของเรา โดยเงื่อนไขของเราคือการวิ่งชน 3 ครั้งก็จะ Game Over ส่วน GUI นั้นให้เราสร้างตัวแปรมารับคือ GameSkin ประกาศที่

public var GameSkin : GUISkin;

และเรียกใช้ที่

if(!isGameOver)    
		{			
			GUI.skin = GameSkin;
			GUI.Label(new Rect(Screen.width-(Screen.width/6), 30, Screen.width/6,

ให้ไปหา Font สวยๆ มาใช้งานก่อน โหลดและไปวางบน Project ครับ

mobile-game-unity-33

สร้าง GUI Skin ขึ้นมาใหม่

mobile-game-unity-32

ตั้งค่า Label ปรกติแล้วลาก Gui Skin ของเราไปวางที่ Object Gamesystem เลยครับ

ต่อมาคือเงื่อนไขการได้คะแนน และ เสียชีวิต

function GetItems(){
	score=score+1;
	timeRemaining += timeExtension;
}

function CrashMonster(){
	lifes = lifes -1;
	timeRemaining -= timeDeduction;
}

ให้เราสร้าง Prefabs ใหม่ขึ้นมาชื่อว่า Items และ Rock ครับ

mobile-game-unity-21

mobile-game-unity-22

ใช้ Asset จาก Terrain Assets อย่างก้อนหินมาประกอบกันให้เป็น กำแพงกั้นไม่สูงมากพอให้ตัวละครกระโดดหลบได้ แล้วใส่ Box Colider ลงไปครับ

mobile-game-unity-20

ลาก Rocks ที่เราสร้างบน Hierarchy ไปวางบน Prefabs ชื่อ Rocks

mobile-game-unity-23

สร้าง Javascript ขึ้นมาใหม่ชื่อว่า Flying.js ครับ ใส่ code ต่อไปนี้ ไม่มีอะไรมากแค่เป็นการบังคับให้วัตถุที่เป็น Prefabs ลอยเข้าหากล้องครับ

#pragma strict
public var objectSpeed : float = -0.5f;
var SecondsUntilDestroy : float = 7;
private var startTime : float;

function Start(){
	startTime = Time.time; 
}

function Update () {
	
	transform.Translate(0, 0, objectSpeed);
}

function FixedUpdate () {
	if (Time.time - startTime >= SecondsUntilDestroy) {
           Destroy(this.gameObject);
       }
}

เช่นเดียวครับทำ เหรียญขึ้นมา แล้ว โคลนตัว Prefabs วิธีเดียวกันใส่ Javascript ไฟล์ใหม่ชื่อว่า Coinflying.js

mobile-game-unity-25

#pragma strict
public var objectSpeed : float = -0.5f;
var SecondsUntilDestroy : float = 7;
private var startTime : float;

function Start(){

	startTime = Time.time; 
}

function Update () {
	objectSpeed = Random.Range(-0.03f,-0.5f);
	Debug.Log("objectSpeed:"+objectSpeed);
	transform.Translate(0, 0, objectSpeed);
}

function FixedUpdate () {
	if (Time.time - startTime >= SecondsUntilDestroy) {
           Destroy(this.gameObject);
       }
}

เช่นกันสร้างไฟล์ Javascript ชื่อ TreeFlying.js ขึ้นมาใส่ code

#pragma strict
public var objectSpeed : float = -0.2f;
var SecondsUntilDestroy : float = 10;
private var startTime : float;

function Start(){
	startTime = Time.time; 
}

function Update () {
	transform.Translate(0, 0, objectSpeed);
}

function FixedUpdate () {
	if (Time.time - startTime >= SecondsUntilDestroy) {
           Destroy(this.gameObject);
       }
}

ทำการโคลน Prefabs

mobile-game-unity-29

เพิ่ม ไฟล์ Javascript ใหม่เข้าไปใน Gamesystem ครับชื่อ

#pragma strict
public var monster : GameObject;
public var items : GameObject;
public var trees : GameObject;

var timeElapsed : float = 0;
var ItemCycle : float = 0.5f;
public var ItemPowerup : boolean = true;

function Start(){
}

function Update () {
		var pos : Vector3;
		
		ItemCycle = Random.Range(0.9f,4f);
		
		
		timeElapsed += Time.deltaTime;
		if(timeElapsed > ItemCycle)
		{
			var temp : GameObject;
			var temp_tree : GameObject;
			if(ItemPowerup)
			{
				temp = Instantiate(items);
				pos = temp.transform.position;
				temp.transform.position = new Vector3(pos.x, Random.Range(-0.5,1), pos.z);
				
			}else{
				temp = Instantiate(monster);
				pos = temp.transform.position;
				temp.transform.position = new Vector3(pos.x, pos.y, pos.z);			
			}
			
				temp_tree = Instantiate(trees);
				pos = temp_tree.transform.position;
				temp_tree.transform.position = new Vector3(pos.x, pos.y, pos.z);
			
			timeElapsed -= ItemCycle;
			ItemPowerup = !ItemPowerup;
		}
}

เพื่อไว้สำหรับสุ่มการปรากฏของวัตถุที่จะลอยเข้าหากล้อง แล้วลาก Prefabs ทั้งหมดไปใส่ใน Gamesystem Object ครับ

mobile-game-unity-38

กลับไปที่ตัวละครครับ สร้างไฟล์ Javascript ขึ้นมาชื่อว่า Collision.js ใส่ code ต่อไปนี้

#pragma strict

public var logic : GamePlay;

function Start () {
}

function Update () {
}

function OnTriggerEnter(c : Collider){
	if(c.gameObject.name == "Items(Clone)")
		{
			//Items
			logic.GetItems();
			Debug.Log("Items");
			Destroy(c.gameObject);
		}
		else if(c.gameObject.name == "Rock(Clone)")
		{
			//Boxes
			logic.CrashMonster();
			Debug.Log("Rock");
			Destroy(c.gameObject);
		} 
}

mobile-game-unity-26

เป็นการทดสอบว่าตัวละครของเรา ชนกับอะไร เช่นถ้าชน Items(Clone) ที่เป็น Prefabs ก็จะเพิ่มจำนวน Score หรือเหรียญ และ ถ้าชน Rock(Clone) ก็จะเป็นลดชีวิต โดยอ้างอิงไปที่ตัวแปร logic ที่เป็นการเรียกไฟล์ GamePlay.js ที่อยู่บน Gamesystem Object

public var logic : GamePlay;

mobile-game-unity-27

ให้ลากเจ้า Game Object ชื่อ Gamesystem ไปวางบนช่อง logic ของ collision ครับตามภาพข้างล่าง

mobile-game-unity-28

ทดสอบลองเล่นเกมดูครับ

mobile-game-unity-30

ถ้าชนหินครบ 3 ครั้งก็ Game Over

mobile-game-unity-31

 

การ Export ตัวเกมของเราไปเป็นไฟล์ apk สำหรับ Android ให้ไปที่เมนู File > Build Setting

mobile-game-unity-34

เลือก Android ตั้งค่า Player Setting พวก Bundle ID สักหน่อยครับ ใส่ Icon ก็ได้

mobile-game-unity-37

 

กด Build รอสักประมาณนึง ระบบจะถามถึง Path ของ Android SDK ถ้ายังไม่มีให้ไปติดตั้งครับถ้ามีแล้วก็น่าจะอยู่ที่

C:\Users\Administrator\AppData\Local\Android\sdk

mobile-game-unity-35

รอสักหน่อยก็จะได้ไฟล์ Apk ออกมาแล้วครับเสียบสาย USB เข้าเครื่องติดตั้ง เกมเราได้เลย

mobile-game-unity-36เอาล่ะทดสอบการติดตั้ง

IMG_5052

IMG_5051

ทดสอบการเล่น

IMG_5053

IMG_5054

เนื่องจากบทเรียนนี้คิดว่าเป็นบทเรียนที่คนจะอ่านต่อนั้นน่าจะมีพื้นฐานมาก่อนพอประมาณ จึงรวบรัด และทำขึ้นแค่ 1 ชั่วโมง ยังไงก่อนจะพัฒนาเกมให้ลองศึกษามาบทเรียนเบื้องต้นก่อนครับ ส่วนบทเรียนนี้เป็นเพียง Guide แบบลัดขั้นตอนไว้แนะนำดีกว่าครับ

Source Code: ติดต่อได้ที่ http://www.facebook.com/daydevthailand
แค่ Source code นะครับไม่มี Assets ให้อันที่จริง พิมพ์ตามก็ไม่มีปัญหาอะไรเลยมั้ง?

Asst. Prof. Banyapon Poolsawas

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

Related Articles

Back to top button
Game & Mobile Development AR VR XR
Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.

Adblock Detected

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