主要實現
主要是兩點
一個是Dash的實現效果,一種是直接Dash到目的地,第二種則是在Dash過程中實現動畫的播放顯示
第二點則是障礙物的檢測,對Dash的一個阻擋效果的實現
Dash實現效果
為了實現Dash過程中的動畫顯示,可以利用時間軸元件實現Location的移動,從而避免直接對角色的Location的瞬移。
首先對於時間軸在C++中的使用,主要就是利用時間軸元件然後利用委託實現時間軸曲線的資料傳輸
在UpdateLoc裡面,透過時間軸曲線輸出的值進行lerp在兩個值之間的插值得到較為平滑的過渡
SetActorLocation(
UKismetMathLibrary::VLerp(DashStartLocation, DashEndLocation, time),
false,
nullptr,
ETeleportType::TeleportPhysics
);
其次對於時間軸的播放速度應當和Montage播放速度差不多,可以設定一個變數DashDuration來控制變化速率,透過設定PlayRate為時間軸長度或者Montage播放時間 / DashDuration來控制播放時間和效果展示
障礙物檢測
- 障礙物檢測得到的是最終有效的EndLocation,原理就是利用CapsuleComponent的尺寸來對路徑上存在多少個有效位置然後對每個位置進行碰撞檢測。
對於每個位置的檢測一般是採用倒序,即從最遠端可到達點直到起點。對於當前位置的檢測採用UKismetSystemLibrary::CapsuleTraceMultiForObjects進行檢測可以獲得該位置上Capsule會發生碰撞的檢測。
//可以檢測的物體引數
TArray<TEnumAsByte<EObjectTypeQuery>> ObjectTypes;
ObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_WorldStatic));
ObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_WorldDynamic));
ObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_Pawn));
ObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_Vehicle));
ObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_Destructible));
//控制Capsule的位置
FVector CurrentCapsuleLoc = Start + CapsuleDiameter * (CapsuleCount - i) * Direction;
- 對於每一個Capsule檢測結果再進一步進行碰撞通道的檢測,這樣可以排除哪些可以破壞的物品對人物的阻擋。
首先就是對當前Capsule的位置是否是在地面之上,然後對於Capsule的檢測結果分析檢測Component的CollisionResponse
//檢測是否在地面上
bool bIsFloor = UKismetSystemLibrary::LineTraceSingle(
GetWorld(),
Location,
Location - FVector{0.0f, 0.0f, 500.0f},
ETTQ,
false,
TArray<AActor*>{},
EDrawDebugTrace::None,
EndHitRes,
true
);
//判斷Capsule的檢測結果是否有發生阻礙的障礙物
for (auto& hit : HitRes)
{
if (hit.Component->GetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn) == ECollisionResponse::ECR_Block)
{
return false;
}
}
Dash方向的控制
一般是透過判斷LastInputVector是否是空值,如果為空那麼就為呼叫ForwardVector
FVector DirVector = GetLastMovementInputVector() == FVector{0.0f, 0.0f, 0.0f} ? GetActorForwardVector() : GetLastMovementInputVector();
Dash次數和冷卻
每次實現Dash之前先判斷是否有有效的Dash次數以及是否正在Dash,而當此次Dash開始後可以呼叫Delay函式實現CoolDown
當一次時間軸動畫播放完成後需要將正在Dash置為false,方便下一次呼叫