标签: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 }
最终效果实现如下:
标签:bin rem tin tde 清零 inline editor lib 游戏
原文地址:https://www.cnblogs.com/dlak/p/13245984.html