Unity

Unity

官方網站:點擊進入
官方粉絲團:點擊進入

《Unity》 鍵盤移動控制 (上)

【Unity】 【鍵盤控制】 【3D】
作者:Jerrard Liu 時間:2015-10-06

原文:Unity - 鍵盤移動控制 - 上 
作者: Jerrard Liu

 

文章標題是在三月底開起來的,想不到一欠就是一個月。
這次主題是人物模型的鍵盤方向以及移動控制,這篇上篇主要是講方向的控制,而移動部分會留在下篇,這次的結果點這裡

首先提一下目標,以攝影機為拍攝方向為中心點,在玩家按下鍵盤W鍵時角色面向前方,按下D角色面向右方,按下S角色面向後方,按下A角色面向左方。
攝影機受mouselook控制會做Y軸的旋轉,當攝影機拍攝方向改變時,按下WASD後角色方向會與攝影機座標一致,也就是說不會有按下W角色卻面向左方或後方的情況。

在方向的控制上採用Unity官方提供的方法:
http://docs.unity3d.com/ScriptReference/Vector3.RotateTowards.html

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    public Transform target;
    public float speed;
    void Update() {
        Vector3 targetDir = target.position - transform.position;////(1)
        float step = speed * Time.deltaTime;////(2)
        Vector3 newDir = Vector3.RotateTowards(transform.forward, targetDir, step, 0.0F);////(3)
        Debug.DrawRay(transform.position, newDir, Color.red);
        transform.rotation = Quaternion.LookRotation(newDir);////(4)
    }
}

(1)腳本中target為要朝向的目標物體座標,透過target座標減去人物模型座標後算出向量。
(2)step是控制旋轉速度,透過speed乘上Time.deltaTime計算才不會有效能影響速度的問題。
(3)利用Vector3.RotateTowards計算兩向量之間的角度newDir
,兩向量為人物模型前方向量transform.forward和(1)的向量(附註:計算出來的角度會依step值切出等分)。
(4)角度算出來後用Quaternion.LookRotation做旋轉,執行到transform.forward和targetDir相等為止,也就是人物模型朝向物體為止。

把基礎概念提完後回到我們要做的內容:
準備所需要的人物模型,接著新增物件model(在這裡是用cube再把render隱藏),把人物模型加到物件model之下,這麼做的原因是人物模型中心位置會隨著動畫播放或是物理模擬不斷的改變。
《Unity》 鍵盤移動控制 (上)

新增作為目標物的四個物件,分別放到人物前後左右四個位置。
《Unity》 鍵盤移動控制 (上)

以人物模型為中心點新增物件CameraTarget(在這裡同樣是用cube再把render隱藏),將攝影機和四個目標物加到CameraTarget之下
加入MouseLook.cs在CameraTarget上,MouseLook.cs可以在右鍵->Import Package->Character Controllers下找到,最後修改MouseLook.cs的參數
《Unity》 鍵盤移動控制 (上)

修改值有兩個sensitivityX和Axes,sensitivityX要把數值條小才不會移動得太快,Axes修改成Mouse X,這裡先只做Y軸的旋轉。

最後回到model物件上,新增腳本(eightDirectionControl.cs),一開始是預定做八方向,這次就先前後左右四方向。
using UnityEngine;
using System.Collections;
public class eightDirectionControl : MonoBehaviour {
        public GameObject model;
        private Animator animator;
        public GameObject [] target = new GameObject[8];
        public float speed;
        void Start () {
                animator = model.GetComponent<Animator> ();
        }

        void Update () {
                animator.SetBool("RunState",false);////(1)
                if(Input.GetKey(KeyCode.W)){////(2)
                        Vector3 targetDir = target[0].transform.position - transform.position;
                        float step = speed * Time.deltaTime;
                        Vector3 newDir = Vector3.RotateTowards(transform.forward, targetDir, step, 0.0F);
                        transform.rotation = Quaternion.LookRotation(newDir);
                        animator.SetBool("RunState",true);////(1)
                }
                else if(Input.GetKey(KeyCode.S)){////(2)

                        Vector3 targetDir = target[4].transform.position - transform.position;
                        float step = speed * Time.deltaTime;
                        Vector3 newDir = Vector3.RotateTowards(transform.forward, targetDir, step, 0.0F);
                        transform.rotation = Quaternion.LookRotation(newDir);
                        animator.SetBool("RunState",true);
                }
                else if(Input.GetKey(KeyCode.A)){////(2)

                        Vector3 targetDir = target[6].transform.position - transform.position;
                        float step = speed * Time.deltaTime;
                        Vector3 newDir = Vector3.RotateTowards(transform.forward, targetDir, step, 0.0F);
                        transform.rotation = Quaternion.LookRotation(newDir);
                        animator.SetBool("RunState",true);
                }
                else if(Input.GetKey(KeyCode.D)){////(2)

                        Vector3 targetDir = target[2].transform.position - transform.position;
                        float step = speed * Time.deltaTime;
                        Vector3 newDir = Vector3.RotateTowards(transform.forward, targetDir, step, 0.0F);
                        transform.rotation = Quaternion.LookRotation(newDir);
                        animator.SetBool("RunState",true);
                }
        }
}

(1)模型的動畫檔切換用RunState布林變數控制,在按下方向鍵切換成true也就是跑步動作,平常是false是待機動作,以下是動畫animator設定。
 
《Unity》 鍵盤移動控制 (上)

準備好待機和移動動畫,用右鍵make transition連結兩個動畫檔,新增布林變數RunState,用滑鼠點擊兩個白色連結部分,在右邊視窗將切換條件設為RunState分別為true和false。

(2)四個if條件當輸入WASD分別將轉向目標物,內容就和上面提到的大同小異,在執行前記得把物件拉到對應的變數上,包含人物模型檔和目標物
《Unity》 鍵盤移動控制 (上)

做到這裡就完成第一部分方向的控制,移動就留到下篇。


《Unity》 鍵盤移動控制 (上)

模型素材:結月ゆかりVer3.5 https://bowlroll.net/file/6518 by お宮

※其他相關資訊:
《Unity》 鍵盤移動控制 (下)

 


x