Game DevelopmentUnity 3D

Point-Click Movement แบบเกม Diablo ด้วย Mouse บน Unity

บทเรียนแบบสั้นกระชับในการพัฒนาเกมสไตล์ Diablo ที่ใช้ Mouse ในการ Point-Click เพื่อเดินไปตำแหน่งที่คลิกล่าสุดใน Unity 3D 

ก่อนจะศึกษาบทเรียนนี้แนะนำให้ไปอ่านบทเรียนก่อนหน้านี้ก่อนที่: เขียนเกมด้วย Unity3D

ในตัวอย่างนี้จะไปแบบสั้นๆ กระชับคือการควบคุมด้วย Mouse คลิกซ้ายแล้วเดินไปตำแหน่งนั้นๆ เพียงแค่นั้นแต่ก่อนจะเรียนรู้ได้ให้ไปเตรียมพร้อม เรื่องของ Animator Controller และ Mecanim แบบ Humanoid ให้เรียบร้อยตามบทเรียนนี้

  1. เขียนเกม Unity การทำ Humanoid ให้กับ โมเดลตัวละคร 3 มิติ
  2. เขียนเกม 3 มิติด้วย Unity การใช้ Animator Controller

อย่าลืมออกแบบฉาก เริ่มต้นให้วางตัวละครลงไปดังนี้

Screen Shot 2558-12-07 at 11.24.29 PM

Screen Shot 2558-12-07 at 11.23.32 PM

ออกแบบ State ของ animation ผ่าน Animator Controller โดยอ้างอิง Bool ตัวเดียวคือ IsRunning พอครับ

Screen Shot 2558-12-07 at 11.24.36 PM

ต่อจากนั้นให้ เราใส่ component เล่านี้ลงไปที่ตัว Player ให้เรียบร้อย

Screen Shot 2558-12-07 at 11.28.16 PM

อย่าลืมใส่ Tag ชื่อ “MainCamera” ให้กับกล้องของเราใน Hierarchy ด้วยนะครับเพื่อทำ Ray Casting เมื่อเสร็จแล้วไปที่ Player ของเราใส่ C# MoveMentByMouse.csใหม่ลงไปโดยใช้ Code ดังนี้

private Transform GameObjectTransform;
private Vector3 new_des_Position;
private float dest_Distance;
public float speed; 
Animator anim;

เก็บตำแหน่งล่าสุดไว้ที่ new_des_Position พร้อมกับตำแหน่งใหม่ที่ dest_Distance กำหนดค่า Speed มาใหม่ จำค่า transform วัตถุที่จะเคลื่อนที่ (Player) ไว้ใน GameObjectTransform

void Start () {
        GameObjectTransform = transform;    
        new_des_Position = GameObjectTransform.position;
        anim = GetComponent <Animator> ();
        Time.timeScale = 1;
}

สร้าง  anim เรียกใช้งาน Component ของ Animator controller ให้เรียบร้อย พร้อมจำค่าล่าสุดคือตำแหน่งแรก

void Update () {
        dest_Distance = Vector3.Distance(new_des_Position, GameObjectTransform.position);
        if(dest_Distance < .5f){ 
            speed = 0;
        }
        else if(dest_Distance > .5f){    
            speed = 3;
        }

        anim.SetBool ("IsRunning", false);
        if (Input.GetButtonDown ("Fire1")) {
            
            Plane PlanePlayer = new Plane(Vector3.up, GameObjectTransform.position);
            Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);

            float hitdist = 0.0f;
            
            if (PlanePlayer.Raycast(ray, out hitdist)) {
                Vector3 targetPoint = ray.GetPoint(hitdist);
                new_des_Position = ray.GetPoint(hitdist);
                Quaternion tRotate = Quaternion.LookRotation(targetPoint - transform.position);
                GameObjectTransform.rotation = tRotate;
            }
        }else if (Input.GetButtonDown ("Fire1")) {
            
            Plane PlanePlayer = new Plane(Vector3.up, GameObjectTransform.position);
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            float hitdist = 0.0f;
            
            if (PlanePlayer.Raycast(ray, out hitdist)) {
                Vector3 targetPoint = ray.GetPoint(hitdist);
                new_des_Position = ray.GetPoint(hitdist);
                Quaternion tRotate = Quaternion.LookRotation(targetPoint - transform.position);
                GameObjectTransform.rotation = tRotate;
            }
            
        }
        if(dest_Distance > .5f){
            anim.SetBool ("IsRunning", true);
            GameObjectTransform.position = Vector3.MoveTowards(GameObjectTransform.position, new_des_Position, speed * Time.deltaTime);
        }
    }

พิจารณาส่วนของการทำ RayCasting จิ้มที่หน้าจอของเกม เพื่อคำนวณระยะจะอยู่ที่

if (Input.GetButtonDown ("Fire1")) {
            
            Plane PlanePlayer = new Plane(Vector3.up, GameObjectTransform.position);
            Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);

            float hitdist = 0.0f;
            
            if (PlanePlayer.Raycast(ray, out hitdist)) {
                Vector3 targetPoint = ray.GetPoint(hitdist);
                new_des_Position = ray.GetPoint(hitdist);
                Quaternion tRotate = Quaternion.LookRotation(targetPoint - transform.position);
                GameObjectTransform.rotation = tRotate;
            }
        }

ดังนั้นภาพรวมของไฟล์ C# จะเป็นดังนี้

using UnityEngine;
using System.Collections;

public class MoveMentByMouse : MonoBehaviour {
    private Transform GameObjectTransform;
    private Vector3 new_des_Position;
    private float dest_Distance;
    public float speed; 
    Animator anim;

    // Use this for initialization
    void Start () {
        GameObjectTransform = transform;    
        new_des_Position = GameObjectTransform.position;
        anim = GetComponent <Animator> ();
        Time.timeScale = 1;
    }
    
    // Update is called once per frame
    void Update () {
        dest_Distance = Vector3.Distance(new_des_Position, GameObjectTransform.position);
        if(dest_Distance < .5f){ 
            speed = 0;
        }
        else if(dest_Distance > .5f){    
            speed = 3;
        }

        anim.SetBool ("IsRunning", false);
        if (Input.GetButtonDown ("Fire1")) {
            
            Plane PlanePlayer = new Plane(Vector3.up, GameObjectTransform.position);
            Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);

            float hitdist = 0.0f;
            
            if (PlanePlayer.Raycast(ray, out hitdist)) {
                Vector3 targetPoint = ray.GetPoint(hitdist);
                new_des_Position = ray.GetPoint(hitdist);
                Quaternion tRotate = Quaternion.LookRotation(targetPoint - transform.position);
                GameObjectTransform.rotation = tRotate;
            }
        }else if (Input.GetButtonDown ("Fire1")) {
            
            Plane PlanePlayer = new Plane(Vector3.up, GameObjectTransform.position);
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            float hitdist = 0.0f;
            
            if (PlanePlayer.Raycast(ray, out hitdist)) {
                Vector3 targetPoint = ray.GetPoint(hitdist);
                new_des_Position = ray.GetPoint(hitdist);
                Quaternion tRotate = Quaternion.LookRotation(targetPoint - transform.position);
                GameObjectTransform.rotation = tRotate;
            }
            
        }
        if(dest_Distance > .5f){
            anim.SetBool ("IsRunning", true);
            GameObjectTransform.position = Vector3.MoveTowards(GameObjectTransform.position, new_des_Position, speed * Time.deltaTime);
        }
    }
}

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

Screen Shot 2558-12-07 at 11.24.07 PM

Screen Shot 2558-12-07 at 11.24.14 PM

ทดสอบการ Transform ของเกม

Screen Shot 2558-12-07 at 11.27.50 PM

คลิกแล้วก็จะวิ่งไปมาในฉากที่เราสร้าง

Screen Shot 2558-12-07 at 11.23.47 PM

ทดสอบดูวีดีโอ Preview ตัว C# ที่เขียนได้ที่นี่

จะเห็นว่าเป็นตัวอย่างง่ายๆ ไม่ได้ยากเย็นอะไรเลยแม้แต่น้อยในการนำไปใช้สร้างเกม Action RPG แบบ Diablo ที่เป็นมุมมอง Isometric และคลิกไปมาเพื่อต่อสู้ได้แบบไม่ต้องเหนื่อยเปลืองแรงใช่ไหมครับ?

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 ของเรานะครับ, ถือว่าช่วยเหลือกัน