UE4窗口移动的实现思路


实现类似英雄联盟和星际争霸等游戏,鼠标移到窗口边缘视角跟随移动。

原理:

在屏幕的周围划分出一定的区域,当鼠标移动到这些区域时,向对应的方向移动摄像机。

创建方向枚举 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);

效果:


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM