UE4 C++学习笔记之初识时间轴,定时器

  任务:在场景中做一个开关门,角色踩上开关后,门打开,离开开关2s后门自动关闭

第一步、新建一个C++ Actor类命名为DoorSwitch,并编写相应代码

DoorSwitch.h代码如下:

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components\PrimitiveComponent.h"
#include "DoorSwitch.generated.h"

UCLASS()
class LEARNTEST_API ADoorSwitch : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ADoorSwitch();

        //Door的静态网格体
	UPROPERTY(EditAnywhere)
	class UStaticMeshComponent* DoorStaticMesh;

        //Switch的静态网格体
	UPROPERTY(EditAnywhere)
	class UStaticMeshComponent* SwitchStaticMesh;

         //触发器组件
	UPROPERTY(EditAnywhere)
	class UBoxComponent* TriggerBox;

        //用于储存Door初始化位置的向量
	UPROPERTY(VisibleAnywhere)
	FVector DoorInitLocation;
        
        //用于储存Switch初始位置的向量
	UPROPERTY(VisibleAnywhere)
	FVector SwitchInitLocation;

        //用于储存关门延迟时间延迟时间的向量
	UPROPERTY(EditAnywhere,Category = "Switch Variates")
	float WaitTime;

        //定时器句柄,开启和关闭定时器时需要使用该参数
	FTimerHandle TimerHandle;

        //关门函数,在定时器中调用
	UFUNCTION()
	void CloseDoor();

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

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

        //进入触发器时执行函数
	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 DoorUp();

        //关门函数,蓝图中实现
	UFUNCTION(BlueprintImplementableEvent)
	void DoorDown();

        //开关上升函数,蓝图中实现
	UFUNCTION(BlueprintImplementableEvent)
	void SwitchUp();

        //开关下降函数,蓝图中实现
	UFUNCTION(BlueprintImplementableEvent)
	void SwitchDown();

        //更新Door位置的函数,可在蓝图中调用
	UFUNCTION(BlueprintCallable)
	void UpdataDoorLocation(float Value);

        //更新Switch位置的函数,可在蓝图中调用
	UFUNCTION(BlueprintCallable)
	void UpdataSwitchLocation(float Value);

};

DoorSwitch.cpp代码如下:

#include "DoorSwitch.h"
#include "Components\BoxComponent.h"
#include "Engine\Public\TimerManager.h"
// Sets default values
ADoorSwitch::ADoorSwitch()
{
 	// 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;

        //创建门的静态网格体,并将其附着在根组件上
	DoorStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorStaticMesh"));
	DoorStaticMesh->SetupAttachment(RootComponent);

        //创建开关的静态网格体,并将其附着在根组件上
	SwitchStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SwitchStaticMesh"));
	SwitchStaticMesh->SetupAttachment(RootComponent);

        //创建触发器静态网格体,并将其设置为根组件
	TriggerBox = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerBox"));
	RootComponent = TriggerBox;

        //触发器相关碰撞预设,只对Pawn类型进行碰撞检测,其他的忽略
	TriggerBox->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
	TriggerBox->SetCollisionObjectType(ECollisionChannel::ECC_WorldStatic);
	TriggerBox->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
	TriggerBox->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn,ECollisionResponse::ECR_Overlap);

        //初始化关门延迟时间
	WaitTime = 2;

}

        //关门函数,在定时器中调用
void ADoorSwitch::CloseDoor()
{
	    //这两个函数在蓝图中,利用时间轴实现
    DoorDown();
	SwitchUp();
}

//更新Door的位置,蓝图中调用
void ADoorSwitch::UpdataDoorLocation(float Value)
{
	FVector NewLocation = DoorInitLocation;
	NewLocation.Z += Value;
	DoorStaticMesh->SetWorldLocation(NewLocation);
}

//更新Switch的位置,蓝图中调用
void ADoorSwitch::UpdataSwitchLocation(float Value)
{
	FVector NewLocation = SwitchInitLocation;
	NewLocation.Z += Value;
	SwitchStaticMesh->SetWorldLocation(NewLocation);
}

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

        //游戏开始时,获取初始的Door和Switch的位置
	DoorInitLocation = DoorStaticMesh->GetComponentLocation();
	SwitchInitLocation = SwitchStaticMesh->GetComponentLocation();

        //触发器绑定相应事件
	TriggerBox->OnComponentBeginOverlap.AddDynamic(this, &ADoorSwitch::OnOverlapBegin);
	TriggerBox->OnComponentEndOverlap.AddDynamic(this, &ADoorSwitch::OnOverlapEnd);
}

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

}

//进入触发区域(开关位置)时执行函数
void ADoorSwitch::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	UE_LOG(LogTemp, Warning, TEXT("SwitchON"));

        //关定时器
	GetWorldTimerManager().ClearTimer(TimerHandle);

        //关门
	DoorUp();
	SwitchDown();
}

//离开触发区域(开关位置)时执行函数
void ADoorSwitch::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	UE_LOG(LogTemp, Warning, TEXT("SwitchOFF"));

        //开启定时器,延时后触发CloseDoor函数
	GetWorldTimerManager().SetTimer(TimerHandle, this, &ADoorSwitch::CloseDoor,WaitTime);
}

第二步、以DoorSwitch C++类为父类建立蓝图类,在该蓝图类中设置门和开关的静态网格体,并且利用时间轴实现开门,关门函数

1、设置门和开关的静态网格体

2、利用时间轴实现开门,关门函数

猜你喜欢

转载自blog.csdn.net/weixin_44928892/article/details/108104167