UE4日记8(盒体触发器|自动门)

创C++类

继承actor

 头文件

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "FloorSwitch.generated.h"

UCLASS()
class TTT_API AFloorSwitch : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AFloorSwitch();
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
		class UBoxComponent* TriggerBox;//盒体触发器

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
		class UStaticMeshComponent* FloorSwitch;//踏板

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
		class UStaticMeshComponent* Door;//门

	UPROPERTY(BlueprintReadWrite)
		FVector InitialSwitchLocation;//踏板原始位置
	UPROPERTY(BlueprintReadWrite)
		FVector InitialDoorLocation;//门原始位置

	FTimerHandle TimerHandle;//计时器句柄

	UPROPERTY(EditAnywhere,BlueprintReadWrite)
		float SwitchTime;//关门时间
	UFUNCTION()
		void CloseDoor();//关门函数

	UFUNCTION()//委托函数:UFUNCTION()	开始重叠与结束重叠
		void OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex ,bool bFromSweep ,const FHitResult& SweepResult);
	UFUNCTION()
		void OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

	UFUNCTION(BlueprintImplementableEvent)//蓝图实施事件
		void RaiseDoor();
	UFUNCTION(BlueprintImplementableEvent)
		void LowerDoor();
	UFUNCTION(BlueprintImplementableEvent)
		void RaiseDoorSwitch();
	UFUNCTION(BlueprintImplementableEvent)
		void LowerDoorSwitch();
	
	UFUNCTION(BlueprintCallable)//蓝图可调用
		void UpdateDoorLocation(float Z);
	UFUNCTION(BlueprintCallable)
		void UpdateSwitchLocation(float Z);
protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

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

};

代码文件

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


#include "FloorSwitch.h"
#include "Components/StaticMeshComponent.h"//静态网格组件
#include "Components/BoxComponent.h"//盒体组件
#include "TimerManager.h"//延时执行
// Sets default values
AFloorSwitch::AFloorSwitch()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	/********触发器***********/
	TriggerBox = CreateDefaultSubobject<UBoxComponent>(TEXT("Trigger Box"));
	RootComponent = TriggerBox;

	//触发器用
	//只查询角色是否在盒子上//即触发器,不阻挡
	TriggerBox->SetCollisionEnabled(ECollisionEnabled::QueryOnly);

	//channel作用对象,response作用类型
	

	//设置自身的碰撞类型
	TriggerBox->SetCollisionObjectType(ECollisionChannel::ECC_WorldStatic);

	//设置对其他对象的碰撞
	//先对所有对象不碰撞
	TriggerBox->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
	//单独对 角色,可重叠
	TriggerBox->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn,ECollisionResponse::ECR_Overlap);
	TriggerBox->SetBoxExtent(FVector(64, 64, 32));


	/***********踏板与门*****************/
	FloorSwitch=CreateDefaultSubobject<UStaticMeshComponent>(TEXT("FloorSwitch"));
	FloorSwitch->SetupAttachment(RootComponent);
	Door=CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Door"));
	Door->SetupAttachment(RootComponent);

	Door->SetCollisionObjectType(ECollisionChannel::ECC_WorldStatic);
	Door->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
	//Door->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn,ECollisionResponse::ECR_Block);

	SwitchTime = 2;//延时关门时间为2秒
}

void AFloorSwitch::CloseDoor()
{
	LowerDoor();
}

void AFloorSwitch::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	UE_LOG(LogTemp,Warning,TEXT("OnOverlapBegin"));
	GetWorldTimerManager().ClearTimer(TimerHandle);//清除计时器(重要)
	RaiseDoor();
	LowerDoorSwitch();
}

void AFloorSwitch::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	UE_LOG(LogTemp, Warning, TEXT("OnOverlapEnd"));
	GetWorldTimerManager().SetTimer(TimerHandle, this, &AFloorSwitch::CloseDoor,SwitchTime);//延时关门
	RaiseDoorSwitch();
}


/*更新门位置函数*/
void AFloorSwitch::UpdateDoorLocation(float Z)
{
	Door->SetWorldLocation(InitialDoorLocation + FVector(0,0,Z));
}

/*更新踏板位置函数*/
void AFloorSwitch::UpdateSwitchLocation(float Z)
{
	FloorSwitch->SetWorldLocation(InitialSwitchLocation+ FVector(0, 0, Z));
}

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

	//角色与人物开始重叠与结束重叠
	//为重叠和结束重叠增加动态绑定
	TriggerBox->OnComponentBeginOverlap.AddDynamic(this, &AFloorSwitch::OnOverlapBegin);
	TriggerBox->OnComponentEndOverlap.AddDynamic(this, &AFloorSwitch::OnOverlapEnd);

	InitialDoorLocation = Door->GetComponentLocation();//初始门位置赋初值
	InitialSwitchLocation = FloorSwitch->GetComponentLocation();//初始踏板位置赋初值
}

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

}

创建类

 

 

 


总结

角色踩上去,门会升起来,2秒后落下。运用了计时器延时执行和清除计时器,就不会出现当角色踩上去了,门落下的情况。

猜你喜欢

转载自blog.csdn.net/weixin_56537692/article/details/128799234
今日推荐