寫在前面
這裡介紹一下如何為Pawn定制自定義的運動元件。
一、建立一個運動元件C++類
- 需要在Editor中建立類,不要直接Visual Studio中建立;
- Pawn的運動元件繼承自
,需要勾選顯示所有類才能找到;UPawnMovementComponent
- 初始時,頭檔案裡面是什麼都沒有的,如下:
-
的繼承結構是:USlidePawnMovementComponent
-
:最基本的類;UObject
-
:最基本的Component類;UActorComponent
-
:最基本的運動元件類;UMovementComponent
-
;UNavMovementComponent
-
;UPawnMovementComponent
-
;USlidePawnMovementComponent
-
二、實作運動元件的功能
1. 頭檔案
- 為了實作自定義的移動方式,這裡僅需要重寫
函數,如下:TickComponent()
- 這個函數是在
類中定義的,如下:MovementComponent
2. cpp實作
- 為了讓Pawn能夠産生實時的移動,需要在每一幀中為Pawn更新位置,重寫的
函數就是執行每一幀中Component施加給Actor的動作,相當于在Actor中的TickComponent()
函數;void Tick(float DeltaTime)
- 是以,在
函數中需要把從外部裝置輸入的信号施加到Pawn上産生作用效果,實作如下:TickComponent()
- 一些注意的點如下:
- 如果運動元件沒有挂載到某個Pawn上,或者運動元件沒有對應施加運動的元件(預設是根元件),則
不會進行具體的移動;TickComponent()
- 這裡的輸入信号的傳遞用的是生産者-消費者模型,這是因為輸入信号可能是同時發生的,但消費這些信号(也就是實際讓Pawn運動起來)則需要一個個執行,是以用生産者-消費者模型而不是Unreal Engine08:Pawn的實作中的簡單綁定到
變量可以實作異步執行,也降低了輸入和執行之間的耦合性;CurrentVelocity
- 實作Pawn的運動仍然用的是位移 = 速度 * 時間的公式,和之前實作的無異;
- 為了實作Pawn撞向其他物體時的沿表明滑動效果,這也是該自定義運動元件的核心目的,這裡需要調用
函數來實作移動,而不是直接将目前Pawn的位置設定為某個地方;SlideAlongSurface()
- 如果在試算的過程中發生了碰撞,則不會執行真正的移動的;
- 如果運動元件沒有挂載到某個Pawn上,或者運動元件沒有對應施加運動的元件(預設是根元件),則
三、在Pawn中使用自定義運動元件
1. 頭檔案
- 首先在頭檔案中定義運動元件,如下:
- 另外要重寫
函數,因為預設的傳回不是自定義的運動元件;GetMovementComponent()
2. cpp實作
- 首先在構造函數中配置設定對象,如下:
- 另外要為運動元件初始化它所施加運動的元件;
- 這裡是因為Pawn可以有很多元件,是以運動元件需要選其中一個來控制,也就是施加運動的對象不是Pawn而是另一個元件(元件得是
類型才能被施加運動);UScenceComponent
- 然後是重寫
函數,如下:GetMovementComponent()
- 最後是運動元件在響應輸入的函數中被調用,如下:
- 一些注意的地方如下:
- 由于在
函數中已經做了數值截斷和與速度相乘計算位移的操作,是以這裡直接傳數值即可;TickComponent()
- 調用的是
和GetActorForwardVector()
函數,這樣相當于是把GetActorRightVector()
拆開了三個次元分别控制;GetActorLocation()
-
函數實際上是充當了生産者的作用,負責把對應的輸入信号放到隊列中供消費者處理,它的實作在AddMovementInput()
中,如下:Pawn.h
- 由于在
- 注意:
- 這裡調用了重寫的
函數;GetMovementComponent()
- 也調用了自定義元件的預設生産者函數;
- 這裡調用了重寫的
- 這樣無需在Pawn中的
函數裡面寫有關位置的更新,也可以實作Pawn的運動效果;Tick()
- 這當然是推薦的寫法,因為即使不實作自定義的運動元件,UE4也已經提供了預設的運動元件供使用;