1. 创建一个使用定时器的Actor

开启和停止以固定频率运行代码的定时器。

Windows
MacOS
Linux
On this page

若初识 虚幻引擎4 ,建议先阅读编程快速入门 教程 。阅读此教程之前应先熟悉创建项目和添加C++代码的操作。

  1. 首先我们将新建一个包含初学者内容包的基础代码项目,命名为HowTo_VTE,然后为其添加一个 Actor 类。在此教程中我们将其命名为Countdown。

    ChooseParentClass.png

    NameYourActor.png

  2. 首先我们将创建一个游戏中可见的简单倒计时定时器。在Countdown.h中将以下代码行添加到类定义的末端:

    int32 CountdownTime;
    
    UTextRenderComponent* CountdownText;
    
    void UpdateTimerDisplay();
  3. 可在Countdown.cpp中创建可渲染文本 Component,并将倒计时时间初始化为3秒。因无需此类 ActorTicking,可将其关闭。ACountdown::ACountdown 应如下所示:

    PrimaryActorTick.bCanEverTick = false;
    
    CountdownText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("CountdownNumber"));
    CountdownText->SetHorizontalAlignment(EHTA_Center);
    CountdownText->SetWorldSize(150.0f);
    RootComponent = CountdownText;
    
    CountdownTime = 3;
  4. ACountdown::UpdateTimerDisplay 应更新文本显示来表明剩余时间,时间到则为零。首次将ACountdown生成到游戏中时将运行此代码。每秒运行一次,直到CountdownTime变量到达零。

    void ACountdown::UpdateTimerDisplay()
    {
        CountdownText->SetText(FString::FromInt(FMath::Max(CountdownTime, 0)));
    }
  5. 指定 定时器 运行函数时将获得一个 定时器柄。需要握住此柄,以便在倒计时结束时将定时器关闭。让我们添加一个函数来进行倒计时,然后将需要控制的定时器柄添加到Countdown.h中的类定义。操作完成后,再添加一个函数,在倒计时结束时执行特殊操作:

    void AdvanceTimer();
    
    void CountdownHasFinished();
    
    FTimerHandle CountdownTimerHandle;

    现在还可在 Countdown.cpp 中编写 ACountdown::AdvanceTimerACountdown::CountdownHasFinished 的主体:

    void ACountdown::AdvanceTimer()
    {
        --CountdownTime;
        UpdateTimerDisplay();
        if (CountdownTime < 1)
        {
            //倒计时结束,停止运行定时器。
            GetWorldTimerManager().ClearTimer(CountdownTimerHandle);
            CountdownHasFinished();
        }
    }
    
    void ACountdown::CountdownHasFinished()
    {
        //改为一个特殊的读出
        CountdownText->SetText(TEXT("GO!"));
    }
  6. 初始化 ACountdown::BeginPlay 中的文字显示——为新的更新函数添加一个调用,并设置一个定时器按每秒一次的频率前进和更新倒计时:

    UpdateTimerDisplay();
    GetWorldTimerManager().SetTimer(CountdownTimerHandle, this, &ACountdown::AdvanceTimer, 1.0f, true);

    我们是在ACountdown::BeginPlay中更新显示,而非ACountdown::ACountdown中。因为在 虚幻编辑器 中设为变量的值将在构造函数之后指定,但在 BeginPlay 之前。将 CountdownTime 公开到编辑器时需要遵守这些值。

  7. 前往 虚幻编辑器 并按下 编译(Compile) 即可检查当前进度。

    CompileFromEditor.png

    然后即可将更新的ACountdown类从 内容浏览器(Content Browser) 放入 关卡编辑器(Level Editor)

    ClassInContentBrowser.png

    LevelEditorText.png

    因倒计时文本是在ACountdown::BeginPlay中设置(而非ACountdown::ACountdown中),默认文本将显示在 关卡编辑器(Level Editor) 中。

    按下 运行(Play) 后,倒计时将按设置进行,显示3、2、1,开始!

此时,我们便成功创建了一个使用定时器的简单类。能够设置倒计时时间,或修改倒计时结束后的行为,这对非编程人员而言可谓受益良多。接下来,我们将把这些特性公开到编辑器。

编写中代码

Countdown.h

// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "GameFramework/Actor.h"
#include "Countdown.generated.h"

UCLASS()
class HOWTO_VTE_API ACountdown : public AActor
{
    GENERATED_BODY()

public: 
    // 设置该Actor属性的默认值
    ACountdown();

protected:
    // 游戏开始时或生成时调用
    virtual void BeginPlay() override;

public:
    // 每帧调用
    virtual void Tick( float DeltaSeconds ) override;

    //倒计时运行时长(以秒计)
    int32 CountdownTime;

    UTextRenderComponent* CountdownText;

    void UpdateTimerDisplay();

    void AdvanceTimer();

    void CountdownHasFinished();

    FTimerHandle CountdownTimerHandle;
};

Countdown.cpp

// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.

#include "HowTo_VTE.h"
#include "Countdown.h"

// 设置默认值
ACountdown::ACountdown()
{
    // 设置此Actor每帧调用Tick()。如果不需要,则可将其关闭来改善性能。
    PrimaryActorTick.bCanEverTick = false;

    CountdownText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("CountdownNumber"));
    CountdownText->SetHorizontalAlignment(EHTA_Center);
    CountdownText->SetWorldSize(150.0f);
    RootComponent = CountdownText;

    CountdownTime = 3;
}

// 游戏开始时或生成时调用
void ACountdown::BeginPlay()
{
    Super::BeginPlay();

    UpdateTimerDisplay();
    GetWorldTimerManager().SetTimer(CountdownTimerHandle, this, &ACountdown::AdvanceTimer, 1.0f, true);
}

// 每帧调用
void ACountdown::Tick( float DeltaTime )
{
    Super::Tick( DeltaTime );

}

void ACountdown::UpdateTimerDisplay()
{
    CountdownText->SetText(FString::FromInt(FMath::Max(CountdownTime, 0)));
}

void ACountdown::AdvanceTimer()
{
    --CountdownTime;
    UpdateTimerDisplay();
    if (CountdownTime < 1)
    {
        // 倒计时结束,停止运行定时器。
        GetWorldTimerManager().ClearTimer(CountdownTimerHandle);
        //在定时器结束时按执行所需的特殊操作。
        CountdownHasFinished();
    }
}

void ACountdown::CountdownHasFinished()
{
    //改为一个特殊的读出
    CountdownText->SetText(TEXT("GO!"));
}
Select Skin
Light
Dark

Welcome to the new Unreal Engine 4 Documentation site!

We're working on lots of new features including a feedback system so you can tell us how we are doing. It's not quite ready for use in the wild yet, so head over to the Documentation Feedback forum to tell us about this page or call out any issues you are encountering in the meantime.

We'll be sure to let you know when the new system is up and running.

Post Feedback