[Unity3D] การควบคุม Player

1. เตรียมโปรเจ็กส์
2. ควบคุม Player ด้วย Keyboard
3. ควบคุม Player ด้วย Accelerator
4. ควบคุม Player ด้วย Touch

1. เตรียมโปรเจ็กส์

สร้างโปรเจ็กส์

  • สร้างโปรเจ็กส์ชื่อ Player Controller

สร้างโฟลเดอร์

  • สร้างโฟลเดอร์ชื่อ Scene
  • สร้างโฟลเดอร์ชื่อ Material
  • สร้างโฟลเดอร์ชื่อ Script

สร้าง Scene

  • ที่โฟลเดอร์ Scene ให้สร้าง Scene ขึ้นมาชื่อ MainScene

 

ที่ MainScene ให้สร้าง Plane1

  • Create > 3D Object > Plane
  • Rename to Plane1
  • Reset Transform
  • Scale = 2, 1, 2
  • ที่ โฟลเดอร์ Material สร้าง Material ชื่อ Plane1
  • ที่ Material > Plane1 กำหนดให้ Color = 40, 130, 120
  • ผูก Material > Plane1 กับ Plane1

 

ที่ MainScene ให้สร้าง Walls

  • สร้าง GameObject ใหม่ เป็น Create Empty
  • เปลี่ยนชื่อเป็น Walls
  • Reset Transform ของ Walls
  • สร้างผนังสี่ด้าน
  • สร้าง Cube ชื่อ West Wall เป็นลูกของ Walls
    • Position = -10, 0, 0
    • Scale = 0.5, 1, 20.5
  • สร้าง Cube ชื่อ East Wall เป็นลูกของ Walls
    • Position = 10, 0, 0
    • Scale = 0.5, 1, 20.5
  • สร้าง Cube ชื่อ North Wall เป็นลูกของ Walls
    • Position = 0, 0, 10
    • Scale = 20.5, 1, 0.5
  • สร้าง Cube ชื่อ South Wall เป็นลูกของ Walls
    • Position = 0, 0, -10
    • Scale = 20.5, 1, 0.5

 

ที่ MainScene ให้สร้าง Player

  • Create > 3D Object > Sphere
  • Rename to Player
  • Reset Transform
  • Position = 0, 0.5, 0
  • ใส่ Rigidbody ให้ Player (Add Component > Physic > Rigidbody)
  • ที่ โฟลเดอร์ Material สร้าง Material ชื่อ Player
  • ที่ Material > Player กำหนดให้ Color = 0, 140, 255
  • ผูก Material > Player กับ Player

 

ให้กล้องเคลื่อนที่ตาม Player
ที่ Main Camera ให้

  • Position = 0, 10, -10
  • Rotation = 40, 0, 0
  • Projection = Perspective
  • Add Component > New Script ชื่อ CameraController
  • ลาก CameraController ไปไว้ในโฟลเดอร์ Script
  • แก้ไขโค๊ด CameraController

สคริป CameraController

[code language=”csharp”]
using UnityEngine;
using System.Collections;

public class CameraController : MonoBehaviour {
public GameObject player;
private Vector3 offset;

// Use this for initialization
void Start()
{
offset = transform.position – player.transform.position;
}

void LateUpdate()
{
transform.position = player.transform.position + offset;
}
}
[/code]

ที่ CameraController

  • ให้ลาก Player มาวางที่สคริป CameraController > Player

2. ควบคุม Player ด้วย Keyboard

ที่ Player

  • Add Component > New Script ชื่อ PlayerController
  • ลาก PlayerController ไปไว้ในโฟลเดอร์ Script
  • แก้ไขโค๊ด PlayerController

สคริป PlayerController

[code language=”csharp”]
using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour
{
public int speed = 10;

private Rigidbody rb;

void Start()
{
rb = GetComponent<Rigidbody>();
}

void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
rb.AddForce(movement * speed);
//rb.velocity = movement * speed;
}
}
[/code]

  • ควบคุม Player ด้วย Keyboard ได้ละ

 

3. ควบคุม Player ด้วย Accelerator

เปลี่ยน Platform เป็น Android

  • ไปที่ File > Build Settings…
  • เปลี่ยน Platform เป็น Android
  • แล้วกด Switch Platform
  • ให้สังเกตว่าโลโก้ Unity ย้ายมาอยู่ที่ท้าย Android เป็นอันใช้ได้

unity_build_setting_android

  • ไปที่เมนู Edit > Project Settings > Player
  • ที่ PlayerSettings
    • ใส่ Company Name
    • ใส่ Other Settings > Identification > Package Name

ที่ Main Camera ให้

  • Position = 0, 15, -15
  • Rotation = 50, 0, 0

ที่ Player ให้

  • แก้ไขโค๊ด PlayerController

สคริป PlayerController

[code language=”csharp”]
using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour
{
public int speed = 10;

private Rigidbody rb;

void Start()
{
rb = GetComponent<Rigidbody>();
}

void FixedUpdate()
{
Vector3 acceleration = Input.acceleration;
Vector3 movement = new Vector3(acceleration.x, 0.0f, acceleration.y);
rb.AddForce(movement * speed);
}
}
[/code]

  • ตอนรันให้วางมือถือในแนวราบ แล้วเอียงมือถือเพื่อควบคุมการเคลื่อนที่ของ Player

 

  • แต่ถ้าไม่ต้องการถือมือถือในแนวราบ ให้ทำกำร Calibrate ตำแหน่งเริ่มต้นตอนผู้ใช้เริ่มเล่น

ที่ PlayerController ให้

  • แก้ไขโค๊ด PlayerController

สคริป PlayerController

[code language=”csharp”]
using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour
{
public int speed = 10;

private Rigidbody rb;
private Quaternion calibrationQuaternion;

void Start()
{
rb = GetComponent<Rigidbody>();
CalibrateAccelerometer();
}

void FixedUpdate()
{
Vector3 accelerationRaw = Input.acceleration;
Vector3 acceleration = FixAcceleration(accelerationRaw);
Vector3 movement = new Vector3(acceleration.x, 0.0f, acceleration.y);
rb.AddForce(movement * speed);
}

void CalibrateAccelerometer()
{
Vector3 accelerationSnapshot = Input.acceleration;
Quaternion rotateQuaternion = Quaternion.FromToRotation(new Vector3(0.0f, 0.0f, -1.0f), accelerationSnapshot);
calibrationQuaternion = Quaternion.Inverse(rotateQuaternion);
}

Vector3 FixAcceleration(Vector3 acceleration)
{
Vector3 fixedAcceleration = calibrationQuaternion * acceleration;
return fixedAcceleration;
}
}
[/code]

 

4. ควบคุม Player ด้วย Touch

สร้าง Movement Zone

  • ที่ Scene View ปรับเป็น 2D
  • Create -> UI -> Image
  • เปลี่ยนชื่อเป็น Movement Zone
  • ที่ Movement Zone ให้ Anchor Presets ย้ายตำแหน่ง (กด Alt) ไปที่มุมล่างขวา
  • ปรับ Anchors (Anchor เอาไว้เป็น Guild line ในการปรับ Movement Zone)
    • Min x=0.5, y=0
    • Max x=1 และ y=0.35
  • ลากปรับ Movement Zone ให้เต็มพื้นที่ของ Anchors
  • เปิดที่ Game View จะเห็น Movement Zone สีขาวทับกับ Player ของเรา
  • ที่ Color ลองปรับ Alpha ดูจะเห็น Movement Zone จางลงได้
  • ให้ปรับ Alpha จนหายไป

เลือกที่ EventSystem

  • เพิ่ม Touch Input Module
  • Add Component -> Event -> Touch Input Module

เลือกที่ Movement Zone

  • สร้างสคริปใหม่ชื่อ SimpleTouchPad
  • ลาก SimpleTouchPad ไปไว้ในโฟลเดอร์ Script
  • แก้ไข้สคลิป SimpleTouchPad

สคลิป SimpleTouchPad

[code language=”csharp”]
using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections;

public class SimpleTouchPad : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
public float smoothing = 0.1f;
private Vector2 origin;
private Vector2 direction;
private Vector2 smoothDirection;

void Awake()
{
// Shorthand for writing Vector2(0, 0).
direction = Vector2.zero;
}

public void OnPointerDown(PointerEventData data)
{
// Set our start point
origin = data.position;
}

public void OnDrag(PointerEventData data)
{
// Compare the different between our start point and current point position
Vector2 currenPositin = data.position;
Vector2 directionRaw = currenPositin – origin;
//Turns the current vector into a unit vector.
//The result is a vector one unit in length pointing
// in the same direction as the original vector.
direction = directionRaw.normalized;
//Debug.Log(direction);
}

public void OnPointerUp(PointerEventData data)
{
// Reset everything
direction = Vector2.zero;
}

public Vector2 GetDirection()
{
smoothDirection = Vector2.MoveTowards(smoothDirection, direction, smoothing);
return smoothDirection;
}
}
[/code]

  • ตัวแปร Smoothing เป็นการควบคุมไม่ให้ Player เคลื่อนที่เร็วเกินไป ซึ่งในที่นี้คือไม่เกิน 0.1
  • ตัวแปร touched ใช้ตรวจสอบว่ามีการสัมผัสแล้วหรือยัง
  • ตัวแปร pointerID ใช้จำนิ้วที่สัมผัสเป็นนิ้วแรก
  • ลองรันดู นิ้วที่สัมผัส Touch Pad ทีหลังจะควบคุม Player ไม่ได้

สคลิป PlayerController

[code language=”csharp”]
using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour
{
public int speed = 10;
public SimpleTouchPad touchPad;

private Rigidbody rb;

void Start()
{
rb = GetComponent<Rigidbody>();
}

void FixedUpdate()
{
Vector2 direction = touchPad.GetDirection();
Vector3 movement = new Vector3(direction.x, 0.0f, direction.y);
rb.AddForce(movement * speed);
//rb.velocity = movement * speed;
}
}
[/code]

  • ที่ Unity
  • เลือก Player แล้วดูที่ Player Controller (Script)
  • ลาก Movement Zone มาใส่ที่ Touch pad
  • ลองรันดูจะใช้นิ้วควบคุม Player ได้ละ