一、新建第一人稱藍圖項目。在場景中隨意選擇一個cube(simulate physics勾選),然后在level blueprint中添加 OnActorHit事件,打印事件,藍圖如下:

對應的Actor如下設置(項目默認,沒做修改):

注意,此時Simulation Generates Hit Events沒有勾選;運行程序后結果如期,子彈擊中該Actor(Name:撞擊時測試對象)觸發OnActorHit事件;

二、再來測試勾選Simulation Generates Hit Events的效果。

此時運行后,在子彈沒有擊中時,也會產生一些hit事件,結果如下圖:

三、總結:1)子彈擊中的過程其實是一個kinematic(運動學)的模擬,而不是物理模擬,打開FirstPersonProjectile藍圖,可以看到如下設置:


運動學方式(官檔所謂kinematic,所謂運動學是經典力學的一個分支,具體參考維基百科,即運動時不考慮物體的質量,慣性……之類)中改變物體(通常就是Actor,即Actor的RootComponent)的空間位置時,使用SetActorLocation或者通過組件設置運動速度(其實,最終結果也是使用SetActorLocation系列函數),指定Sweep有效(Enabled),如果與物體發生碰撞(collide)時,觸發OnActorHit事件(或者OnComponentHit,如果是在組件級別上設置碰撞事件),與是否勾選Simulation Generates Hit Events 無關。這也就是所謂的Query方式。(后記,運動學方式大致算法是物理移動到一個指定位置時(使用SetActorLocation系列函數),不能盲目的移動到用戶指定的位置,大致分成二個階段:1,掃描(sweep),如果當前位置到目標位置之間有障礙(obstacle),則不能移動到目標位置,要判定碰撞發生時的位置和矢量……等一系列參數(想不出來更恰當的描述),這也是FHitResult之類的參數存在的意義,2、然后根據碰撞表(其實這一步我們可以控制,例如官網教程中控制pawn沿桌子邊沿滑動的例子)進行響應。當然如果不發生上述事件(前進道路無障礙),則如用戶意愿,把Actor移動到指定位置。
2)如果勾選Simulation Generates Hit Events,則如文檔所述,利用PhysX(Nvidia PhysX SDK)進行物理的模擬,這沒什么好講的,主要是此時如果物體與別的物體發生接觸(contact),就會觸發這個事件。這個行為不是UE的,應該是PhysX模擬的結果,對于PhysX的研究,留待后續……,唔,10M的文檔,想想頭痛。
三、2017年3月20日進一步的測試與總結(cnblogs吃了我的文章,沒心情寫了,簡單總結,有心情再細寫):
OnComponentHit是事件的發起者,它調用NotifyActor,NotifyActor隨之廣播(broadcast)OnActorHit,所以這三個事件是一體俱榮的。另外,對于委托,一定要加UFUNCTION函數修飾符,不能在同一個地方再次栽跟頭了,愚蠢……!
1、在打開物理模擬過程前提下(非kinematic),如果打開Simulation Generates Hit Events, 在模擬過程中,如果由于物理模擬產生了碰撞,就會觸發上述三個事件。如果關閉Simulation Generates Hit Events,則不會觸發上述三個事件。但是注意一定是由于物理模擬產生的碰撞。
2、對于kinematic方式,即關閉物理模擬時,Simulation Generates Hit Events不起任何作用,這點在文檔中已經指出。
3、對于kinematic方式,上述三個事件,只受collision enabled中的Query選項是否打開影響,如果打開就會觸發,否則不受影響。
浙公網安備 33010602011771號