DeveloperFeaturedGame DevelopmentUnity 3DVirtual Reality

ฟังก์ชัน Walk() การเดินหน้าใน VR บน Unity 3D และ CardBoard

จากบทเรียน “สร้าง Virtual Reality บน Google Cardboard ด้วย Unity 3D” ที่แนะนำการสร้าง VR World ไปแล้วรอบนี้เราจะมาทำการเขียนฟังก์ชันการเดินไปข้างหน้า

ให้เราเปิดโครงงานตัวเก่าขึ้นมาครับ

กด Alt ค้างแล้วคลิกที่เลนส์แล้วเลื่อนมุมมอง
กด Alt ค้างแล้วคลิกที่เลนส์แล้วเลื่อนมุมมอง

ให้เรากดที่ GameObject ตัว CardboardMain ก่อนครับ แล้วสร้าง New C# Script ใหม่ขึ้นมาว่า Walk.cs ครับ

        private const int RIGHT_ANGLE = 90; 
	private bool isWalking = false;
	CardboardHead head = null;

	public float speed = 5.0f;
	public bool walkWhenTriggered;
	public bool walkWhenLookDown = true;
	public double thresholdAngle;
	public bool freezeYPosition; 
	public float yOffset;

ตัวแปรที่ประกาศเป็นไว้หลักจะอยู่ที่

public float speed = 5.0f;

เป็นความเร็วในการเดินหน้าของตัวละครในเกมของ VR ครับ (ซึ่งจะเดินโดยอัตโนมัติ) การเดินอัตโนมัติเราจะเช็ตที่

public bool walkWhenLookDown = true;

ส่วน

public bool walkWhenTriggered;

จะเป็นการอีกวิธีคือเมื่อมีการหันหน้าจะหยุดแล้วหันอีกที หรือมีการเคลื่อนไหวซ้ำเล็กๆ น้อยๆจะเดิน (หัน, หัน หรือ ผงกหัวเล็กน้อย)

public double thresholdAngle;
public bool freezeYPosition; 
public float yOffset;

ส่วนขององศาในการเช็คว่า เราจะเดินไปข้างหน้าคือ LookDown ใช้เส้นองศา หรือเส้นขอบฟ้าตรวจสอบ

เขียนตั้งค่า Camera Component ใน Start() ดังนี้

void Start () {
  head = Camera.main.GetComponent<StereoController>().Head;
}

ส่วนของการทำงานเป็นการตรวจ Update() องศา และ State ของการเดิน หรือหยุด ด้วยการเทียบตัวแปรของ lookDown

void Update () 
	{
		if (walkWhenTriggered && !walkWhenLookDown && !walkingPlayer && Cardboard.SDK.CardboardTriggered) 
		{
			walkingPlayer = true;
		} 
		else if (walkWhenTriggered && !walkWhenLookDown && walkingPlayer && Cardboard.SDK.CardboardTriggered) 
		{
			walkingPlayer = false;
		}

		if (walkWhenLookDown && !walkWhenTriggered && !walkingPlayer &&  
		    head.transform.eulerAngles.x >= thresholdAngle && 
		    head.transform.eulerAngles.x <= RIGHT_ANGLE) 
		{
			walkingPlayer = true;
		} 
		else if (walkWhenLookDown && !walkWhenTriggered && walkingPlayer && 
		         (head.transform.eulerAngles.x <= thresholdAngle ||
		 head.transform.eulerAngles.x >= RIGHT_ANGLE)) 
		{
			walkingPlayer = false;
		}
		if (walkWhenLookDown && walkWhenTriggered && !walkingPlayer &&  
		    head.transform.eulerAngles.x >= thresholdAngle && 
		    Cardboard.SDK.CardboardTriggered &&
		    head.transform.eulerAngles.x <= RIGHT_ANGLE) 
		{
			walkingPlayer = true;
		} 
		else if (walkWhenLookDown && walkWhenTriggered && walkingPlayer && 
		         head.transform.eulerAngles.x >= thresholdAngle &&
		         (Cardboard.SDK.CardboardTriggered ||
		 head.transform.eulerAngles.x >= RIGHT_ANGLE)) 
		{
			walkingPlayer = false;
		}
		
		if (walkingPlayer) 
		{
			Vector3 direction = new Vector3(head.transform.forward.x, 0, head.transform.forward.z).normalized * speed * Time.deltaTime;
			Quaternion rotation = Quaternion.Euler(new Vector3(0, -transform.rotation.eulerAngles.y, 0));
			transform.Translate(rotation * direction);
		}
		
		if(freezeYPosition)
		{
			transform.position = new Vector3(transform.position.x, yOffset, transform.position.z);
		}
	}

พิจารณาในส่วนนี้ Trigger จะมีการตรวจสถานะตามนี้ครับ

if (walkWhenTriggered && !walkWhenLookDown && !walkingPlayer && Cardboard.SDK.CardboardTriggered) 
		{
			walkingPlayer = true;
		} 
		else if (walkWhenTriggered && !walkWhenLookDown && walkingPlayer && Cardboard.SDK.CardboardTriggered) 
		{
			walkingPlayer = false;
		}

และ Lookdown ตรวจการเทียบการก้มหน้า กับองศาตามนี้

if (walkWhenLookDown && !walkWhenTriggered && !walkingPlayer &&  
		    head.transform.eulerAngles.x >= thresholdAngle && 
		    head.transform.eulerAngles.x <= RIGHT_ANGLE) 
		{
			walkingPlayer = true;
		} 
		else if (walkWhenLookDown && !walkWhenTriggered && walkingPlayer && 
		         (head.transform.eulerAngles.x <= thresholdAngle ||
		 head.transform.eulerAngles.x >= RIGHT_ANGLE)) 
		{
			walkingPlayer = false;
		}
		if (walkWhenLookDown && walkWhenTriggered && !walkingPlayer &&  
		    head.transform.eulerAngles.x >= thresholdAngle && 
		    Cardboard.SDK.CardboardTriggered &&
		    head.transform.eulerAngles.x <= RIGHT_ANGLE) 
		{
			walkingPlayer = true;
		} 
		else if (walkWhenLookDown && walkWhenTriggered && walkingPlayer && 
		         head.transform.eulerAngles.x >= thresholdAngle &&
		         (Cardboard.SDK.CardboardTriggered ||
		 head.transform.eulerAngles.x >= RIGHT_ANGLE)) 
		{
			walkingPlayer = false;
		}

ทดสอบเล็กน้อย

unity-VR-9

แบบอัดหน้าจอไว้ให้

น่าจะใช้สร้างเกม VR ได้ละ – Project ต่อไปทดสอบ Trigger เกม สยองขวัญ ตกใจกรี๊ดกร๊าดดดด

Ref: Jupp Otto, 
"Autowalk Script for the Google Cardboard Unity SDK",สืบค้นเมื่อ 07/2015

Asst. Prof. Banyapon Poolsawas

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

Related Articles

Back to top button

Adblock Detected

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