UE5数字孪生系列笔记(三)

news2025/2/3 3:49:35

C++创建Pawn类玩家

  • 创建一个GameMode蓝图用来加载我们自定义的游戏Mode
  • 新建一个Pawn的C++,MyCharacter类作为玩家,新建一个相机组件与相机臂组件,box组件作为根组件
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "MyCharacter.generated.h"

UCLASS()
class CITYTWIN_API AMyCharacter : public APawn
{
	GENERATED_BODY()

public:
	// Sets default values for this pawn's properties
	AMyCharacter();

	//box作为根组件
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Camera")
	class UBoxComponent* CollisionBox;

	//相机组件
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Camera")
	class UCameraComponent* FollowCamera;

	//相机臂组件
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Camera")
	class USpringArmComponent* CameraBoom;

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

};

  • 声明创建组件,硬编码一些基本属性
// Fill out your copyright notice in the Description page of Project Settings.


#include "MyCharacter.h"
#include "Components/BoxComponent.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"

// Sets default values
AMyCharacter::AMyCharacter()
{
 	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	CollisionBox = CreateDefaultSubobject<UBoxComponent>(TEXT("CollisionBox"));
	CollisionBox->SetupAttachment(GetRootComponent());

	CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
	CameraBoom->SetupAttachment(CollisionBox);
	CameraBoom->TargetArmLength = 1500.f;
	CameraBoom->bUsePawnControlRotation = false;
	CameraBoom->bEnableCameraLag = true;//摄像机臂平滑
	CameraBoom->bEnableCameraRotationLag = true;//启用相机旋转延迟
	CameraBoom->bDoCollisionTest = false;//关闭摄像机臂碰撞

	FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
	FollowCamera->SetupAttachment(CameraBoom);
	FollowCamera->bUsePawnControlRotation = false;
}

// Called when the game starts or when spawned
void AMyCharacter::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void AMyCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

}
  • 创建这个Pawn类的蓝图进行之前登录页面动画的视角旋转方向问题的解决
  • 首先将蓝图生成对齐到视角
    在这里插入图片描述
  • 将Pawn类自动接收玩家0
    在这里插入图片描述
  • 然后删除PlayerStart
    在这里插入图片描述
  • 运行结果
    请添加图片描述

移动增强输入系统

  • 在项目建立.cs文件中添加这个模块
    在这里插入图片描述
  • 绑定增强输入系统操作
  • MyCharacter.h
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "../../../../UE_5.2.1/UE_5.2/Engine/Plugins/EnhancedInput/Source/EnhancedInput/Public/InputActionValue.h"
#include "MyCharacter.generated.h"

UCLASS()
class CITYTWIN_API AMyCharacter : public APawn
{
	GENERATED_BODY()

public:
	// Sets default values for this pawn's properties
	AMyCharacter();

	//box作为根组件
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Camera")
	class UBoxComponent* CollisionBox;

	//相机组件
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Camera")
	class UCameraComponent* FollowCamera;

	//相机臂组件
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Camera")
	class USpringArmComponent* CameraBoom;

	//绑定映射
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	class UInputMappingContext* MappingContext;

	//移动绑定
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	class UInputAction* LeftButtonAction;


protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

	//鼠标按下操作事件
	void LeftMouseDown(const FInputActionValue& value);
	void LeftMouseUp(const FInputActionValue& value);

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

};

  • MyCharacter.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyCharacter.h"
#include "Components/BoxComponent.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "EnhancedInputSubsystems.h"
#include "EnhancedInputComponent.h"

// Sets default values
AMyCharacter::AMyCharacter()
{
 	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	CollisionBox = CreateDefaultSubobject<UBoxComponent>(TEXT("CollisionBox"));
	CollisionBox->SetupAttachment(GetRootComponent());

	CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
	CameraBoom->SetupAttachment(CollisionBox);
	CameraBoom->TargetArmLength = 1500.f;
	CameraBoom->bUsePawnControlRotation = false;
	CameraBoom->bEnableCameraLag = true;//摄像机臂平滑
	CameraBoom->bEnableCameraRotationLag = true;//启用相机旋转延迟
	CameraBoom->bDoCollisionTest = false;//关闭摄像机臂碰撞

	FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
	FollowCamera->SetupAttachment(CameraBoom);
	FollowCamera->bUsePawnControlRotation = false;
}
// Called when the game starts or when spawned
void AMyCharacter::BeginPlay()
{
	Super::BeginPlay();
	APlayerController* PlayerController = Cast<APlayerController>(Controller);
	if (PlayerController)
	{
		UEnhancedInputLocalPlayerSubsystem* Subsystem =
			ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer());
		if (Subsystem)
		{
			Subsystem->AddMappingContext(MappingContext, 0);
		}
	}
}
void AMyCharacter::LeftMouseDown(const FInputActionValue& value)
{
}

void AMyCharacter::LeftMouseUp(const FInputActionValue& value)
{
}
// Called every frame
void AMyCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}
// Called to bind functionality to input
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	UEnhancedInputComponent* EnhancedInputConponent = Cast<UEnhancedInputComponent>(PlayerInputComponent);
	if (EnhancedInputConponent)
	{
		EnhancedInputConponent->BindAction(LeftButtonAction, ETriggerEvent::Started, this, &AMyCharacter::LeftMouseDown);
		EnhancedInputConponent->BindAction(LeftButtonAction, ETriggerEvent::Completed, this, &AMyCharacter::LeftMouseUp);

	}
}

获取鼠标位置坐标与鼠标移动后的差量

  • 使用GetMousePosition函数来获取鼠标的坐标点
  • MyCharacter.h中新建一个函数专门用来获取鼠标的坐标点的函数
	//鼠标的坐标点
	FVector2D MousePos = FVector2D::ZeroVector;

void GetMousePosition();
  • MyCharacter.cpp中实现此方法
void AMyCharacter::GetMousePosition()
{
	
	GetWorld()->GetFirstPlayerController()->GetMousePosition(MousePos.X, MousePos.Y);
	
	//打印鼠标信息到屏幕
	GEngine->AddOnScreenDebugMessage(-1, 1, FColor::Red, FString::Printf(TEXT("%f,%f"), MousePos.X, MousePos.Y));
}

  • 获取鼠标变化差量,当我们鼠标变化时,我们要获取到这个变化的差量值,我们可以定义两个变量,一个变量存储用来作为变化之前的绝对位置减去变化之后的当前绝对位置,然后另外两个变量来存储变化之后当前的绝对位置
	//鼠标的坐标点
	FVector2D MousePos = FVector2D::ZeroVector;
	
	//记录的鼠标变化差量
	FVector2D MouseVariationDifference = FVector2D::ZeroVector;

	//记录变化之后的鼠标坐标
	float MouseX = 0.f;
	float MouseY = 0.f;

void AMyCharacter::GetMousePosition()
{

	//获取当前鼠标移动坐标
	GetWorld()->GetFirstPlayerController()->GetMousePosition(MousePos.X, MousePos.Y);

	//记录的鼠标变化差量
	MouseVariationDifference = MousePos - FVector2D(MouseX, MouseY);

	//记录变化后的鼠标位置
	MouseX = MousePos.X;
	MouseY = MousePos.Y;

	//打印鼠标信息到屏幕
	GEngine->AddOnScreenDebugMessage(1, 1, FColor::Red, FString::Printf(TEXT("%f,%f"), MousePos.X, MousePos.Y));
	GEngine->AddOnScreenDebugMessage(2, 1, FColor::Yellow, FString::Printf(TEXT("%f,%f"), MouseVariationDifference.X, MouseVariationDifference.Y));
}

设置滑动鼠标实现旋转视角效果

  • 通过获取的移动的鼠标差量进行鼠标滑动移动视角
  • 新建一个鼠标视角移动速度变量,用来控制鼠标实现视角旋转的移动速度
	//鼠标视角移动速度
	float MouseSpeed = 0.1f;
  • 新建一个鼠标视角移动函数,函数逻辑
  • ActorRotator.Pitch + (MouseVariationDifference.Y * MouseSpeed):Pitch是虚幻中的抬头与低头,在直角坐标系中用来Y来描述
  • ActorRotator.Yaw + (MouseVariationDifference.X * MouseSpeed * -1.f):Yaw是摇头转向,在直角坐标系中用来X来描述,实践中得乘以-1使用,估计是因为虚幻默认以右方向为正方向的原因
	//鼠标移动视角移动事件
	void MouseMove();
	
void AMyCharacter::MouseMove()
{
	FRotator ActorRotator = GetActorRotation();
	FRotator NewActorRotator = FRotator(ActorRotator.Pitch + (MouseVariationDifference.Y * MouseSpeed),
		ActorRotator.Yaw + (MouseVariationDifference.X * MouseSpeed * -1.f), ActorRotator.Roll);
	SetActorRotation(NewActorRotator);
}
  • 调用函数
// Called every frame
void AMyCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	//获取鼠标坐标
	GetMousePosition();
	//鼠标移动视角
	MouseMove();

}
  • 运行结果
    请添加图片描述

鼠标左键视觉拖动效果

  • 将滑动鼠标实现旋转视角效果设置为鼠标左键按下后才能实现
  • 添加一个布尔变量用来标识是否要开启鼠标旋转视角事情
	//标识鼠标左键是否按下
	bool bIsMouseLeftDown = false;

void AMyCharacter::MouseMove()
{
	if (bIsMouseLeftDown)
	{
		FRotator ActorRotator = GetActorRotation();
		//限制一下视角度数带来的错误
		FRotator NewActorRotator = FRotator(FMath::Clamp((ActorRotator.Pitch + (MouseVariationDifference.Y * MouseSpeed)),-80.f,-10.f),
			ActorRotator.Yaw + (MouseVariationDifference.X * MouseSpeed * -1.f), ActorRotator.Roll);
		SetActorRotation(NewActorRotator);
		
	}
}

void AMyCharacter::LeftMouseDown(const FInputActionValue& value)
{
	bIsMouseLeftDown = true;
}

void AMyCharacter::LeftMouseUp(const FInputActionValue& value)
{
	bIsMouseLeftDown = false;
}

鼠标右键视角移动效果

  • 添加右键的输入操作
    在这里插入图片描述
  • 新建右键是否按下的标识布尔变量,创建右键操作的输入行为,即绑定函数
	//移动绑定
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	class UInputAction* RightButtonAction;
	//标识鼠标右键是否按下
	bool bIsMouseRightDown = false;


// Called to bind functionality to input
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	UEnhancedInputComponent* EnhancedInputConponent = Cast<UEnhancedInputComponent>(PlayerInputComponent);
	if (EnhancedInputConponent)
	{
		EnhancedInputConponent->BindAction(LeftButtonAction, ETriggerEvent::Started, this, &AMyCharacter::LeftMouseDown);
		EnhancedInputConponent->BindAction(LeftButtonAction, ETriggerEvent::Completed, this, &AMyCharacter::LeftMouseUp);
		EnhancedInputConponent->BindAction(RightButtonAction, ETriggerEvent::Started, this, &AMyCharacter::RightMouseDown);
		EnhancedInputConponent->BindAction(RightButtonAction, ETriggerEvent::Completed, this, &AMyCharacter::RightMouseUp);
	}
}

void AMyCharacter::RightMouseDown(const FInputActionValue& value)
{
	bIsMouseRightDown = true;
}

void AMyCharacter::RightMouseUp(const FInputActionValue& value)
{
	bIsMouseRightDown = false;
}

  • 新建鼠标右键移动速度变量,编写鼠标右键移动逻辑
	//鼠标右键移动速度
	float MouseRightSpeed = 100.f;

void AMyCharacter::MouseMove()
{
	if (bIsMouseLeftDown)
	{
		FRotator ActorRotator = GetActorRotation();
		//限制一下视角度数带来的错误
		FRotator NewActorRotator = FRotator(FMath::Clamp((ActorRotator.Pitch + (MouseVariationDifference.Y * MouseSpeed)),-80.f,-10.f),
			ActorRotator.Yaw + (MouseVariationDifference.X * MouseSpeed * -1.f), ActorRotator.Roll);
		SetActorRotation(NewActorRotator);
	}
	if (bIsMouseRightDown)
	{
		FVector SpeedMove = FVector(MouseVariationDifference.Y * MouseRightSpeed,
			-1.0 * MouseRightSpeed * MouseVariationDifference.X, 0);
		AddActorLocalOffset(SpeedMove);
		//限制z轴
		FVector Location = GetActorLocation();
		FVector NewLocation = FVector(Location.X, Location.Y, 4520);
		SetActorLocation(NewLocation);
	}
}

鼠标中键控制摄像机臂长度,缩放地图效果

  • 新建鼠标中键的操作行为,添加一个鼠标中键移动速度变量,然后在鼠标中键操作事件中完成逻辑,逻辑是获取相机臂的长度,用获取鼠标滚轮的量值乘以鼠标中键移动速度变量被获取的相机臂原长度减去
	//移动绑定
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	class UInputAction* MiddleButtonAction;
	
	//鼠标中键移动速度
	float MouseMiddleSpeed = 1000.f;

void AMyCharacter::MiddleMouseSlide(const FInputActionValue& value)
{
	float Axis = value.Get<float>();
	float CameraArm = CameraBoom->TargetArmLength;
	//限制相机臂长度
	CameraBoom->TargetArmLength = FMath::Clamp((CameraArm - Axis * MouseMiddleSpeed), 1000.f, 30000.f);
}
  • 运行结果
    请添加图片描述

源码

MyCharacter.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "../../../../UE_5.2.1/UE_5.2/Engine/Plugins/EnhancedInput/Source/EnhancedInput/Public/InputActionValue.h"
#include "MyCharacter.generated.h"



UCLASS()
class CITYTWIN_API AMyCharacter : public APawn
{
	GENERATED_BODY()

public:
	// Sets default values for this pawn's properties
	AMyCharacter();

	//box作为根组件
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Camera")
	class UBoxComponent* CollisionBox;

	//相机组件
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Camera")
	class UCameraComponent* FollowCamera;

	//相机臂组件
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Camera")
	class USpringArmComponent* CameraBoom;

	//绑定映射
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	class UInputMappingContext* MappingContext;

	//移动绑定
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	class UInputAction* LeftButtonAction;

	//移动绑定
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	class UInputAction* RightButtonAction;

	//移动绑定
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	class UInputAction* MiddleButtonAction;

	//鼠标的坐标点
	FVector2D MousePos = FVector2D::ZeroVector;

	//记录的鼠标变化差量
	FVector2D MouseVariationDifference = FVector2D::ZeroVector;

	//记录变化之后的鼠标坐标
	float MouseX = 0.f;
	float MouseY = 0.f;

	//鼠标视角移动速度
	float MouseSpeed = 0.1f;
	//鼠标右键移动速度
	float MouseRightSpeed = 100.f;
	//鼠标中键移动速度
	float MouseMiddleSpeed = 1000.f;

	//标识鼠标左键是否按下
	bool bIsMouseLeftDown = false;
	//标识鼠标右键是否按下
	bool bIsMouseRightDown = false;


protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

	//鼠标按下操作事件
	void LeftMouseDown(const FInputActionValue& value);
	void LeftMouseUp(const FInputActionValue& value);
	void RightMouseDown(const FInputActionValue& value);
	void RightMouseUp(const FInputActionValue& value);
	void MiddleMouseSlide(const FInputActionValue& value);

	//鼠标移动视角移动事件
	void MouseMove();

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

	void GetMousePosition();
};

MyCharacter.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "MyCharacter.h"
#include "Components/BoxComponent.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "EnhancedInputSubsystems.h"
#include "EnhancedInputComponent.h"
#include "Engine/Engine.h"

// Sets default values
AMyCharacter::AMyCharacter()
{
 	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	CollisionBox = CreateDefaultSubobject<UBoxComponent>(TEXT("CollisionBox"));
	CollisionBox->SetupAttachment(GetRootComponent());

	CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
	CameraBoom->SetupAttachment(CollisionBox);
	CameraBoom->TargetArmLength = 1500.f;
	CameraBoom->bUsePawnControlRotation = false;
	CameraBoom->bEnableCameraLag = true;//摄像机臂平滑
	CameraBoom->bEnableCameraRotationLag = true;//启用相机旋转延迟
	CameraBoom->bDoCollisionTest = false;//关闭摄像机臂碰撞

	FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
	FollowCamera->SetupAttachment(CameraBoom);
	FollowCamera->bUsePawnControlRotation = false;
}

// Called when the game starts or when spawned
void AMyCharacter::BeginPlay()
{
	Super::BeginPlay();
	APlayerController* PlayerController = Cast<APlayerController>(Controller);
	if (PlayerController)
	{
		UEnhancedInputLocalPlayerSubsystem* Subsystem =
			ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer());
		if (Subsystem)
		{
			Subsystem->AddMappingContext(MappingContext, 0);
		}
	}
}

void AMyCharacter::LeftMouseDown(const FInputActionValue& value)
{
	bIsMouseLeftDown = true;
}

void AMyCharacter::LeftMouseUp(const FInputActionValue& value)
{
	bIsMouseLeftDown = false;
}

void AMyCharacter::RightMouseDown(const FInputActionValue& value)
{
	bIsMouseRightDown = true;
}

void AMyCharacter::RightMouseUp(const FInputActionValue& value)
{
	bIsMouseRightDown = false;
}


void AMyCharacter::MiddleMouseSlide(const FInputActionValue& value)
{
	float Axis = value.Get<float>();
	float CameraArm = CameraBoom->TargetArmLength;
	//限制相机臂长度
	CameraBoom->TargetArmLength = FMath::Clamp((CameraArm - Axis * MouseMiddleSpeed), 1000.f, 30000.f);
}

void AMyCharacter::MouseMove()
{
	if (bIsMouseLeftDown)
	{
		FRotator ActorRotator = GetActorRotation();
		//限制一下视角度数带来的错误
		FRotator NewActorRotator = FRotator(FMath::Clamp((ActorRotator.Pitch + (MouseVariationDifference.Y * MouseSpeed)),-80.f,-10.f),
			ActorRotator.Yaw + (MouseVariationDifference.X * MouseSpeed * -1.f), ActorRotator.Roll);
		SetActorRotation(NewActorRotator);
	}
	if (bIsMouseRightDown)
	{
		FVector SpeedMove = FVector(MouseVariationDifference.Y * MouseRightSpeed,
			-1.0 * MouseRightSpeed * MouseVariationDifference.X, 0);
		AddActorLocalOffset(SpeedMove);
		//限制z轴
		FVector Location = GetActorLocation();
		FVector NewLocation = FVector(Location.X, Location.Y, 4520);
		SetActorLocation(NewLocation);
	}
}


// Called every frame
void AMyCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	//获取鼠标坐标
	GetMousePosition();
	//鼠标移动视角
	MouseMove();

}

// Called to bind functionality to input
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	UEnhancedInputComponent* EnhancedInputConponent = Cast<UEnhancedInputComponent>(PlayerInputComponent);
	if (EnhancedInputConponent)
	{
		EnhancedInputConponent->BindAction(LeftButtonAction, ETriggerEvent::Started, this, &AMyCharacter::LeftMouseDown);
		EnhancedInputConponent->BindAction(LeftButtonAction, ETriggerEvent::Completed, this, &AMyCharacter::LeftMouseUp);
		EnhancedInputConponent->BindAction(RightButtonAction, ETriggerEvent::Started, this, &AMyCharacter::RightMouseDown);
		EnhancedInputConponent->BindAction(RightButtonAction, ETriggerEvent::Completed, this, &AMyCharacter::RightMouseUp);
		EnhancedInputConponent->BindAction(MiddleButtonAction, ETriggerEvent::Triggered, this, &AMyCharacter::MiddleMouseSlide);

	}
}

void AMyCharacter::GetMousePosition()
{
	//获取当前鼠标移动坐标
	GetWorld()->GetFirstPlayerController()->GetMousePosition(MousePos.X, MousePos.Y);

	//记录的鼠标变化差量
	MouseVariationDifference = MousePos - FVector2D(MouseX, MouseY);

	//记录变化后的鼠标位置
	MouseX = MousePos.X;
	MouseY = MousePos.Y;

	//打印鼠标信息到屏幕
	/*GEngine->AddOnScreenDebugMessage(1, 1, FColor::Red, FString::Printf(TEXT("%f,%f"), MousePos.X, MousePos.Y));
	GEngine->AddOnScreenDebugMessage(2, 1, FColor::Yellow, FString::Printf(TEXT("%f,%f"), MouseVariationDifference.X, MouseVariationDifference.Y));*/
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1555069.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2.java openCV4.x 入门-hello OpenCV

专栏简介 &#x1f492;个人主页 &#x1f4f0;专栏目录 点击上方查看更多内容 &#x1f4d6;心灵鸡汤&#x1f4d6;我们唯一拥有的就是今天&#xff0c;唯一能把握的也是今天 &#x1f9ed;文章导航&#x1f9ed; ⬆️ 1.环境搭建 ⬇️ 3.Mat之构造函数与数据类型 hell…

关于深度学习的 PyTorch 项目如何上手分析?从什么地方切入?

文章目录 PyTorch 项目分析1.背景2.分析流程 PyTorch 项目分析 1.背景 当我们拿到一个 PyTorch 的深度学习项目时&#xff0c;应该怎么入手&#xff1f;怎么去查看代码&#xff1f; 2.分析流程 首先阅读对应项目的 README.md 文件。通过阅读 README.md &#xff0c;一般可以…

HarmonyOS 应用开发之创建PageAbility

开发者需要重写app.js/app.ets中的生命周期回调函数&#xff0c;开发者通过DevEco Studio开发平台创建PageAbility时&#xff0c;DevEco Studio会在app.js/app.ets中默认生成onCreate()和onDestroy()方法&#xff0c;其他方法需要开发者自行实现。接口说明参见前述章节&#xf…

UVA1388 - Graveyard (数学)

Graveyard 题面翻译 题目描述 在一个周长为 10000 10000 10000的圆上等距分别着 n n n个雕塑。现在又有 m m m个新雕塑加入(位置可以随意),希望所有 n m nm nm个雕塑在圆周上分布均匀。这就需要移动其中一些原有的雕塑。要求 n n n个雕塑移动的总距离尽量小。 输入格式 输…

前端-css-01

1.CSS 长度单位和颜色设置 1.1CSS 中的长度单位 px 像素 em 字体大小的倍数&#xff08;字体默认是16px&#xff09; % 百分比 1.2CSS 中的颜色设置方式 1.2.1使用颜色名表示颜色 red、orange、yellow、green、cyan、blue、purple、pink、deeppink、skyblue、greenyellow .…

国产暴雨AI服务器X3418开启多元自主可控新篇章

在当前数字化转型的大潮中&#xff0c;算力作为新质生产力的重要动力引擎&#xff0c;对推动经济社会发展起着关键作用。尤其在人工智能领域&#xff0c;随着高性能、安全可控的AI算力需求持续攀升&#xff0c;国产化服务器的研发与应用显得尤为迫切。 作为国内专业的算力基础…

aeon,一个好用的 Python 库!

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个好用的 Python 库 - aeon Github地址&#xff1a;https://github.com/aeon-toolkit/aeon 在现代计算机科学和人工智能领域&#xff0c;处理时间序列数据是一个重要而复杂的任务。Python aeon库…

【Roadmap to learn LLM】Large Language Models in Five Formulas

by Alexander Rush Our hope: reasoning about LLMs Our Issue 文章目录 Perpexity(Generation)Attention(Memory)GEMM(Efficiency)用矩阵乘法说明GPU的工作原理 Chinchilla(Scaling)RASP(Reasoning)结论参考资料 the five formulas perpexity —— generationattention —— m…

mysql 常见运算符

学习了mysql数据类型&#xff0c;接下来学习mysql常见运算符。 2&#xff0c;常见运算符介绍 运算符连接表达式中各个操作数&#xff0c;其作用是用来指明对操作数所进行的运算。运用运算符 可以更加灵活地使用表中的数据&#xff0c;常见的运算符类型有&#xff1a;算…

PN8034芯朋微PN8034SSC-R1B非隔离SOP7封装12V300MA电源芯片

PN8034集成PFM控制器及650V高雪州能力智能功本MOSFET&#xff0c;用于外图元器件极精简的小功本非隔离开关电源。PN8034内置高压启动模块&#xff0c;实现系统快速启动&#xff0c;超低待机功能。该芯片提供了完整的智能化保护功能&#xff0c;包括过流保护&#xff0c;欠压保护…

QT_day3:信号和槽的连接方式

1、使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;密码是…

基于.NET Core开发的轻量级分布式配置中心

前言 今天给大家推荐一个基于.NET Core开发的轻量级分布式配置中心&#xff1a;AgileConfig。 AgileConfig官方介绍 AgileConfig秉承轻量化的特点&#xff0c;部署简单、配置简单、使用简单、学习简单&#xff0c;它只提取了必要的一些功能&#xff0c;并没有像Apollo那样复…

小米汽车引入革命性卫星通信技术:专利揭示直连卫星能力

小米汽车在近期的SU7发布会上&#xff0c;虽已展示了其运动轿跑车型的各项卓越性能&#xff0c;售价起于21.59万元&#xff0c;但其技术创新的深度远不止于此。一项最新公布的专利显示&#xff0c;小米汽车科技有限公司正在积极探索和开发车载卫星通信技术&#xff0c;该技术的…

【web安全】Dr4g0n-b4ll 靶场笔记

搜索目标&#xff0c;使用&#xff1a;nmap -sn 192.168.111.0/24 扫描当前ip段的存货 -sn是忽略端口&#xff0c;只扫描存活&#xff0c;发现IP&#xff1a;192.168.111.133 先不要扫描&#xff0c;直接访问&#xff1a;192.168.111.133&#xff0c;打开是普通的网页 观察内容…

vivado 手动布线

手动路由 手动路由允许您为网络选择特定的路由资源。这给了你对信号将要采用的路由路径的完全控制。手动路由不调用route_design。路线在路线数据库中直接更新。当您想精确控制网络的延迟时&#xff0c;可能需要使用手动路由。对于例如&#xff0c;假设有一个源同步接口&#…

ATTCK学习笔记

ATT&CK 前言知识 威胁情报&#xff1a;一般为网络流量中或者操作系统上观察到的能高度表明计算机被入侵的痕迹&#xff0c;例如某病毒的Hash值、服务器的IP地址等等。简单来说&#xff0c;威胁情报就像是当计算机被入侵时所表现出来的某种特征&#xff0c;我们将这些威胁…

爬虫(Web Crawler)逆向技术探索

实战案例分析 为了更好地理解爬虫逆向的实际应用&#xff0c;我们以一个具体的案例进行分析。 案例背景 假设我们需要从某电商网站上获取商品价格信息&#xff0c;但该网站采取了反爬虫措施&#xff0c;包括动态Token和用户行为分析等。 分析与挑战 动态Token&#xff1a;…

Linux部分命令

目录 1.文件介绍 2.ls命令 3.目录命令 4.相对路径以及绝对路径 5.命令创建目录&#xff08;文件夹&#xff09; 6.which命令 7.find命令 8.grep命令 9.wc命令 10.echo、tail、重定向符 1.文件介绍 和window不同&#xff0c;Linux没有盘路径&#xff0c;所有的文件都存…

python读取excel,转换成json格式,for国际化前端菜单

# -*- coding: utf-8 -*-import pandas as pd import json# 读取Excel文件中的数据 excel_file rD:\解析excel\中英.xlsx df pd.read_excel(excel_file)# 生成中文JSON和英文JSON cn_data {} en_data {} pu_data {} special_data_cn {} special_data_en {} special_data…

Stata 15 for Mac:数据统计分析新标杆,让研究更高效!

Stata 是一种统计分析软件&#xff0c;适用于数据管理、数据分析和绘图。Stata 15 for Mac 具有以下功能&#xff1a; 数据管理&#xff1a;Stata 提供强大的数据管理功能&#xff0c;用户可以轻松导入、清洗、整理和管理数据集。 统计分析&#xff1a;Stata 提供了广泛的统计…