创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秒后落下。运用了计时器延时执行和清除计时器,就不会出现当角色踩上去了,门落下的情况。