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

Adblock Detected

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