開發遊戲時,像是射擊判定、角色與身旁物體的檢測等功能,一定會用到射線檢測,在Unity中可以使用Physics.Raycast()系列方法來完成,而Unreal中則是使用LineTrace系列方法。

LineTrace有分為LineTraceSingle與LineTraceMulti,顧名思義,就是這條射線可以檢測單個還是多個物體。
另外LineTrace還可以根據Object Type、Channel、Profile來指定要檢測哪些物體。
今天要記錄的是LineTraceSingleByChannel的使用,想做的效果是模擬子彈射擊。

新增Trace Channel

首先先到Project Settings > Engine > Collision > Trace Channels新增一個Trace Channel叫做Bullet,Defualt Response設為Block。

然後修改下面Preset的NoCollsion與OverlapAll與Bullet的Collsion Response。

射線判定

Unreal中,射線與物體的碰撞判定的過程大概是這樣子的:

  1. 先指定射線的Trace Channel
  2. 然後射線會在給定的起始位置到結束位置中的物體做碰撞檢測
  3. 射線會根據自己的Trace Channel與被擊中的物體的Collsion Preset判斷Collsion Response
  4. 最後回傳FHitResult,包含擊中的物體、位置等資訊

Collsion Response有3種Block、Overlap、Ignore。

  • Block:阻擋射線(射線不能再往後面檢測了),並記錄這個物體資訊
  • Overlap:不阻擋射線(射線還可以再往後面檢測),並記錄這個物體資訊
  • Ignore:完全忽略這個物體

C++

LineTraceSingleByChannel()方法是UWorld提供的,因此可以使用GetWorld()得到當前的UWorld物件後,呼叫LineTraceSingleByChannel,並傳入一個FHitResult作為回傳的資訊,一個射線起始位置的FVector,一個射線結束位置的FVector,最後是這個射線的Trace Channel。

1
2
3
4
FVector StartPoint;    // 開始位置
FVector EndPoint; // 結束位置
FHitResult Hit; // 回傳的碰撞結果
bool bHit = GetWorld()->LineTraceSingleByChannel(Hit, StartPoint, EndPoint, ECC_GameTraceChannel1);

最後面的這個參數不能直接傳入剛剛新增的Trace Channel的名字Bullet。
而是要先到 專案資料夾 > Config > DefaultEngine.ini中搜尋Bullet,找到ECC_GameTraceChannel1傳入。

這樣就可以使用射線檢測囉!
如果要拿到檢測結果,直接從FHitResult變數Hit裡面找就可以了。

__END__