實現類似英雄聯盟和星際爭霸等游戲,鼠標移到窗口邊緣視角跟隨移動。
原理:
在屏幕的周圍划分出一定的區域,當鼠標移動到這些區域時,向對應的方向移動攝像機。
創建方向枚舉 EScreenMoveState
enum EScreenMoveState
{
Screen_None,
Screen_UP, //上
Screen_Down, //下
Screen_Right, //左
Screen_Left, //右
Screen_RightAndUP, //左上
Screen_RightAndDown, //左下
Screen_LeftAndUP, //右上
Screen_LeftAndDown, //右下
Screen_MAX
};
獲取當前的移動狀態
EScreenMoveState CursorMove(const APlayerController* PlayerController)
{
if (PlayerController)
{
//屏幕尺寸
int32 SizeX = INDEX_NONE;
int32 SizeY = INDEX_NONE;
//鼠標位置
float MousePostionX = -107374176.f;
float MousePostionY = -107374176.f;
//獲取屏幕尺寸
PlayerController->GetViewportSize(SizeX, SizeY);
//獲取鼠標位置
PlayerController->GetMousePosition(MousePostionX, MousePostionY);
if (MousePostionX >= 0 && MousePostionX <= SizeX && MousePostionY >= 0 && MousePostionY <= SizeY)
{
if (FMath::IsNearlyEqual(MousePostionX, 0.0f, 10.0f) && FMath::IsNearlyEqual(MousePostionY, 0.0f, 10.0f))
{
return EScreenMoveState::Screen_LeftAndUP;
}
else if (FMath::IsNearlyEqual(MousePostionX, SizeX, 10.0f) && FMath::IsNearlyEqual(MousePostionY, SizeY, 10.0f))
{
return EScreenMoveState::Screen_RightAndDown;
}
else if (FMath::IsNearlyEqual(MousePostionX, SizeX, 10.0f) && FMath::IsNearlyEqual(MousePostionY, 0.0f, 10.0f))
{
return EScreenMoveState::Screen_RightAndUP;
}
else if (FMath::IsNearlyEqual(MousePostionX, 0.0f, 10.0f) && FMath::IsNearlyEqual(MousePostionY, SizeY, 10.0f))
{
return EScreenMoveState::Screen_LeftAndDown;
}
else if (FMath::IsNearlyEqual(MousePostionX, 0.0f, 10.0f))
{
return EScreenMoveState::Screen_Left;
}
else if (FMath::IsNearlyEqual(MousePostionY, 0.0f, 10.0f))
{
return EScreenMoveState::Screen_UP;
}
else if (FMath::IsNearlyEqual(MousePostionY, SizeY, 10.0f))
{
return EScreenMoveState::Screen_Down;
}
else if (FMath::IsNearlyEqual(MousePostionX, SizeX, 10.0f))
{
return EScreenMoveState::Screen_Right;
}
}
}
return EScreenMoveState::Screen_None;
}
使當前的攝像頭隨着鼠標移動
bool MoveDirection(APlayerController* PlayerController, EScreenMoveState ScreenMoveState, float& ScreenMoveSpeed)
{
FVector OffsetValue = FVector::ZeroVector;
if (PlayerController && PlayerController->GetPawn())
{
switch (ScreenMoveState)
{
case Screen_UP:
OffsetValue = FVector(ScreenMoveSpeed, 0.0f, 0.0f);
break;
case Screen_Down:
OffsetValue = FVector(-ScreenMoveSpeed, 0.0f, 0.0f);
break;
case Screen_Right:
OffsetValue = FVector(0.0f, ScreenMoveSpeed, 0.0f);
break;
case Screen_Left:
OffsetValue = FVector(0.0f, -ScreenMoveSpeed, 0.0f);
break;
case Screen_RightAndUP:
OffsetValue = FVector(ScreenMoveSpeed, ScreenMoveSpeed, 0.0f);
break;
case Screen_RightAndDown:
OffsetValue = FVector(-ScreenMoveSpeed, ScreenMoveSpeed, 0.0f);
break;
case Screen_LeftAndUP:
OffsetValue = FVector(ScreenMoveSpeed, -ScreenMoveSpeed, 0.0f);
break;
case Screen_LeftAndDown:
OffsetValue = FVector(-ScreenMoveSpeed, -ScreenMoveSpeed, 0.0f);
break;
}
PlayerController->GetPawn()->AddActorWorldOffset(OffsetValue);
}
return OffsetValue != FVector::ZeroVector;
}
讓鼠標始終顯示
bShowMouseCursor = true;
設置 InputModeGameAndUI
FInputModeGameAndUI InputMode;
//將鼠標鎖定在視口中
InputMode.SetLockMouseToViewportBehavior(EMouseLockMode::LockAlways);
//鼠標始終顯示
InputMode.SetHideCursorDuringCapture(false);
SetInputMode(InputMode);
效果: