UE 實現鏡頭平移,旋轉和縮放

0x00 引

在數字孿生三維場景中,通過鍵盤和滑鼠來控制鏡頭的移動,縮放是很常見的行為,也是很必要的行為,用戶正是通過這些操作,達到對整個三維場景的觀看和控制。

0x01 鍵盤控制鏡頭前後左右移動

通常,我們會通過幾個鍵盤來控制鏡頭的移動,比如W向前,S向後,A向左,D向右。
如果是開發過threejs的讀者,可能能夠設想到的思路是這樣的,監聽鍵盤事件,如果是字母W就是把鏡頭的位置和中心點向前移動,其他鍵類似。

不過UE把相關的類似的操作封裝成了新的事件,通過在項目中配置,可以得到相關的事件的映射,如下圖所示,在項目配置中(編輯 -> 項目設置 -> 輸入):

image.png
如上圖所示,W和向上鍵映射了向前的MoveForward事件,S和向下鍵映射了向後MoveForward事件。 因此監聽MoveForward事件即可實現鏡頭的向前、向後移動。 同理監聽MoveRight事件可以實現向右、向左移動。

添加攝影機組件

接著上一篇文章 《UE 實現滑鼠點選模型》,打開A_Pawn藍圖類,添加攝影機組件

image.png

添加完成後如下所示:

image.png

添加完成後,就可以通過對Pawn的控制來達到對鏡頭的控制。因為鏡頭是改Pawn的孩子,Pawn的改變會影帶動鏡頭的變化。

添加”浮動pawn移動”組件

“浮動pawn移動”組件為Pawn類提供了簡單的運動的能力,指定”浮動pawn移動”組件之後,Pawn類就可以被控制移動。

添加”浮動pawn移動”組件:

image.png

添加之後可以看到:

image.png

監聽MoveForward事件實現前後移動

在藍圖中添加MoveForward事件:

image.png

image.png

其中Axis Value表示事件的縮放值(1表示向前,-1表示向後)。監聽到了MoveForward之後,就是控制Pawn的前後移動,通過「添加移動輸入」 可以控制Pawn的移動:

image.png

其中目標是Pawn類,此處使用self即可(Pawn類自身,World Direction表示移動的方向,Scale Value 表示移動的縮放值,一般1表示向前,-1向後,這個正好和前面的Axis Value可以對應。

獲取Pawn自身的旋轉方向作為World Direction的輸入。通過獲取控制旋轉,然後在通過控制旋轉獲取向前的向量獲取Pawn向前的向量。如果你熟悉webgl和threejs,此步驟類似於下面這個函數:

/**
 * 獲取網元的正前方向量
 * @method frontDirection
 * @return {Vec3} 返回網元的正前方向量
 */
frontDirection : function() {
    var n = new $Vec3(0, 0, 1);
    n = n.applyMatrix4(new Mat4().extractRotation(this.matrixWorld));
    n.normalize();
    return n;
},

如下圖所示:

image.png

最終全部的藍圖如下:

image.png

監聽MoveRight事件實現左右移動

這和 「監聽MoveForward事件實現前後移動」類似,此處不在詳細說明,全部藍圖如下:

image.png

0x02 滑鼠移動控制鏡頭旋轉

UE有兩個滑鼠事件「滑鼠X」、「滑鼠Y」分別表示滑鼠X方向和Y方向的移動。

image.png

滑鼠X事件實現鏡頭左右旋轉

在監聽了滑鼠X事件後,需要設置鏡頭的旋轉,通過下面的藍圖節點,可以設置Pawn的旋轉。

image.png

image.png

其中目標是Pawn自己,New Rotation表示要設置的新的旋轉的值,是一個向量,該屬性還可以進行分割成三個分量,x,y,z。之所以要分割是因為我們左右旋轉,只需要改變Z軸方向的旋轉。

image.png

image.png

後續涉及到的分割結構體引腳和此處類似,可能不會在單獨說明。

首先需要獲取原本的旋轉值,然後在原本的旋轉值基礎上,加上一個新的增量。獲取Pawn的旋轉,可以通過「獲取控制旋轉」獲取控制器的當前的旋轉值:

image.png

改節點的目標是控制器,所以需要獲取控制器作為目標的輸入:

image.png

在原來的Z軸旋轉的基礎上,加上一個增量,這個增量就是「滑鼠X」節點的Axis Value,不過一般來說,Axis Value 會比較小,所以還會先乘以一個倍數,把相稱的結果作為增量。把Z軸旋轉添加增量之後的值,賦值給「設置控制旋轉」節點的Z旋轉值。

整體的藍圖流程如下:

image.png

判斷滑鼠是否按下

一般來說,我們要旋轉鏡頭,需要按下滑鼠,然後移動才能旋轉。所以我們需要添加一個條件判斷,首先通過下面的節點,可以判斷滑鼠是否按下:

image.png

其中目標是玩家控制器,所以需要獲取玩家控制器並連接上

image.png

其中的key 設置為滑鼠左鍵,表示判斷滑鼠左鍵的按下情況。該節點也可以判斷其他鍵的按下情況。

然後添加一個條件分支,把上述節點的結果作為條件分支節點的輸入條件:

image.png

整體的藍圖流程如下:

image.png

滑鼠Y事件實現鏡頭上下旋轉

滑鼠Y事件實現鏡頭上下旋轉和「滑鼠X事件實現鏡頭左右旋轉」,此處不再贅述,區別的地方在設置的是X軸的旋轉。
整體的藍圖流程如下。

image.png

0x03 滑鼠滾輪控制鏡頭縮放

實現滾輪縮放,需要使用到 彈簧臂組件。 首先在藍圖的添加一個彈簧臂組件,如下圖所示:

image.png

添加之後的,需要把彈簧臂加做camera的父親,這樣彈簧臂的改變會帶著鏡頭一塊改變:

image.png

彈簧臂組件有一個長度屬性,通過改變這個長度,就能達到伸縮的效果。

首先監聽滑鼠滾輪事件:

image.png

然後設置彈簧臂的長度,可以拖拽彈簧臂組件到藍圖中:

image.png

要設置長度,先要獲取原本的長度,

image.png

最後在原本長度上面增加一個長度,全部的藍圖如下所示:

image.png

0x04

本文講述了通過藍圖實現鏡頭的平移旋轉,旋轉和縮放,涉及到了很多的知識點,需要仔細耐心的查看。

如果你有好的經驗,也歡迎和我交流。關注公號「ITMan彪叔」 可以添加作者微信進行交流,及時收到更多有價值的文章。