創作內容

33 GP

[Unity3D技術區]環繞攝影機x角色方向

作者:節操君│2015-11-15 17:54:57│巴幣:102│人氣:12264
使用環繞攝影機時角色的方向控制

環繞攝影機的部分可以參照之前寫的[Unity3D技術區]基本第三人稱環繞攝影機教學,這篇是要講解怎麼去定義當前攝影機方向來判別角色的移動方向。

先講這篇要呈現的效果
1.角色會依照當前攝影機的方向去定義玩家按下WASD時所移動的方向
2.角色的Smooth旋轉
這種移動方式很多ARPG都是使用這種移動方式,例如瑪奇英雄傳黑暗靈魂巫師系列等等,做這種效果其實就是很簡單一個要點,只要能掌握當前攝影機面對的方向這個數據就好很做了~



獲取攝影機面對方向的向量

首先我們先認識一個單字"forward",這是泛指前方的意思,在unity裡面的Transform類裡面可以找到這個Transform.forward,這個變數是獲取當前物件的前方向量(長度1)




簡單來說Forward就是Unity內你選擇一個物件後,3個方向箭頭的Z軸(藍色)那個方向就是你的Forward,這個參數剛好就是我們可以拿來獲取攝影機的前方向量!

但能否直接取得攝影機的forward資訊拿來當角色移動方向?
答案是不行!直接取主攝影機的forward會變成有X軸的問題,如果你的攝影機是30度斜著看你的角色,那你這時候的forward就會是向下斜30度的向量,如果直接套用這個數據去移動角色,角色就會往下移動!


這種作法不是說不行,如果你是要做空戰那種類型的可以用這種模式,但是如果你是要做角色在地面的就要注意這點!

為了解決這個問題,我這邊用的方法是生成一個空的物件,讓該物件的旋轉的Y軸跟主攝影機的Y軸同步,之後直接取生成出來的那個物件.transform.forward即可獲得攝影機的前方向量,並且不會受到X軸影響的forward!



將這支程式掛在主角身上,這樣就會在遊戲開始時就會生成一個CameraDir的空物件在角色裡面



這個物件會不斷更新Y軸旋轉,跟主攝影機的Y軸旋轉同步,接著只要取到這個物件的Forward就會是我們角色要移動的方向!




角色移動方向的問題就這樣解決啦~~~
這問題的解法有很多種,我這只是其中一種方式,可能也有比較快速的方式可以解決這問題,可以去找看看來交流一下



角色的Smooth旋轉

接著來說明一下角色旋轉的部分,上面的處理方式只是讓角色移動,並沒有做到角色旋轉,如果你是使用RootMotion動畫製作的話甚至不用上面的步驟,直接實作角色旋轉的部分就能達到移動效果

首先我們先認識一個函式Mathf.SmoothDampAngle,這個函式給他一個當前值和目標值,他會依據SmoothTime去做平滑,並且這個是適用角度的,如果你給他350要Shooth到0,他實際上去跑會是-10~0而不是350~0,因此就不會產生角色旋轉時會轉一大圈的問題。

首先我們先在上面角色移動那程式裡面加一個函式




這個函式需要傳入一個目標角度,之後他會改變自身的旋轉,X和Z旋轉都為0,Y軸則是使用Mathf.SmoothDampAngle去平滑他的旋轉。

接著我們只要將這個函式套入每個方向的移動處理裡面即可






大致上角色移動方向和攝影機的關係處理就是這樣~如果有任何問題歡迎在下方留言

下回合預計寫"使用Mecanim控制角色動畫"
結束這回合
引用網址:https://home.gamer.com.tw/TrackBack.php?sn=3017897
All rights reserved. 版權所有,保留一切權利

相關創作

同標籤作品搜尋:Unity|Unity3D|自製|自製遊戲

留言共 14 篇留言

悠浪貓
直接把取出來的forward向量, 把不必要的那個軸向歸零
然後再做一次 Normalize() 應該就可以了吧? [e1]

Vector3 vecForward = Camera.main.transform.forward;
vecForward.y = 0.0f;
vecForward.Normalize(); << 這個 0w0?

11-15 18:35

節操君
對耶~這招也可以[e17]
好像還有另一種方式是
Quaternion.Euler(mainCameraTran.eulerAngles) * transform.forward
這樣也可以算出相對於攝影機的方向
總之這解法好像很多XD11-15 18:48
新手方
小的是使用官方的GetAxis取得V和H後進行運算,算出方向後角色往前並撥放前進動畫

明明功能差不多。程式碼的複雜度硬生生高了一階......

我還得好好跟您學習才是呢

11-15 23:04

T-LUN
很期待下回解說!

11-22 15:43

群星舞
請問要怎麼才可以移動8個方向@@?

03-26 00:27

節操君
斜著的一棟只要判定2個按鍵成立就可以了
重點會在給予的速度向量,如果說我要往右前方移動,那給予的向量是要給(forward+right) * 0.7
這個算法比較簡單一點,出來的移動速度會跟純方向的速度會有些微的差異,*0.7是我測試感覺比較相近的值03-26 21:20
JRc哈比
請問 發生NullReferenceException: Object reference not set to an instance of an object問題時該如何解決呢? 點了它後事指向charCtrl.Move(moveVector*Time.deltaTime);這一句

06-11 04:52

節操君
應該是charCtrl這個參數沒有給予值,剛剛檢查一下我好像忘了寫上去[e26]
可以在Start函式裡寫 charCtrl = GetConponent<CharacterController>();
06-11 12:34
島瓜吉
你好,我有試著用你的方式練習看看第三人稱移動
可是會一直跑出
there is no 'charactercontroller' attached to the "cube" game object, but a script is trying to access it.
的錯誤訊息

已經有照你樓上說的在void Start()裡頭加上charCtrl = GetConponent<CharacterController>();

好像還是讀取不到參數的樣子@@?
按WASD旋轉和攝影機環繞沒有問題,可是角色就是無法移動
有檢查過程式有沒有打錯好像也沒漏打Orz

02-24 12:34

節操君
你的角色物件身上有CharacterController組件嗎?02-26 01:26
島瓜吉
啊啊....真對不起...我一直以為我套CharacterController上去了還檢查了整整一天
耍蠢了抱歉,感謝感謝XDDD

02-27 13:49

廢物敗類窩囊廢麥可
大大好,剛好專題要做遊戲,
想請問{System.NullReferenceException}
在這行mainCameraTran = Camera.main.gameObject.transform;
請問是甚麼問題啊?
研究很久都沒有抓出問題..

08-02 01:51

節操君
這很久以前的語法了不知道現在新版本還能不能用
mainCameraTran 主要是抓主攝影機的座標數據,不一定要用我的Camera.main去抓,用自己的方式抓也可以08-02 20:43
少佐
大大你好,前幾天我在板上問問題有其他大大給了你這個方法讓我參考,但我現在全部照你的方式打好後,執行時整個畫面會一直震動,有點類似跳針的狀況,請問這個問題該怎麼解決?

08-10 20:06

節操君
你好,方便的話可以上傳個影片看看,這樣敘述真的不知道是甚麼問題08-11 13:59
少佐
https://drive.google.com/open?id=1Yg5eBOQb3BryUn-GxK8sKgNnq9lhnt9d
我上傳到雲端,請你看看這樣開得起來嗎?因為我還不會用youtube傳影片,影片開頭我分別按了WASD,但人物轉向順序分別為ASDW,這是問題一,然後問題二就是我上一個留言問的了,拜託大大幫忙了

08-12 13:58

節操君
首先是旋轉方向錯誤的問題,你可能先檢查一下Code的角度有沒有Key對,其次檢查一下cameraDir這個物件的旋轉方向不是正常08-12 14:15
節操君
第二個抖動的問題,看影片看不出來是什麼原因
建議要查問題點要先讓環境單純一點,例如說腳色先不要有動畫,甚至只拿一個Cube當角色,然後角色身上的Component不要多,只要把我這支程式需要的Component掛上去就好,不要多掛,這樣就能檢測到底是程式碼的問題還是你原本角色Compoment的問題08-12 14:18
節操君
我有注意到影片內的Player程式有吃到Rigidbody,在我印象裡CharacterContorller和Rigidbody是會相衝的,有可能是造成抖動的問題08-12 14:19
少佐
我剛剛照大大的建議做測試,的確是Rigidbody與CharacterContorller並存產生抖動的問題,我之後再找用CharacterContorller作跳躍動作的方法就可以換掉Rigidbody以解決問題。但我旋轉的問題我看了Code都一樣,而cameraDir的旋轉方向則是我在WASD之間切換的時候他會轉一下然後回到原位,不知道這樣是正常的嗎?

08-12 19:30

daidaili
請問一下 腳色控制器 那邊Parameters的參數 要加那些? 抱歉我剛踏入unity這個領域

10-19 14:47

daidaili
public class skull : MonoBehaviour {
public Animator anim;
public int state=0;
// Use this for initialization
void Start () {
anim = GetComponent<Animator> ();
}

// Update is called once per frame
void Update () {
if(Input.GetKey(KeyCode.W)){
state=1;
}
else{
state=0;
}
anim.SetInteger ("state", state);
transform.Translate (0, 0, Input.GetAxis ("Vertical") * Time.deltaTime * 20);
transform.Rotate (0, Input.GetAxis ("Horizontal") * Time.deltaTime * 50,0);
}
}


我之前是用這個 不知道如何整合再一起

10-19 15:14

風流無名
不好意思 我有看不懂你的描述
第一支程式是掛在空物件 然後再把空物件掛到角色模組上吧
那第二個程式是要再創一個腳本嗎?是要掛在角色還是空物件上?

08-23 18:05

我要留言提醒:您尚未登入,請先登入再留言

33喜歡★d82519 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:[MMDxUnity]M... 後一篇:[UE4]Lightin...

追蹤私訊切換新版閱覽

作品資料夾

Ander1119son大家
各位,歡迎來看看我所寫的輕小說《為了復仇的我 轉生成為了Bxxch?!》謝謝各位!看更多我要大聲說3小時前


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】