天天看點

深入了解UE常用類型--SpringArmComponent

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;
}
           

計算旋轉

相關參數

深入了解UE常用類型--SpringArmComponent

相關代碼

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(即使用相對值),可以在這裡設定

深入了解UE常用類型--SpringArmComponent

工作原理

GetDesiredRotation傳回的就是目前的Rotation(相對于世界),這個函數最終的傳回值也是作為絕對旋轉的值(相對于世界)

是以如果不繼承某個軸的旋轉并且使用相對旋轉或者使用絕對旋轉的話就會導緻在該軸上相機不會随着父物體旋轉(總是保持初始設定的相對旋轉作為絕對旋轉);反之在某個軸上繼承了旋轉并且使用相對旋轉,這時如果選擇了UsePawnControlRotation的話就會使用Controller中的旋轉,否則跟着父物體旋轉(即傳回DesiredRotation)

繼承旋轉的含義就是随着父物體旋轉

常用案例

  1. 第三人稱自由相機視角,将滑鼠xy軸輸入存入Controller中(Yaw和Pitch),使用相對旋轉,UsePawnControlRotation設定為true。人物的移動方向擷取Controller(也就是相機)的前和右(先去除Controller的pitch和roll分量再計算)

繼續閱讀