自动门

基础内容

Posted by AIaimuti on April 27, 2020

今天要做的是一个机关门,踩到地上机关,门开启,且可以延时关闭

自动门

触发盒子及机关声明

UPROPERTY(EditAnywhere, BlueprintReadWrite)
class UBoxComponent * TriggerBox;

UPROPERTY(EditAnywhere, BlueprintReadWrite)
class UStaticMeshComponent * FloorSwitch;

UPROPERTY(EditAnywhere, BlueprintReadWrite)
class UStaticMeshComponent * Door;

触发盒子及机关配置

添加头文件:
#include “Components/BoxComponent.h”
#include “Components/StaticMeshComponent.h”
SetCollisionEnabled(ECollisionEnabled::QueryOnly)
ECollisionEnabled 有4个参数
NoCollision 无碰撞
QueryOnly 仅询问,没有物理碰撞,会有重叠
PhysicsOnly 只有物理碰撞,阻挡效果
QueryAndPhysics 两种都关心,询问和物理碰撞

TriggerBox = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerBox"));
RootComponent = TriggerBox;
//选择碰撞类型,仅询问,即可以重叠
TriggerBox->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
//设置自己是世界静态物体
TriggerBox->SetCollisionObjectType(ECollisionChannel::ECC_WorldStatic);
//将所以通道设置为忽略
TriggerBox->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
//对Pawn设置重叠
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);

相关函数声明

BlueprintImplementableEvent

函数在蓝图中实现

//上升门
UFUNCTION(BlueprintImplementableEvent)
	void RaiseDoor();
//下降门
UFUNCTION(BlueprintImplementableEvent)
	void LowerDoor();
//上升机关
UFUNCTION(BlueprintImplementableEvent)
	void RaiseFloorSwitch();
//下降机关
UFUNCTION(BlueprintImplementableEvent)
	void LowerFloorSwitch();

DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SixParams

带DECLARE_DYNAMIC_MULTICAST_DELEGATE前缀的是一种动态委托的宏,这种宏采用AddDynamic绑定自定义函数, 自定义函数参数必须和宏定义中的参数声明形式相同,且.h文件中声明自定义函数前面需要加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(BlueprintCallable)
	void UpdateDoorLocation(float Z);
//更新机关的位置
UFUNCTION(BlueprintCallable)
	void UpdateSwitchLocation(float Z);

相关函数定义

添加头文件: #include “TimerManager.h” 碰撞函数的绑定是动态生成的,不要放在构造函数,可能会出问题,因此放在BeginPlay()

void AFloorSwitch::BeginPlay()
{
	Super::BeginPlay();
	TriggerBox->OnComponentBeginOverlap.AddDynamic(this, &AFloorSwitch::OnOverlapBegin);
	TriggerBox->OnComponentEndOverlap.AddDynamic(this, &AFloorSwitch::OnOverlapEnd);
	
}

在重合触发盒子的时候,开门,降下机关,同时关闭计时器, 离开触发盒子的时候,关门,开始计时器,起到延时关闭的效果

void AFloorSwitch::OnOverlapBegin(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
	UE_LOG(LogTemp, Warning, TEXT("Overlap Begin"));
	//关闭计时器
	GetWorldTimerManager().ClearTimer(TimerHandle);
	RaiseDoor();
	LowerFloorSwitch();
}

void AFloorSwitch::OnOverlapEnd(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex)
{
	UE_LOG(LogTemp, Warning, TEXT("Overlap End"));
	//开启计时器
	GetWorldTimerManager().SetTimer(TimerHandle, this, &AFloorSwitch::CloseDoor, SwitchTime);
	//LowerDoor();
	//RaiseFloorSwitch();
}
void AFloorSwitch::CloseDoor()
{
	LowerDoor();
	RaiseFloorSwitch();
}

这两个函数用于蓝图实现,起到改变开关和门的位置的效果

void AFloorSwitch::UpdateDoorLocation(float Z)
{
	FVector NewLocation = InitialDoorLocation;
	NewLocation.Z += Z;
	Door->SetWorldLocation(NewLocation);
}

void AFloorSwitch::UpdateSwitchLocation(float Z)
{
	FVector NewLocation = InitialSwitchLocation;
	NewLocation.Z += Z;
	FloorSwitch->SetWorldLocation(NewLocation);
}

替换机关和门

选中物体–>在World Outliner中右键选中的物体Browse to Asset–>在资源浏览器中选中物体–>蓝图中向左箭头 选中物体右键Pilot + 物体名字,可以控制该物体飞 transform的数值可以复制