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

文章目录

  • 关键类
  • 鼠标按下、释放事件
  • 物体抓取
  • 计算物体重量

关键类

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

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

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

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

鼠标按下、释放事件

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

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

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

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

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


#include 

	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"));
}


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

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

物体抓取

首先给pawn添加组件
UE4学习-鼠标事件(按下、释放、物体抓取、计算重量、触发开门)_第3张图片
编译,保存。

添加的句柄对应的类是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。
UE4学习-鼠标事件(按下、释放、物体抓取、计算重量、触发开门)_第4张图片

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

在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,触发机关,门打开了。

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

UE4学习-鼠标事件(按下、释放、物体抓取、计算重量、触发开门)_第5张图片
UE4学习-鼠标事件(按下、释放、物体抓取、计算重量、触发开门)_第6张图片

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

你可能感兴趣的:(UE4,游戏,游戏开发,c++,UE4,触发器)