UE4学习-添加机关并添加代码控制

添加机关

首先向场景里面添加一个聚光源
在这里插入图片描述

添加聚光源以后,可以对其属性进行修改,如图:
在这里插入图片描述
然后需要给聚光源添加一个触发体积(TriggerVolume)。
在这里插入图片描述
然后调整触发体积的大小,按空格进行切换模式,移动旋转缩放
在这里插入图片描述

代码编写

所有引入的头文件都需要放在 #include “openDoor.generated.h” 之前。
定义ATriggerVolume的指针,添加UPROPERTY(EditAnywhere),这样表示可以在任意地方赋值。
所以可以在界面上进行赋值。


#include <Engine/TriggerVolume.h>

UPROPERTY(EditAnywhere)
ATriggerVolume* trigger;

赋值如图:
选中门,然后选中自定义的组件openDoor
在这里插入图片描述

在这里插入图片描述

编译完成,会添加Trigger
在这里插入图片描述

在这里插入图片描述

然后选中TriggerVolume即可。

划重点:
pawn = GetWorld()->GetFirstPlayerController()->GetPawn(); // 得到defaultPawn

这句代码不能放到构造函数里面,否则编译会造成虚幻的崩溃。

给密室添加屋顶

这里使用玻璃作为屋顶。
在这里插入图片描述
添加玻璃,然后使用缩放工具进行调整,盖满整个房间即可。

打印日志

UE4里面日志,使用UE_LOG,第一个参数默认是LogTemp,第二个参数是日志类型,警告是Warning,字符串使用TEXT() 括起来。
UE_LOG(LogTemp, Warning, TEXT("%s begin openDoor()"), *owner->GetName());

控制系统角色

运行,然后F8弹出,能看到一个DefaultPawn,这个是系统默认角色。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

创建一个新游戏模式替换DefaultPawn

在这里插入图片描述
创建以后,指定pawn为刚才创建的对象。
运行,F8,pawn就是我们自定义的pawn了。
在这里插入图片描述

添加抓取组件

在这里插入图片描述

获取起点和终点


FVector start;
	FRotator viewRot;
	GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(start, viewRot);

	FVector end = start + viewRot.Vector() * 100; // 100cm
	DrawDebugLine(GetWorld(), start, end, FColor(255, 0, 0), false, 0.0f, 0, 10.0f);

物体拾取,碰撞属性设置

在检查碰撞的时候,只检测ECollisionChannel::ECC_PhysicsBody类别的物体。

设置物体属性:
在这里插入图片描述

今日完整代码

openDoor.h


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

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "openDoor.generated.h"

class AActor;
class ATriggerVolume;
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class MYPROJECT_API UopenDoor : public UActorComponent
{
	GENERATED_BODY()

public:	
	// Sets default values for this component's properties
	UopenDoor();

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

public:	
	// Called every frame
	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
	void openDoor();
	void closeDoor();
		
private:
	AActor* owner;
	AActor* pawn;
	UPROPERTY(EditAnywhere)
	ATriggerVolume* trigger;
	float openTime = 0.4f;
	float lastTime = 0.0f;
};


openDoor.cpp


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

#include "openDoor.h"
#include <GameFramework/Actor.h>
#include <Engine/TriggerVolume.h>
#include <Engine/World.h>

// Sets default values for this component's properties
UopenDoor::UopenDoor()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	PrimaryComponentTick.bCanEverTick = true;
}


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

/*	openDoor();*/


	owner = GetOwner();
	pawn = GetWorld()->GetFirstPlayerController()->GetPawn();  // 得到defaultPawn
	UE_LOG(LogTemp, Warning, TEXT("%s begin openDoor()"), *owner->GetName());
}


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

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

void UopenDoor::openDoor()
{
	// pitch=y yaw=z roll=x
/*	FRotator newRotator = FRotator(0, 0, 0);*/
	FRotator newRotator = FRotator(0, 180, 0);
	owner->SetActorRotation(newRotator);
}

void UopenDoor::closeDoor()
{
	// pitch=y yaw=z roll=x
	FRotator newRotator = FRotator(0, 90, 0);
	owner->SetActorRotation(newRotator);
}


grabber.h


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

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "grabber.generated.h"


UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class MYPROJECT_API Ugrabber : public UActorComponent
{
	GENERATED_BODY()

public:	
	// Sets default values for this component's properties
	Ugrabber();

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

public:	
	// Called every frame
	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;

private:
	FVector getLineStart();
	FVector getLineEnd();
	AActor* lineTrace();
};

grabber.cpp


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


#include "grabber.h"
#include <Engine/World.h>
#include <DrawDebugHelpers.h>

// Sets default values for this component's properties
Ugrabber::Ugrabber()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	PrimaryComponentTick.bCanEverTick = true;

	// ...
}

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

	// ...
	
}

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

FVector Ugrabber::getLineStart()
{
	// 设置起点和终点,画射线
	FVector start;
	FRotator viewRot;
	GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(start, viewRot);
	return start;
}

FVector Ugrabber::getLineEnd()
{
	FVector start;
	FRotator viewRot;
	GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(start, viewRot);

	return start + viewRot.Vector() * 100; // 100cm
}

AActor* Ugrabber::lineTrace()
{
	// 检查碰撞
	FHitResult hit;
	GetWorld()->LineTraceSingleByObjectType(hit, getLineStart(), getLineEnd(), FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody),
		FCollisionQueryParams(FName(TEXT(""), false, GetOwner()));

	AActor * act = hit.GetActor();
	if (nullptr != act)
	{
		UE_LOG(LogTemp, Warning, TEXT(line hit : % s), *act->GetName());
	}
	return act;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值