C++ Programming Tutorials_3翻译

来源:互联网 发布:网络贷款有风险 编辑:程序博客网 时间:2024/06/04 22:48


所在原文目录结构位置:

C++ Programming Guide

 |_____Programming Quick Start Guide

 |_____Introduction to C++ Programming in UE4

 |_____C++ Programming Tutorials

 |_____Managing Game Code

 |_____Development Setup

 |_____Gameplay Programming

 |_____Engine Architecture

 |_____Console Manager: Console Variables in C++

 |_____Command-Line Arguments

 |_____Assertions

 |_____Blueprint Function Libraries

 |_____Unreal Build System

 |_____Plugins

 |_____Coding Standard

 |_____Symbol Debugger


原文地址:Variables,Times,and Events


-------------------------------------------------------------------------------------------------------------------------------------------------------


C++ Programming Tutorials

C++编程教程

1.Player Input and Pawns 玩家输入和Pawn(个人感觉Pawn是副角色,配角) 

 见译文:  C++ Programming Tutorials_1 


2.Game-Controlled Cameras 游戏控制摄像机

见译文:C++ Programming Tutorials 2


3.Variables, Timers, and Events 变量,定时器和事件

This tutorial will show you how to expose variables and functions to the editor, use timers to delay or repeat code execution, and use events to communicate between Actors.

本教程要讲怎样将(C++中)变量,函数暴露给UE编辑器,使用计时器来延迟或重复代码的执行,和用事件来使Actorr交互.

Steps 步骤:

   1.Creating an Actor that uses a timer  创建一个ACtor,使用一个计数器

         !!!If you are new to Unreal Engine 4, you might want to read ourProgramming Quick Start tutorial first. For this tutorial, we will assume you are familiar with creating a project and adding C++ code to it.

         !!!如果你是新手,请先阅读前面的译文.

         ① We will begin by creating a new, Basic Code project, with starter content, named "HowTo_VTE", and then adding an Actor class to it. We'll name it "Countdown" in this tutorial.     

          我们从创建一个新的,C++,基础代码开始,使用初学者内容,项目命名为"HowTo_VTE", ,然后本教程为项目增加一个Actor类,名为该类为"Countdown"



         ② We'll start by creating a simple countdown timer that we can see in-game. InCountdown.h, add the following lines to the end of our class definition:

          我们创建一个简单的countdown计时器,能在游戏中被看见.在Countdown.h头文件中,在该类定义的尾部增加如下代码:`

int32 CountdownTime;UTextRenderComponent* CountdownText;void UpdateTimerDisplay();

         ③ InCountdown.cpp, we can create our renderable text Component and initialize our countdown time to 3 seconds. We can also turn Ticking off for this type of Actor, since we will not need it. ACountdown::ACountdown should look like this:

         在Countdown.cpp文件中,我们创建我们的可渲染的文本组件,初始化我们的countdown计时器为3秒.在我们不再需要的时候我们也可以关闭Actor这种类型的Ticking. ACountdown::ACountdown应该是这样的:


PrimaryActorTick.bCanEverTick = false;CountdownText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("CountdownNumber"));CountdownText->SetHorizontalAlignment(EHTA_Center);CountdownText->SetWorldSize(150.0f);RootComponent = CountdownText;CountdownTime = 3;

         ④ ACountdown::UpdateTimerDisplay should update our text display to show the time remaining, or zero if the time is up. This code should run when we first spawn our ACountdown into the game, and once per second until our CountdownTime variable hits zero.

         ACountdown::UpdateTimerDisplay 更新我们的文本显示,显示剩余时间,时间到了为0,这段代码应当在游戏中我们一运行我们的ACountdown 就要被触发,每秒一次,直到时间为0为止.

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

  无论何时我们指定一个计时器去控制一个函数的运行,我们有一个计时器的句柄.我们需要抓住这个句柄以便我们可以在计时结束时关闭计时器,我们新增加一个函数来表示时间到了,计时器句柄将要控制它,在Countdown.h类定义的末尾,当时间计时结束时做一些指定的事.</span></span>

    
void AdvanceTimer();void CountdownHasFinished();FTimerHandle CountdownTimerHandle;
</pre></h3><h3 align="left"><span style="color:#3333ff;background-color: rgb(255, 255, 255);"><span style="color:#000000;">       We can also write the body of ACountdown::AdvanceTimer and ACountdown::CountdownHasFinished in<code>Countdown.cpp</code> now:</span></span></h3><h3 align="left"><span style="color:#3333ff;background-color: rgb(255, 255, 255);"><span style="color:#000000;">我们在<span style="font-family:Courier New;">Countdown.cpp</span> 的ACountdown::AdvanceTimer 和ACountdown::CountdownHasFinished中写:</span></span></h3><h3 align="left"><span style="color:#3333ff;background-color: rgb(255, 255, 255);"><span style="color:#000000;"></span></span><pre class="cpp" name="code">void ACountdown::AdvanceTimer(){    --CountdownTime;    UpdateTimerDisplay();    if (CountdownTime < 1)    {        //We're done counting down, so stop running the timer.        GetWorldTimerManager().ClearTimer(CountdownTimerHandle);        CountdownHasFinished();    }}void ACountdown::CountdownHasFinished(){    //Change to a special readout    CountdownText->SetText(TEXT("GO!"));}

         ⑥Let's initialize the text display in ACountdown::BeginPlay by adding a call to our new update function, and setting a timer to advance and update the countdown once per second:

          让我们在ACountdown::BeginPlay 中初始化文本显示,为我们新的更新函数增加一个回调,每秒一次更新我们的计时器

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


         !!!We are updating the display in ACountdown::BeginPlay rather than ACountdown::ACountdown because values set to variables in the Unreal Editor will be assigned after the constructor, but before BeginPlay. We will want to respect those values later, when we expose CountdownTime to the editor.

         !!!我们在ACountdown::BeginPlay 中更新展示而不是在ACountdown::ACountdown 构造函数中,因为设置的变量在虚幻编辑器中将在构造函数之后被分配,但是在BeginPlay之前.当我们要暴露CountdownTime到编辑器的时候,以后我们要注重这些值.

         ⑦Let's check our progress so far by going to the Unreal Editor and pressing Compile

          回到UE编辑器中按下Play来检查到目前为止我们的进程.

          We can then drop our updated ACountdown class from the Content Browser into the Level Editor.

           我们可以在Level Editor(关卡编辑器)的Content Browser (内容浏览器)减少ACountdown的更新.

          !!!Because we set our countdown text during ACountdown::BeginPlay and not ACountdown::ACountdown, the default "Text" is shown in the Level Editor.

          !!!由于我们在ACountdown::BeginPlay中设置我们的countdown 文本而不是在ACountdown::ACountdown ,在关卡编辑器中显示默认的默认的"Text"

    When we press Play, the countdown will progress as expected, saying "3", "2", "1", and finally "GO!"

    当我们按下Play按钮,计时器将如期运行,"3", "2", "1",最后:"GO!".

At this point, we've already created a simple class that uses a timer. Non-programming users would get much more out of it if they could set the countdown time, or change the behavior when the countdown finishes. Next, we'll expose these features to the editor.

这儿,我们已经创建好了一个简单的类,使用了计时器.非编程的用户如果他们能设置倒计时,或者倒计时结束时改变他们的行为的话他们将获得更多,下面,我们要暴露属性给编辑器.



完成代码:

Countdown.h


// Copyright 1998-2015 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:     // 构造函数    ACountdown();    // 游戏开始时调用    virtual void BeginPlay() override;    // 每帧调用(本项目屏蔽了该函数,改成每秒更新)    virtual void Tick( float DeltaSeconds ) override;    //倒计时(这里默认为3秒)    int32 CountdownTime;
    UTextRenderComponent* CountdownText;//文本    void UpdateTimerDisplay();//更新时间和文本的显示    void AdvanceTimer();//计时器的委托函数    void CountdownHasFinished();//计时器时间到后的行为    FTimerHandle CountdownTimerHandle;//计时器句柄};


Countdown.cpp

<strong>// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.#include "HowTo_VTE.h"#include "Countdown.h"// Sets default valuesACountdown::ACountdown(){    // 本项目不需要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)    {        // We're done counting down, so stop running the timer.        GetWorldTimerManager().ClearTimer(CountdownTimerHandle);        //Perform any special actions we want to do when the timer ends.        CountdownHasFinished();    }}void ACountdown::CountdownHasFinished(){    //Change to a special readout    CountdownText->SetText(TEXT("GO!"));}</strong>

总结:心中一直萦绕着这么一个问题,例子中,把Tick这个每帧更新这个函数给屏蔽掉了,为啥还能3,2,1,地跑呢?

而且BeginPlay也就调用了一次.

解:它是通过委托来调用的,GetWorldTimerManager().SetTimer(CountdownTimerHandle,this,&ACountdown::AdvanceTimer,1.0f,true);它把AdvanceTimer这个委托函数地址保存下来,后面的参数1.0表示调用频率,这里为1.0秒调用一次AdvanceTimer.(一孔之见,我改成0.5,结论跟我想的丝毫不差)

(注意:改0.5要注意数据类型,int32改成 float,FromInt变成SanitizeFloat),UE4基本类型转换参考这儿:UE4基础数据类型转换

    2.Expose variables and functions to the editor 暴露变量,函数给编辑器

           ①Our countdown timer is currently hard-coded to use a value of 3 seconds. It would be more useful if we could set the countdown time to any value we want in the editor, and this is easy to do. In Visual Studio, we can openCountdown.h and find the line that says:

           我们的countdown 计时器目前使用硬编码的值3秒,如果我们把它设置为编辑器中可编辑的任意值岂不是更好吗?修改还更简单了.在VS中,我们打开Countdown.h,找到这个成员变量:

int32 CountdownTime;

     In order to expose this variable to Unreal Engine, we need to make it a UPROPERTY. This enables the engine to preserve the value of the variable when launching the game or loading a saved level. The UPROPERTY tag, with empty parentheses, is added right above the variable it affects:

     为了暴露这个变量到虚幻引擎,我们需要使之成为一个UPROPERTY宏,当引擎启动或者加载一个关卡的时候,允许引擎能维护变量的值,

UPROPERTY标记,用一对圆括号括起来,放在变量的正上方,如下:

UPROPERTY()int32 CountdownTime;

    UPROPERTY supports arguments that change how Unreal Engine will use the variable. Since we want our variable to be editable, we can add the EditAnywhere argument

    UPROPERTY 支持一些参数,这取决于引擎要怎样使用这些变量,这里,我们希望引擎能修改变量的值,所以,我们修改参数为EditAnywhere(哪里都可以修改) ,这样引擎就可以修改这个变量的值了.

UPROPERTY(EditAnywhere)int32 CountdownTime;

重新编译,可以看到如下:

 

We can also add a comment to our variable in C++, and our comment will become the description of the variable in the Unreal Editor, like this:

为我们的变量添加注释,这样,在虚幻编辑器中可以看到这个变量的作用了,如下:

     !!!There is a lot more we can do with UPROPERTY, and looking into other arguments such as BlueprintReadWrite and Category might be good next steps, but we have all that we need at the moment.

     !!!我们可以用UPROPERTY宏做更多的事情,和调查其他参数,比如BlueprintReadWrite(蓝图读写)和Category 可能是很好的下一步,但是待会儿我们都需要。


When we return to the Unreal Editor and press Compile, our variable will appear in the Details Panel for the ACountdown we placed earlier, and we can test out different timer values by changing this number and pressing Play.

当我们返回编辑器编译,我们的变量就显示在Details面板上,修改不同的时间,按Play运行测试下效果吧


           ②In addition to changing the value of the timer, let's also enable non-programming developers to change what happens when the timer is up. In Visual Studio, we'll open Countdown.h and find the following line:

           除了改变timer的值,让我们也使非编程开发人员改变定时器的时候会发生什么情况.在VS中,打开Countdown.h找到以下行:

void CountdownHasFinished();

We can expose this function to the Unreal Engine by making it a UFUNCTION, like this:

我们能通过UFUNCTION宏来暴露这个函数给虚幻引擎,像这样:

UFUNCTION()void CountdownHasFinished();


          

Just like the UPROPERTY macro, we need to provide information about what can be done with it in order to enable more features and access for non-programming developers. There are three options to consider:

就像UPROPERTY宏一样,我们需要提能做什么的信息以便更多未来的需求和给非编程开发人员使用,有三个选项需要考虑:

           (①)BlueprintCallable functions are written in C++ and can be called from the Blueprint Graph, but cannot be changed or overridden without editing C++ code. Functions marked this way are usually features that have been programmed for non-programmer use, but that are not supposed to be changed or wouldn't make sense to change. An easy example of this would be any kind of math function.

           BlueprintCallable 函数使用C++写的,能从Blueprint Graph被调用,但是不能被修改或者覆盖,除非修改C++代码.函数用这种方法标记,通常表明设定给非编程人员使用.但它不允许修改,或者没有改变的意义.一个简单的例子就是一些数学函数.

           (②)BlueprintImplementableEvent functions are set up in a C++ header (.h) file, but the body of the function is written entirely in the Blueprint Graph, not in C++. These are usually created to give a non-programmer the ability to create custom reactions to special situations that have no expected default action or standard behavior. An example of this might be an event that happens when a powerup touches the player's ship in a spaceship game.

            BlueprintImplementableEvent 函数是设置在C++的头文件(.h)中,但是函数的实现部分是写在Blueprint Graph,bushi zai C++.这些函数通常被建用来给非编程人员建立自定义指定行为,因为那些行为是无法预料的,或者不是规范的.一个例子就是在太空船游戏中,一个通电玩家飞船将会发生什么事件.

           (③)BlueprintNativeEvent functions are like a combination of BlueprintCallable and BlueprintImplementableEvent functions. They have default behaviors programmed in C++, but these can be supplemented or replaced by overriding in the Blueprint Graph. When programming these, the C++ code always goes in a virtual function with "_Implementation" added to the end of the name, as shown below. This is the most flexible option, so we will use it for this tutorial.

            BlueprintNativeEvent 函数就像是BlueprintCallable 和 BlueprintImplementableEvent 的组合.他们在C++里有默认的行为,但是这些能在Blueprint Graph被扩充或者通过覆盖替换掉,当编程时,C++代码经常在虚函数名最后加上"_Implementation",如下所示.这是最灵活的选择,因此,本教程我们使用它.(这就是我以前看到函数名不一样时候的疑惑)

To grant non-programmers the ability to call our C++ function and to override it with Blueprints, we need to make the following changes toCountdown.h:

授予非程序员调用我们的c++函数的能力和用Blueprints覆盖函数的能力,我们要对Countdown.h作如下改变:

UFUNCTION(BlueprintNativeEvent)void CountdownHasFinished();virtual void CountdownHasFinished_Implementation();

Then, in Countdown.cpp, we will need to change the line that says:

然后,在Countdown.cpp文件中,我们需要作如下改变:

void ACountdown::CountdownHasFinished()
!!!

To:转变为:

void ACountdown::CountdownHasFinished_Implementation()

We have now made a variable and a function accessible to, and alterable by, non-programmers, while providing our own default value and functionality in C++. To see how a non-programmer might use this, we'll make a Blueprint extension of our ACountdown class and modify it ourselves.

我们已经做了一个变量和一个函数,可访问,可修改,非程序化,同时在C++中提供默认的值.非程序员可以使用这个,我们将为我们的ACountdown 类做一个可扩展可修改的Blueprint.

完成代码:

Countdown.h

// Copyright 1998-2015 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:     // Sets default values for this actor's properties    ACountdown();    // Called when the game starts or when spawned    virtual void BeginPlay() override;    // Called every frame    virtual void Tick( float DeltaSeconds ) override;    //How long, in seconds, the countdown will run    UPROPERTY(EditAnywhere)    int32 CountdownTime;    UTextRenderComponent* CountdownText;    void UpdateTimerDisplay();    void AdvanceTimer();    UFUNCTION(BlueprintNativeEvent)    void CountdownHasFinished();    virtual void CountdownHasFinished_Implementation();    FTimerHandle CountdownTimerHandle;};

Countdown.cpp

<strong>// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.#include "HowTo_VTE.h"#include "Countdown.h"// Sets default valuesACountdown::ACountdown(){    // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.    PrimaryActorTick.bCanEverTick = false;    CountdownText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("CountdownNumber"));    CountdownText->SetHorizontalAlignment(EHTA_Center);    CountdownText->SetWorldSize(150.0f);    RootComponent = CountdownText;    CountdownTime = 3;}// Called when the game starts or when spawnedvoid ACountdown::BeginPlay(){    Super::BeginPlay();    UpdateTimerDisplay();    GetWorldTimerManager().SetTimer(CountdownTimerHandle, this, &ACountdown::AdvanceTimer, 1.0f, true);}// Called every framevoid 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)    {        // We're done counting down, so stop running the timer.        GetWorldTimerManager().ClearTimer(CountdownTimerHandle);        //Perform any special actions we want to do when the timer ends.        CountdownHasFinished();    }}void ACountdown::CountdownHasFinished_Implementation(){    //Change to a special readout    CountdownText->SetText(TEXT("GO!"));}</strong>

   3.  Extend and override C++ withBlueprints   蓝图扩展和覆盖c++

           !!!This section of the tutorial involves using Blueprints to extend the functionality of C++ classes. However, it is only intended as a test that our C++ code was written correctly, not as a Blueprint tutorial. For a proper introduction to Blueprints, we recommend theBlueprints Quick Start Guide

           !!!这段教程涉及到使用蓝图来扩展C++类的函数功能,然而,它只是作为C++代码写的正确的一个测试,这不是蓝图教程,适当介绍蓝图,见蓝图教程.

            ①To change the behavior of our ACountdown instance, called "Countdown1", in the editor, we must first make an editable Blueprint version of it. To do this, we can select it from the World Outliner and click the Blueprint/Add Script button in the Details Panel.

             要改变我们的ACountdown实例的行为,叫做"Countdown1",在编辑器,我们必须先做一个可编辑版本的蓝图,为此,我们可以选World Outliner 中的Countdown1,然后 点击Details面板中Blueprint/Add Script 按钮.

From there, we can provide a path and name for the Blueprint asset that will contain our modified ACountdown class.

从这儿,我们为能Blueprint 提供一个路径和名字,包含我们修改的ACountdown类.

This will create a new asset that represents a Blueprint version of "Countdown1". It will also replace "Countdown1" with an instance of this new Blueprint, so that changes we make to the Blueprint will affect "Countdown1" in the game.

这将创建一个代表"Countdown1"版本的Blueprint 的新的资源.它还将取代“Countdown1”这个新蓝图的一个实例,改变我们的蓝图将会影响“Countdown1”游戏


            ②The Unreal Editor will automatically take us to our new asset in the Content Browser, and we can right-click it and choose "Edit..." to modify its Blueprint Graph, Component hierararchy, and Default Values.

            虚幻编辑器自动的带我们到Content Browser新资源.右击->编辑 来修改它的Blueprint Graph(),Component 层级和Default Values.


            ③Functions and events can be found in the Event Graph tab, so we'll select that first.

            函数和事件可以在Event Graph(事件图表)中被找到,所以我们选择这个标签.

Then, by righting-click anywhere in the Event Graph window, we can add our CountdownHasFinished function as an event node to define its behavior.

然后,在Event Graph窗口中右击,我们能把CountdownHasFinished 这个函数作为定义它它行为事件的节点.

            ④We can now add any additional functionality we would like by left-clicking and dragging off of the white ("execution") pin on the right side of our new node.

            我们现在能增加额外的功能,左击然后拖出一条白色的线.

When we release the left mouse button, we will be asked what function or event we would like to execute. For this tutorial, let's spawn aParticle System when the countdown finishes. We'll want a Spawn Emitter At Location node, so select that from the list. It can save time to type a partial phrase, like "spawn loc", into the search field. We can then left-click and drag the yellow "Location" pin and attach it to aGet Actor Location function.

当我们松开左键,我们将被问想要执行什么功能或事件,在本教程中,当倒计时结束我们将产生一个粒子系统.我们需要一个Spawn Emitter At Location 节点(注意:不是Spawn Effect at Location,寡人深受其害,半天没找到粒子),所以,从列表中选择,在搜索地方输入一部分短语,像"spawn loc",拖拽黄色的 "Location"附加到Get Actor Location 函数



            Now we just need to select what effect we'd like to see. By clicking "Select Asset" under "Emitter Template", we can get a list of appropriate effect assets. "P_Explosion" is a good one, so we'll pick that.

             选一个粒子效果,爆炸挺不错的.点击"Select Asset",模版里选"P_Explosion"

           ⑤If we press Play now, we'll see our countdown take place, and our explosion will happen when our countdown number hits zero.

               点击Play,到0的时候,爆炸.

However, we programmed our countdown to say "GO!" at the end, not "0". This is no longer happening because we have completely replaced our C++ functionality with our Blueprint visual scripting. This is not what we intended to do in this case, so we need to add a call to the C++ version of this function, which can be done by right-clicking the Countdown Has Finished node and selecting "Add call to parent function" from the context menu.

但是,我们规划了说GO之后爆炸,而不是0,GO永远不会发生了,因为我们蓝图已经完全取代了C++函数功能,这不是我们想要的,所以,我们需要添加一个C++版本的功能函数,

右击Countdown Has Finished 节点,点击 "Add call to parent function".


When this is done, a node labeledParent: Countdown Has Finished will be placed in theEvent Graph. The typical place to connect a "parent" node is directly to the event node, which is what we will do here. This is not required, though, as the parent-call node is like any other and can be called anywhere we like, even multiple times.

做完这些,一个节点的标签Parent: Countdown Has Finished 将出现在图表窗口中,像这样:

Now when we run our game, we should see both the word "GO!" (from our C++ code) and an explosion (from our Blueprint Graph) after the countdown finishes!

现在启动我们的游戏,我们在计时器为0的时候就能看到"GO"(C++代码)和爆炸的粒子效果(蓝图事件)了.

代码和上面的一样:略.

   4.On Your Own! 自己做!

Next Step

Programming Tutorials Home

Using what you have learned, try to do the following:

学以致用:

  • Create an Actor that moves or rotates to a target transform when anEvent is run. This could be used as a moving platform or door in a game. Make theEvent start aTimer that will trigger a second Event which moves theActor back to its original location. Use exposed variables (viaUPROPERTY) instead of hard-coded values wherever appropriate.

  • 创建一个Actor,当事件促发时,移动或者旋转到目标值.这能被用来做游戏里的一个移动平台或者门.用事件启动一个计时器,使得计时器触发第二个事件(让Actor回到原来最初的位置),无论在哪里都用暴露变量(用UPROPERTY)的方式,而不是硬编码方式.

  • Make a lit torch that burns out (perhaps by deactivating a fiery Particle System Component) by using aTimer handle and a few customEvents. For example, anAddFuelEvent could extend the burning time of the torch. ADouseWithWaterEvent could shut it off immediately and preventAddFuel from working in the future. Both of these features can be written without using aTick, simply by modifying a runningTimer through its handle.

  • 通过使用一个定时器和一些自定义的事件让火炬点燃燃烧(也许通过关闭的粒子系统的组件),举个例子,AddFuel事件可以延长燃烧的火炬,DouseWithWater事件会立即把它关掉,和在未来,防止AddFuel工作.这两种功能可以都不使用Tick,只要简单的修改一个运行的计时器句柄即可.

As for the specifics covered in this tutorial:

  • For more information about Timers, try the Gameplay Timers page.

  • For a complete reference using the UPROPERTY tag with variables in your classes or structs, look at theProperties page.

  • To learn more about UFUNCTIONS and Event creation, check theFunctions page.

  • For further tutorials, see the C++ Programming Tutorials page.


 ------------------------------------------------题目容我好好研究---------------------------------------------------------



4.Player-Controlled Cameras 玩家控制摄像机

5.Components And Collision 组件和碰撞


0 0
原创粉丝点击