UE4学习-鼠标事件(按下、释放、物体抓取、计算重量、触发开门)

本文详细介绍了如何在UE4中实现物体的抓取、移动与重量计算功能。通过绑定鼠标事件,利用UPhysicsHandleComponent组件,实现了物体的抓取与释放。同时,通过UPrimitiveComponent组件获取物体质量,结合触发器组件,实现了基于物体总重量的机关门开启机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关键类

本篇博文用到的关键类有:

UInputComponent 用来绑定鼠标的按下和释放事件 BindAction

UPhysicsHandleComponent 设置被抓取物体的抓取,移动,释放
GrabComponentAtLocationWithRotation
ReleaseComponent
SetTargetLocation

UPrimitiveComponent 抓取组件抓取的对象
还可以获取质量 GetMass

鼠标按下、释放事件

首先,添加鼠标事件,在项目设置中,引擎->输入->操作映射,按加号,添加一个映射对象,然后添加一个鼠标左键事件,一个空格键事件。

在这里插入图片描述

在代码中创建一个 UInputComponent对象。

在grabber.h文件中,定义个人建议使用前置声明,把头文件放在cpp里面去包含。

并且添加两个函数,一个表示按下,一个表示释放。


#include <Components/InputComponent.h>

	void Grab();
	void Release();

UInputComponent* inputComponent = nullptr;

在cpp文件中添加:


// Called when the game starts
void Ugrabber::BeginPlay()
{
	Super::BeginPlay();

	inputComponent = GetOwner()->FindComponentByClass<UInputComponent>();

	if (nullptr != inputComponent)
	{
		UE_LOG(LogTemp, Warning, TEXT("find inputComponent"));
		inputComponent->BindAction("grab", IE_Pressed, this, &Ugrabber::Grab);
		inputComponent->BindAction("grab", IE_Released, this, &Ugrabber::Release);
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("not find inputComponent"));
	}
	
}



void Ugrabber::Grab()
{
	UE_LOG(LogTemp, Warning, TEXT("inputComponent press"));
}

void Ugrabber::Release()
{
	UE_LOG(LogTemp, Error, TEXT("inputComponent release"));
}


然后在虚幻编译器中进行编译,运行,鼠标按下释放,空格按下释放,都能打印日志,表示事件被触发。

在这里插入图片描述

物体抓取

首先给pawn添加组件
在这里插入图片描述
编译,保存。

添加的句柄对应的类是UPhysicsHandleComponent。

在grabber.h文件中,定义个人建议使用前置声明,把头文件放在cpp里面去包含。

并且添加两个函数,一个表示按下,一个表示释放。



class UPhysicsHandleComponent;
UPhysicsHandleComponent* physicsHandel = nullptr;

在grabber.cpp文件中添加:


BeginPlay()
{
	physicsHandel = GetOwner()->FindComponentByClass<UPhysicsHandleComponent>();
}

// Called every frame
void Ugrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	// 设置抓取物体跟随移动
	if (physicsHandel && physicsHandel->GrabbedComponent)
	{
		physicsHandel->SetTargetLocation(getLineEnd());
	}
}

void Ugrabber::Grab()
{
	UE_LOG(LogTemp, Warning, TEXT("inputComponent press"));
	FHitResult hit = lineTrace();
	UPrimitiveComponent* primit = hit.GetComponent();
	if (hit.GetActor() && physicsHandel)
	{
		UE_LOG(LogTemp, Warning, TEXT("Grab"));
		physicsHandel->GrabComponentAtLocationWithRotation(primit, NAME_None, primit->GetOwner()->GetActorLocation(), GetOwner()->GetActorRotation());
	}
}

void Ugrabber::Release()
{
	UE_LOG(LogTemp, Error, TEXT("inputComponent release"));
	if (physicsHandel)
	{
		physicsHandel->ReleaseComponent();
	}
}

这里把物体的抓取和释放的函数修改了。

计算物体重量

要计算物体重量,需要给物体添加一个选项: 生成重叠事件

在这里插入图片描述

还要给物体设置重量,桌子20kg,椅子10kg。
在这里插入图片描述

一定要把物体的 生成重叠事件 这个选项勾选,否则没法被检查到。物体质量也没法计算。

在openDoor.h文件中添加一个函数:


	float GetTotalMassInTrigger();

在openDoor.cpp文件中添加如下代码:


float UopenDoor::GetTotalMassInTrigger()
{
	if (nullptr == trigger)
	{
		return 0.0f;
	}
	TArray<AActor*> actArr;
	trigger->GetOverlappingActors(OUT actArr);
	float totalMass = 0.0f;
	for (const AActor* act : actArr)
	{
		totalMass += act->FindComponentByClass<UPrimitiveComponent>()->GetMass();
	}
	UE_LOG(LogTemp, Warning, TEXT("total mass %f"), totalMass);
	return totalMass;
}

// Called every frame
void UopenDoor::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	// if (nullptr != trigger && trigger->IsOverlappingActor(pawn))
	if(trigger && GetTotalMassInTrigger() > 25.0f)
	{
		openDoor();
		lastTime = GetWorld()->GetTimeSeconds();
	}
	if (GetWorld()->GetTimeSeconds() - lastTime > openTime)
	{
		closeDoor();
	}
}

在 TickComponent 函数中添加了质量判断,还修改开门的方式,桌子和椅子一共的重量添加,才能触发开门。

运行起来,桌子和椅子一起在触发器范围内,总质量为30kg,触发机关,门打开了。

当然角色老是会在空中飘着,给角色也设置一个模拟物体的属性,这样物体就带重力了,跳上去也会慢慢落下来。

在这里插入图片描述
在这里插入图片描述

到此,游戏基本完成,下篇博文会使用蓝图对开门等操作,设置动画效果。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值