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

文章目录

  • 添加机关
  • 代码编写
  • 给密室添加屋顶
  • 打印日志
  • 控制系统角色
  • 创建一个新游戏模式替换DefaultPawn
  • 添加抓取组件
  • 获取起点和终点
  • 物体拾取,碰撞属性设置
  • 今日完整代码

添加机关

首先向场景里面添加一个聚光源
UE4学习-添加机关并添加代码控制_第1张图片

添加聚光源以后,可以对其属性进行修改,如图:
UE4学习-添加机关并添加代码控制_第2张图片
然后需要给聚光源添加一个触发体积(TriggerVolume)。
UE4学习-添加机关并添加代码控制_第3张图片
然后调整触发体积的大小,按空格进行切换模式,移动旋转缩放
UE4学习-添加机关并添加代码控制_第4张图片

代码编写

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


#include 

UPROPERTY(EditAnywhere)
ATriggerVolume* trigger;

赋值如图:
选中门,然后选中自定义的组件openDoor
UE4学习-添加机关并添加代码控制_第5张图片

UE4学习-添加机关并添加代码控制_第6张图片

编译完成,会添加Trigger
UE4学习-添加机关并添加代码控制_第7张图片

UE4学习-添加机关并添加代码控制_第8张图片

然后选中TriggerVolume即可。

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

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

给密室添加屋顶

这里使用玻璃作为屋顶。

添加玻璃,然后使用缩放工具进行调整,盖满整个房间即可。

打印日志

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

控制系统角色

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

UE4学习-添加机关并添加代码控制_第9张图片

UE4学习-添加机关并添加代码控制_第10张图片

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

UE4学习-添加机关并添加代码控制_第11张图片
创建以后,指定pawn为刚才创建的对象。
运行,F8,pawn就是我们自定义的pawn了。

添加抓取组件

UE4学习-添加机关并添加代码控制_第12张图片

获取起点和终点


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类别的物体。

设置物体属性:
UE4学习-添加机关并添加代码控制_第13张图片

今日完整代码

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 
#include 
#include 

// 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 
#include 

// 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;
}

你可能感兴趣的:(UE4)