实现类似英雄联盟和星际争霸等游戏,鼠标移到窗口边缘视角跟随移动。
原理:
在屏幕的周围划分出一定的区域,当鼠标移动到这些区域时,向对应的方向移动摄像机。
创建方向枚举 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);
效果: