基于C++代码的UE4学习(八)—— 自定义代理结合Timer实现道具的消失与重生

2021-04-23 06:28

阅读:647

标签:icm   cube   world   class   handle   err   nts   ue4   ++   

依照题目可以知道我们今天要实现的功能是道具的消失与重生。

这里就涉及到道具如何消失,如何重生的问题。

我们规定:

当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 "Components\StaticMeshComponent.h"
 6 #include "Components\BoxComponent.h"
 7 #include "UObject\ConstructorHelpers.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(TEXT("myStaticMesh"));
18     box = CreateDefaultSubobject(TEXT("box"));
19     box->InitBoxExtent(FVector(80.0f));
20     RootComponent = box;
21     myStaticMesh->SetupAttachment(GetRootComponent());
22 
23     auto myStaticMeshAssets = ConstructorHelpers::FObjectFinder(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(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::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实现道具的消失与重生

标签:icm   cube   world   class   handle   err   nts   ue4   ++   

原文地址:https://www.cnblogs.com/dlak/p/13272550.html


评论


亲,登录后才可以留言!