这一节需要从三部分来讲,先讲解第一部分。

Construction与构造函数之间的关系。

构造函数是C++中的,Construction是蓝图中的,暂且理解为蓝图中的构造函数。

***但是,它们还是有区别的,Construction在C++中调用可以更改在构造函数中赋值好的属性值。

先定义一个ACTOR类,头文件内容如下,加粗的内容之前都学习过,这里不再赘述:

 

 1 #include "CoreMinimal.h"
 2 #include "GameFramework/Actor.h"
 3 #include "MyActor.generated.h"
 4 
 5 UCLASS()
 6 class ONCONSTRUCTION_API AMyActor : public AActor
 7 {
 8     GENERATED_BODY()
 9     
10 public:    
11     // Sets default values for this actor's properties
12     AMyActor();
13 
14 protected:
15     // Called when the game starts or when spawned
16     virtual void BeginPlay() override;
17 
18 public:    
19     // Called every frame
20     virtual void Tick(float DeltaTime) override;
21 
22     virtual void EndPlay(EEndPlayReason::Type EndReason) override;
23 
24     virtual void OnConstruction(const FTransform& Transform) override;
25 
26     virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
27 
28     UPROPERTY(EditAnywhere,BlueprintReadWrite)
29     bool show;
30 
31     UPROPERTY()
32     class UStaticMeshComponent* myStaticMesh;
33 
34 private:
35 
36     FTimerHandle myTimerHandle;
37     void setBomb();
38 };

 

重点是源文件:

 

 1 // Fill out your copyright notice in the Description page of Project Settings.
 2 
 3 
 4 #include "MyActor.h"
 5 #include "UObject/ConstructorHelpers.h"
 6 #include "Components/StaticMeshComponent.h"
 7 
 8 // Sets default values
 9 AMyActor::AMyActor()
10 {
11      // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
12     PrimaryActorTick.bCanEverTick = true;
13     myStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("myStaticMesh"));
14     auto asset = ConstructorHelpers::FObjectFinder<UStaticMesh>(TEXT("StaticMesh'/Engine/BasicShapes/Cube.Cube'"));
15     show = true;
16     if (asset.Succeeded()) {
17         myStaticMesh->SetStaticMesh(asset.Object);
18         myStaticMesh->SetMobility(EComponentMobility::Movable);
19     }
20 
21 }
22 
23 
24 void AMyActor::OnConstruction(const FTransform& Transform) {
25     //在构造函数中的初始化的属性被更改时候的代码,写在这里,它将重新构造更新。
26     show = false;
27     myStaticMesh->SetVisibility(show);
28 }
29 
30 void AMyActor::PostEditChangeProperty(FPropertyChangedEvent& events)
31 {
32     if (events.Property != nullptr) {
33         const FName propertyName = events.Property->GetFName();
34 
35         if (propertyName == GET_MEMBER_NAME_CHECKED(AMyActor, show)) {
36             myStaticMesh->SetVisibility(show);
37         }
38     }
39 }
40 
41 
42 
43 // Called when the game starts or when spawned
44 void AMyActor::BeginPlay()
45 {
46     Super::BeginPlay();
47     GetWorld()->GetTimerManager().SetTimer(myTimerHandle, this, &AMyActor::setBomb, 3.0f, true);
48     
49 }
50 
51 // Called every frame
52 void AMyActor::Tick(float DeltaTime)
53 {
54     Super::Tick(DeltaTime);
55
56     myStaticMesh->SetVisibility(show); 
57 
58 } 
59 
60 void AMyActor::EndPlay(EEndPlayReason::Type EndReason) 
61 { 
62     GetWorld()->GetTimerManager().ClearTimer(myTimerHandle); 
63 } 
64
65 void AMyActor::setBomb() { 
66     show = !show; 
67 }

 

 

构造函数是AMyActor,在里面将show属性设置为了true,这样会导致Cube在被构造的时候,是看得见的。

但是在OnConstruction函数中将show属性设置为了false。这样会导致Cube在被构造的时候,又成了看不见的。

 

 1 AMyActor::AMyActor()
 2 {
 3      // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
 4     PrimaryActorTick.bCanEverTick = true;
 5     myStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("myStaticMesh"));
 6     auto asset = ConstructorHelpers::FObjectFinder<UStaticMesh>(TEXT("StaticMesh'/Engine/BasicShapes/Cube.Cube'"));
 7     show = true;
 8     if (asset.Succeeded()) {
 9         myStaticMesh->SetStaticMesh(asset.Object);
10         myStaticMesh->SetMobility(EComponentMobility::Movable);
11     }
12 
13 }
14 
15 
16 void AMyActor::OnConstruction(const FTransform& Transform) {
17     //在构造函数中的初始化的属性被更改时候的代码,写在这里,它将重新构造更新。
18     show = false;
19     myStaticMesh->SetVisibility(show);
20 }

 

第二部分,我们将手动控制show属性,人为操纵将其可见与否进行设置。这里需要说明的是,PostEditChangeProperty方法只能相应人为操作(目前只实验出如此,如果可以自动的话,一定有别的方法,而我现在还不清楚,希望知道的可以告诉我,先谢谢了)

 

 1 void AMyActor::PostEditChangeProperty(FPropertyChangedEvent& events)
 2 {
 3     if (events.Property != nullptr) {
 4         const FName propertyName = events.Property->GetFName();
 5 
 6         if (propertyName == GET_MEMBER_NAME_CHECKED(AMyActor, show)) {
 7             myStaticMesh->SetVisibility(show);
 8         }
 9     }
10 }

 

 

第三部分,我不想手动控制,加一个Timer,用计时器来帮忙显示和关闭显示。

 

1 void AMyActor::BeginPlay()
 2 {
 3     Super::BeginPlay();
 4     GetWorld()->GetTimerManager().SetTimer(myTimerHandle, this, &AMyActor::setBomb, 3.0f, true);
 5     
 6 }
 7 
 8 void AMyActor::setBomb() {
 9     show = !show;
10 }
11 
12 void AMyActor::Tick(float DeltaTime)
13 {
14     Super::Tick(DeltaTime);
15 
16     myStaticMesh->SetVisibility(show);
17 
18 }

 

 

这里是放在Tick里去不断调用SetVisibility方法的,这一点很重要,因为PostEditChangeProperty方法无法响应Timer对属性的改变。

每隔三秒,show的值会取反,会改变,从而造成效果的改变,此时手动点击show属性一样可以改变。

 

 

更多推荐

基于C++代码的UE4学习(三十)——蓝图的Construction Script与TIMER结合的控制Cube显现