基于C++代码的UE4学习(四)—— 定时器

摘要:
15//设置此角色属性的默认值16A碰撞角色();2930私有:4142受保护:47//调用每个帧48虚拟控件(floatDeltaTime)覆盖;Category=“Properties”)63UClass*parentClass;

在UE中有专门的类用来完成定时器的功能,它就是FTimerHandle类。

我们来完成一个例子,每隔一段时间之后,让一个ACTOR自我复制,在一定范围内随机生成。

这是ACTOR的头文件:

 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 "CollisionActor.generated.h"
 8 
 9 UCLASS()
10 class MYPROJECT6_API ACollisionActor : public AActor
11 {
12     GENERATED_BODY()
13     
14 public:    
15     // Sets default values for this actor's properties
16     ACollisionActor();
17 
18 public:
19     UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Properties")
20     class UStaticMeshComponent* myStaticMesh;
21 
22     FORCEINLINE UStaticMeshComponent* GetmyStaticMesh() {
23         return myStaticMesh;
24     }
25 
26 
27     UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Properties")
28     class USphereComponent* myCollision;
29 
30 private:
31     FScriptDelegate startsOverlap;
32     FScriptDelegate endsOverlap;
33 public:
34     UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Properties")
35     bool status;
36 public:
37     UFUNCTION(BlueprintCallable,Category = "FUNCTIONS")
38     void onOverlap();
39     UFUNCTION(BlueprintCallable, Category = "FUNCTIONS")
40     void endOverlap();
41 
42 protected:
43     // Called when the game starts or when spawned
44     virtual void BeginPlay() override;
45 
46 public:    
47     // Called every frame
48     virtual void Tick(float DeltaTime) override;
49 
50 
51 public:
52     UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Properties")
53     FTimerHandle StarTimer;
54 
55     UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Properties")
56     FTimerHandle EndTimer;
57 
58     UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Properties")
59     float timeInterval;
60 
61 
62     UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Properties")
63     UClass* parentClass;
64 
65     UFUNCTION(BlueprintCallable, Category = "FUNCTIONS")
66     virtual void EndPlay(EEndPlayReason::Type EndReason) override;
67 
68     UFUNCTION(BlueprintCallable, Category = "FUNCTIONS")
69     void spawnSelf();
70 
71     UFUNCTION(BlueprintCallable, Category = "FUNCTIONS")
72     void deletes();
73 };

这些代码是新增在头文件中的:

 1 public:
 2     UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Properties")
 3     FTimerHandle StarTimer;
 4 
 5     UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Properties")
 6     FTimerHandle EndTimer;
 7 
 8     UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Properties")
 9     float timeInterval;
10 
11 
12     UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Properties")
13     UClass* parentClass;
14 
15     UFUNCTION(BlueprintCallable, Category = "FUNCTIONS")
16     virtual void EndPlay(EEndPlayReason::Type EndReason) override;
17 
18     UFUNCTION(BlueprintCallable, Category = "FUNCTIONS")
19     void spawnSelf();
20 
21     UFUNCTION(BlueprintCallable, Category = "FUNCTIONS")
22     void deletes();
23 };

拥有两个处理TImer的对象,一个为start一个为end,他们分别会在BeginPlay和EndPlay两个继承自父类并重写后的函数中实现。spawnSelf函数用来创建自身,deletes函数用来销毁自身,以免内存过载。

以下是ACTOR的源文件:

  1 // Fill out your copyright notice in the Description page of Project Settings.
  2 
  3 
  4 #include "CollisionActor.h"
  5 #include "ComponentsBoxComponent.h"
  6 #include "UObjectConstructorHelpers.h"
  7 #include "ComponentsStaticMeshComponent.h"
  8 #include "ComponentsSphereComponent.h"
  9 #include "Engine.h"
 10 
 11 // Sets default values
 12 ACollisionActor::ACollisionActor()
 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     myStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("myStaticMesh"));
 17     myCollision = CreateDefaultSubobject<USphereComponent>(TEXT("myCollision"));
 18 
 19     auto myMeshAsset = ConstructorHelpers::FObjectFinder<UStaticMesh>(TEXT("StaticMesh'/Engine/EditorMeshes/ColorCalibrator/SM_ColorCalibrator.SM_ColorCalibrator'"));
 20     auto myMatAsset = ConstructorHelpers::FObjectFinder<UMaterialInterface>(TEXT("Material'/Engine/VREditor/UI/ArrowMaterial.ArrowMaterial'"));
 21 
 22     if (myMeshAsset.Succeeded() && myMatAsset.Succeeded()) {
 23         myStaticMesh->SetStaticMesh(myMeshAsset.Object);
 24         myStaticMesh->SetMaterial(0, myMatAsset.Object);
 25     }
 26     if (!myStaticMesh->IsSimulatingPhysics()) {
 27         myStaticMesh->SetSimulatePhysics(true);
 28         myStaticMesh->SetEnableGravity(false);
 29     }
 30 
 31     RootComponent = myCollision;
 32     myStaticMesh->SetupAttachment(GetRootComponent());
 33     myCollision->InitSphereRadius(120.f);
 34 
 35     startsOverlap.BindUFunction(this, "onOverlap");
 36     myCollision->OnComponentBeginOverlap.Add(startsOverlap);
 37 
 38 
 39     endsOverlap.BindUFunction(this, "endOverlap");
 40     myCollision->OnComponentEndOverlap.Add(endsOverlap);
 41 
 42     status = false;
 43 
 44     parentClass = ACollisionActor::StaticClass();
 45 
 46 
 47     timeInterval = 5.0f;
 48 
 49 }
 50 
 51 void ACollisionActor::onOverlap()
 52 {
 53     GEngine->AddOnScreenDebugMessage(-1, 5, FColor::Red, TEXT("Touch"));
 54     status = true;
 55     
 56 }
 57 
 58 void ACollisionActor::endOverlap()
 59 {
 60     GEngine->AddOnScreenDebugMessage(-1, 5, FColor::Red, TEXT("OutTouch"));
 61     status = false;
 62 }
 63 
 64 
 65 // Called when the game starts or when spawned
 66 void ACollisionActor::BeginPlay()
 67 {
 68     Super::BeginPlay();
 69 
 70     GetWorld()->GetTimerManager().SetTimer(StarTimer,this,&ACollisionActor::spawnSelf, timeInterval,true);
 71     GetWorld()->GetTimerManager().SetTimer(EndTimer,this,&ACollisionActor::spawnSelf, timeInterval*8,true);
 72 
 73 }
 74 
 75 
 76 
 77 void ACollisionActor::spawnSelf() {
 78     FVector location = FVector(FMath::RandRange(-1000.0f,1000.0f), FMath::RandRange(-1000.0f, 1000.0f), FMath::RandRange(-1000.0f, 1000.0f));
 79     GetWorld()->SpawnActor(parentClass,&location);
 80 }
 81 
 82 void ACollisionActor::EndPlay(EEndPlayReason::Type EndReason)
 83 {
 84     Super::EndPlay(EndReason);
 85     GetWorld()->GetTimerManager().ClearTimer(StarTimer);
 86     GetWorld()->GetTimerManager().ClearTimer(EndTimer);
 87 
 88 }
 89 
 90 
 91 void ACollisionActor::deletes()
 92 {
 93     Destroy();
 94 }
 95 
 96 // Called every frame
 97 void ACollisionActor::Tick(float DeltaTime)
 98 {
 99     Super::Tick(DeltaTime);
100 
101     if (status == true) {
102         myStaticMesh->AddLocalRotation(FRotator(10.0f));
103     }
104     else {
105         myStaticMesh->AddLocalRotation(FRotator(0.0f));
106         myStaticMesh->SetRelativeRotation(FRotator(0.0f));
107     }
108 }

想要得到计时器的对象,就得先从世界中获得时间管理对象:

1 GetWorld()->GetTimerManager().SetTimer(StarTimer,this,&ACollisionActor::spawnSelf, timeInterval,true);

通过GetWolrd()获得世界的指针,再调用GetTimerManager()对象,调用SetTimer函数来设置计时器。

SetTimer常用有四个参数,分别是FTimerHandle类的修,该计时器指向哪个类,该计时器绑定哪个方法,计时器的时间间隔,以及是否循环。

StartTimer这个计时器对象绑定了SpawnSelf方法,通过SpawnActor方法进行自我复制,这里需要传入两个参数,第一个是复制哪个类对象,第二个是在世界里的位置。

这里的parentClass指针实际上是指向UClass *parentClass = ACollisionActor::StaticClass();,也就是指向了自己,也就不断自我复制。

1 void ACollisionActor::spawnSelf() {
2     FVector location = FVector(FMath::RandRange(-1000.0f,1000.0f), FMath::RandRange(-1000.0f, 1000.0f), FMath::RandRange(-1000.0f, 1000.0f));
3     GetWorld()->SpawnActor(parentClass,&location);
4 }

结束Play后调用以下方法,实现计时器清零。

EndPlay方法是继承而来的,还需要写入参数,意思是给一个结束游戏的理由,在枚举型结构体中的EEndplayReason::Type中,EndReason是各种结束理由的形式参数。

找到GetTimerManager之后,通过ClearTimer方法将我们的FTimerHandle类的对象放进去,对其清零。

1 void ACollisionActor::EndPlay(EEndPlayReason::Type EndReason)
2 {
3     Super::EndPlay(EndReason);
4     GetWorld()->GetTimerManager().ClearTimer(StarTimer);
5     GetWorld()->GetTimerManager().ClearTimer(EndTimer);

以下方法用于销毁自身。

1 void ACollisionActor::deletes()
2 {
3     Destroy();
4 }

以下方法用于触发碰撞体之后,进行旋转。

 1 void ACollisionActor::Tick(float DeltaTime)
 2 {
 3     Super::Tick(DeltaTime);
 4 
 5     if (status == true) {
 6         myStaticMesh->AddLocalRotation(FRotator(10.0f));
 7     }
 8     else {
 9         myStaticMesh->AddLocalRotation(FRotator(0.0f));
10         myStaticMesh->SetRelativeRotation(FRotator(0.0f));
11     }
12 }

最终效果实现如下:

基于C++代码的UE4学习(四)—— 定时器第1张

免责声明:文章转载自《基于C++代码的UE4学习(四)—— 定时器》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇从mysql数据库删除重复记录只保留其中一条(保留id最小的一条)js 千分位(分转元,万转元...)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

fancyBox简单入门

1. 下载 fancyBox,解压后根据需要将文件复制到网页文件夹中(建议不要更改目录结构),并在网页源码中引入相应的 css 样式和 js 文件(如果更改了目录结构,引入的时候请调整相应代码,对应它们所在的路径)。注意:别忘了还要先加载 jQuery 库! <!-- 加载 jQuery 库(必须) --> <script type="t...

通过sqlplus执行sql脚本并生成log

如何在sqlplus中执行sql脚本 [1]登陆Sqlplus 请输入用户名 sys/admin@orcl as sysdba 成功后,可以执行导入 [2]执行 SQL>@ c:\sql\unitdata.sql  如果是在linux就执行start /tmp/shp/beijing_region.shp 你就可以看到提示执行的结果 如何生成sqlp...

WPF实现无刷新动态切换多语言(国际化)

1. 在WPF中国际化使用的是 .xaml文件的格式       如图:Resource Dictionary (WPF)        2. 创建默认的语言文件和其他语言文件        这里以英语为默认语言,新建一个 Resource Dictionary (WPF)文件,并命名为DefaultLanguage.xaml,内容如下:    <R...

vue项目动态新增表单、图片、文件

<div class="type_box" v-for="(item,index) in attrList" :key="item.id"> <div class="add-row"> <span class="label-span">key<...

WPF利用Image实现图片按钮

  之前有一篇文章也是采用了Image实现的图片按钮,不过时间太久远了,忘记了地址。好吧,这里我进行了进一步的改进,原来的文章中需要设置4张图片,分别为可用时,鼠标悬浮时,按钮按下时,按钮不可用时的图片,这里我只用了一张图片,利用C#的图片灰度处理自动获得不可用时的图片,利用图片的间距实现悬浮及按下效果。先上效果:(正常 悬浮 按下 不可用)   代码其...

JavaScript 清空Session

      众所周知,Session是运行在服务器端的,JavaScript是运行在客户端的,JavaScript不能直接运行服务器端的代码。但最近笔者却遇到了这样的需求:在一个学习系统里面,用户不能同时打开两个在线考试或在线学习的窗口。通过打开模态对话框,的确可以禁止用户再打开一个新窗口,但如果用户重新打开一个新的页面,却可以打开一个新的对话框。    ...