SpringArmComponent
工作原理
SpringArmComponent是常用的相機輔助元件,主要作用是快速實作第三人稱視角(包括相機避障等功能)
核心函數是UpdateDesiredArmLocation,注冊時和每幀都會調用該函數來計算相機位置
void USpringArmComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
UpdateDesiredArmLocation(bDoCollisionTest, bEnableCameraLag, bEnableCameraRotationLag, DeltaTime);
}
具體位置更新是通過将計算後将結果寫入RelativeSocketLocation和RelativeSocketRotation,通過重載GetSocketTransform和調用UpdateChildTransform(Child就是Camera)來實作相機位置更新
void USpringArmComponent::UpdateDesiredArmLocation(bool bDoTrace, bool bDoLocationLag, bool bDoRotationLag, float DeltaTime)
{
......
// Form a transform for new world transform for camera
FTransform WorldCamTM(DesiredRot, ResultLoc);
// Convert to relative to component
FTransform RelCamTM = WorldCamTM.GetRelativeTransform(GetComponentTransform());
// Update socket location/rotation
RelativeSocketLocation = RelCamTM.GetLocation();
RelativeSocketRotation = RelCamTM.GetRotation();
UpdateChildTransforms();
}
FTransform USpringArmComponent::GetSocketTransform(FName InSocketName, ERelativeTransformSpace TransformSpace) const
{
FTransform RelativeTransform(RelativeSocketRotation, RelativeSocketLocation);
......
return RelativeTransform;
}
計算旋轉
相關參數
相關代碼
FRotator USpringArmComponent::GetTargetRotation() const
{
FRotator DesiredRot = GetDesiredRotation();
if (bUsePawnControlRotation)
{
if (APawn* OwningPawn = Cast<APawn>(GetOwner()))
{
const FRotator PawnViewRotation = OwningPawn->GetViewRotation();
if (DesiredRot != PawnViewRotation)
{
DesiredRot = PawnViewRotation;
}
}
}
// If inheriting rotation, check options for which components to inherit
if (!IsUsingAbsoluteRotation())
{
const FRotator LocalRelativeRotation = GetRelativeRotation();
if (!bInheritPitch)
{
DesiredRot.Pitch = LocalRelativeRotation.Pitch;
}
if (!bInheritYaw)
{
DesiredRot.Yaw = LocalRelativeRotation.Yaw;
}
if (!bInheritRoll)
{
DesiredRot.Roll = LocalRelativeRotation.Roll;
}
}
return DesiredRot;
}
UsingAbsoluteRotation是SceneComponent的一個設定,一般來說都是false(即使用相對值),可以在這裡設定
工作原理
GetDesiredRotation傳回的就是目前的Rotation(相對于世界),這個函數最終的傳回值也是作為絕對旋轉的值(相對于世界)
是以如果不繼承某個軸的旋轉并且使用相對旋轉或者使用絕對旋轉的話就會導緻在該軸上相機不會随着父物體旋轉(總是保持初始設定的相對旋轉作為絕對旋轉);反之在某個軸上繼承了旋轉并且使用相對旋轉,這時如果選擇了UsePawnControlRotation的話就會使用Controller中的旋轉,否則跟着父物體旋轉(即傳回DesiredRotation)
繼承旋轉的含義就是随着父物體旋轉
常用案例
- 第三人稱自由相機視角,将滑鼠xy軸輸入存入Controller中(Yaw和Pitch),使用相對旋轉,UsePawnControlRotation設定為true。人物的移動方向擷取Controller(也就是相機)的前和右(先去除Controller的pitch和roll分量再計算)