基于C++代码的UE4学习—— 自定义代理结合Timer实现道具的消失与重生
Posted dlak
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于C++代码的UE4学习—— 自定义代理结合Timer实现道具的消失与重生相关的知识,希望对你有一定的参考价值。
依照题目可以知道我们今天要实现的功能是道具的消失与重生。
这里就涉及到道具如何消失,如何重生的问题。
我们规定:
当StartPlayer触碰到道具的时候,道具就消失,间隔5秒钟之后,道具再次在原点重生。
文中的提及的Cube类是AMyActor_Cube类的简称。
文中的提及的Spawn类是AMyActor_Spawn类的简称。
先定义一个ACTOR类的派生类,作为道具,载入任意一个模型即可,这里是载入了Cube模型,并增加了Box类型碰撞体。
以下是Cube类的头文件代码:
请注意第10行,我们宣布了一个代理,这个代理是自己自定义的,也就是说,名字是随便起的。
在32行声明了一个该代理的对象。
1 // Fill out your copyright notice in the Description page of Project Settings. 2 3 #pragma once 4 5 #include "CoreMinimal.h" 6 #include "GameFramework/Actor.h" 7 #include "MyActor_Cube.generated.h" 8 9 10 DECLARE_DELEGATE(MyDelegateSignature) 11 12 UCLASS() 13 class MYPROJECT5_API AMyActor_Cube : public AActor 14 { 15 GENERATED_BODY() 16 17 public: 18 // Sets default values for this actor‘s properties 19 AMyActor_Cube(); 20 21 protected: 22 // Called when the game starts or when spawned 23 virtual void BeginPlay() override; 24 25 public: 26 // Called every frame 27 virtual void Tick(float DeltaTime) override; 28 29 public: 30 class UStaticMeshComponent* myStaticMesh; 31 class UBoxComponent* box; 32 MyDelegateSignature mySig; 33 virtual void NotifyActorBeginOverlap(AActor* actor)override; 34 FRotator rotate; 35 };
以下是Cube类的源文件代码:
当Cube类的对象被overlap的时候,就会触发代理执行。
1 // Fill out your copyright notice in the Description page of Project Settings. 2 3 4 #include "MyActor_Cube.h" 5 #include "ComponentsStaticMeshComponent.h" 6 #include "ComponentsBoxComponent.h" 7 #include "UObjectConstructorHelpers.h" 8 #include "Engine.h" 9 10 11 // Sets default values 12 AMyActor_Cube::AMyActor_Cube() 13 { 14 // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don‘t need it. 15 PrimaryActorTick.bCanEverTick = true; 16 17 myStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("myStaticMesh")); 18 box = CreateDefaultSubobject<UBoxComponent>(TEXT("box")); 19 box->InitBoxExtent(FVector(80.0f)); 20 RootComponent = box; 21 myStaticMesh->SetupAttachment(GetRootComponent()); 22 23 auto myStaticMeshAssets = ConstructorHelpers::FObjectFinder<UStaticMesh>(TEXT("StaticMesh‘/Engine/BasicShapes/Cube.Cube‘")); 24 25 if (myStaticMeshAssets.Succeeded()) { 26 myStaticMesh->SetStaticMesh(myStaticMeshAssets.Object); 27 myStaticMesh->SetWorldScale3D(FVector(0.8f)); 28 myStaticMesh->SetSimulatePhysics(false); 29 myStaticMesh->SetEnableGravity(false); 30 } 31 32 rotate = FRotator(0.0f); 33 } 34 35 // Called when the game starts or when spawned 36 void AMyActor_Cube::BeginPlay() 37 { 38 Super::BeginPlay(); 39 40 } 41 42 // Called every frame 43 void AMyActor_Cube::Tick(float DeltaTime) 44 { 45 Super::Tick(DeltaTime); 46 myStaticMesh->SetRelativeRotation(FRotator(10.0f*DeltaTime + rotate.Pitch,0.0f,10.0f*DeltaTime + rotate.Roll)); 47 48 rotate.Pitch += 0.1f; 49 rotate.Roll += 0.1f; 50 } 51 52 void AMyActor_Cube::NotifyActorBeginOverlap(AActor* actor) 53 { 54 GEngine->AddOnScreenDebugMessage(-1,5,FColor::Blue,TEXT("Touch!")); 55 mySig.ExecuteIfBound(); 56 }
那具体执行什么呢?当然是执行消失与重生了。我们再创建一个ACTOR类的派生类Spawn,用于管理Cube类的消失与重生功能。
由于需要定时重生,所以这里肯定会用到FTimerHandle结构体(之前文章都习惯性的说成类,理解意思就好)。
以下是Spawn类的头文件代码:
1 // Fill out your copyright notice in the Description page of Project Settings. 2 3 #pragma once 4 5 #include "CoreMinimal.h" 6 #include "GameFramework/Actor.h" 7 #include "MyActor_Cube.h" 8 #include "MyActor_Spawn.generated.h" 9 10 UCLASS() 11 class MYPROJECT5_API AMyActor_Spawn : public AActor 12 { 13 GENERATED_BODY() 14 15 public: 16 // Sets default values for this actor‘s properties 17 AMyActor_Spawn(); 18 19 protected: 20 // Called when the game starts or when spawned 21 virtual void BeginPlay() override; 22 23 public: 24 // Called every frame 25 virtual void Tick(float DeltaTime) override; 26 27 public: 28 UPROPERTY() 29 class USceneComponent* scene; 30 31 UFUNCTION() 32 void spawnActor(); 33 34 UFUNCTION() 35 void managementActor(); 36 37 UPROPERTY() 38 FTimerHandle myTimer; 39 40 UPROPERTY() 41 AMyActor_Cube* myActorCube; 42 };
新定义两个方法,一个方法用于重生Cube,一个方法用于管理Cube。
既然是要和Cube类的对象发生交互,千万不要忘记导入Cube类的头文件。.
以下是Spawn类的源文件代码:
1 // Fill out your copyright notice in the Description page of Project Settings. 2 3 4 #include "MyActor_Spawn.h" 5 6 // Sets default values 7 AMyActor_Spawn::AMyActor_Spawn() 8 { 9 // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don‘t need it. 10 PrimaryActorTick.bCanEverTick = true; 11 scene = CreateDefaultSubobject<USceneComponent>(TEXT("Scene")); 12 RootComponent = scene; 13 14 } 15 16 // Called when the game starts or when spawned 17 void AMyActor_Spawn::BeginPlay() 18 { 19 Super::BeginPlay(); 20 spawnActor(); 21 22 } 23 24 // Called every frame 25 void AMyActor_Spawn::Tick(float DeltaTime) 26 { 27 Super::Tick(DeltaTime); 28 29 } 30 31 void AMyActor_Spawn::spawnActor() 32 { 33 myActorCube = GetWorld()->SpawnActor<AMyActor_Cube>(AMyActor_Cube::StaticClass(), GetTransform()); 34 myActorCube->mySig.BindUObject(this, &AMyActor_Spawn::managementActor); 35 } 36 37 void AMyActor_Spawn::managementActor() 38 { 39 GetWorld()->GetTimerManager().SetTimer(myTimer, this, &AMyActor_Spawn::spawnActor, 5, false); 40 myActorCube->mySig.Unbind(); 41 myActorCube->Destroy(); 42 }
先来设计生成Cube类对象的代码,在spawmActor方法中,在世界里产生一个AMyActor_Cube类的实例,并将该实例的代理绑定在Spawn类中的managementActor方法上。
也就是说,当Cube类的对象被Overlap的时候,会开始执行这个被绑定的managementActor方法。
managementActor方法触发后,会每隔5秒钟,调用spawnActor方法,以此往复,这里需要注意的是managementActor里的Timer的LOOP属性设定必须给到false,否则会不断复制,造成管理失控。
因为触碰到Cube类的对象后,该对象会消失,所以Spawn类中的Cube类的指针指向的代理得先解绑,再将对象销毁。
效果图如下:
触碰后物体消失,左上角有提示信息
过5秒钟之后,再次产生一个Cube类的对象。
以上是关于基于C++代码的UE4学习—— 自定义代理结合Timer实现道具的消失与重生的主要内容,如果未能解决你的问题,请参考以下文章
虚幻引擎 4 (ue4) 中带有自定义 c++ 蓝图函数库的蓝图循环/for/while 节点