码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2020-07-05 15:12:38      阅读:80      评论:0      收藏:0      [点我收藏+]

标签:bin   rem   tin   tde   清零   inline   editor   lib   游戏   

在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 "Components\BoxComponent.h"
  6 #include "UObject\ConstructorHelpers.h"
  7 #include "Components\StaticMeshComponent.h"
  8 #include "Components\SphereComponent.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学习(四)—— 定时器

标签:bin   rem   tin   tde   清零   inline   editor   lib   游戏   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!