开门

一个关于时间轴的案例。介绍了如何用时间轴以及蓝图和C++来实现玩家靠近门后,门会自动打开的效果。

Windows
MacOS
Linux

选择实现方法:

Blueprints

C++

课程:蓝图基本概念|蓝图 - 基本概念|https://cdn2.unrealengine.com/Unreal+Engine%2Fonlinelearning-courses%2Fblueprints---essential-concepts%2FBPEssentialsThumbnail_1920x1080-1920x1080-2fcdde875f1d79ade1c295fe4fef53c4b8c5ecde.PNG?resize=1&w=1400|https://cdn2.unrealengine.com/Unreal+Engine%2Fonlinelearning-courses%2Fblueprints---essential-concepts%2FBlueprint--Essential-Concepts-1000x1000-9f372ce55de42ce9596dffd6c931839e44fcc873.png?resize=1&w=300 课程:使用蓝图进行交互式材质交换|使用蓝图进行交互式材质交换|https://cdn2.unrealengine.com/Unreal+Engine%2Fonlinelearning-courses%2Finteractive-material-swaps-using-blueprints%2F406---Hero2-1920x1080-ce26b6199cf620364149d2d934c73ae30e983110.png?resize=1&w=1400|https://cdn2.unrealengine.com/Unreal+Engine%2Fonlinelearning-courses%2Finteractive-material-swaps-using-blueprints%2FInteractive-Material-Swaps-Using-Blueprints-1000x1000-21158a5fe67365e3bf5db49712b52482382f15ac.png?resize=1&w=300 课程:制作蓝图产品配置器|企业级蓝图|https://cdn2.unrealengine.com/Unreal+Engine%2Fonlinelearning-courses%2Fblueprint-for-enterprise%2F301-Blueprints-%281200X675%29-1200x675-d140b8a0b13b05c0619e35e1076b4c82e4a4b855.png?resize=1&w=1400|https://cdn2.unrealengine.com/Unreal+Engine%2Fonlinelearning-courses%2Fblueprint-for-enterprise%2FBlueprint-for-Enterprise-1000x1000-13caa11b8e5c5e91506a8dd63b39d247318c3208.png?resize=1&w=300

本教程演示如何凭借 引擎初学者内容包 中的可用资源,使用 时间轴 蓝图创建基于距离的开门。

创建门Actor

  1. 首先,点击 新建(New) > 游戏(Games) > 空白(Blank) > 蓝图(Blueprint) 创建名为 TimelineDoorActor 的项目,并启用 初学者内容包(Starter Content)

  2. 点击 添加/导入(Add/Import) 按钮新建蓝图 Actor 类,将其命名为 BP_DoorActor

  3. 从内容浏览器中双击该BP_Door Actor在蓝图编辑器中打开,然后打开 类默认值(Class Defaults)

    图像替换文本

  4. 下一步,在 组件(Components) 选项卡中点击 添加组件(Add Component) 按钮,选择 静态网格体(Static Mesh) 添加新的 静态网格体组件(Static Mesh Component)

    图像替换文本

  5. 右键点击你的静态网格体组件,选择 重命名(Rename),将其重命名为 DoorFrame

    图像替换文本

  6. 下一步,在 组件(Components) 选项卡中点击 添加组件(Add Component) 按钮,选择 静态网格体(Static Mesh) 添加新的 静态网格体组件(Static Mesh Component)。(重复步骤3)

  7. 右键点击你的静态网格体组件,选择重命名(Rename),将其重命名为 Door

    图像替换文本

  8. 点击添加组件(Add Component),从下拉菜单中选择 盒体碰撞(Box Collision),将其重命名为 Box

    图像替换文本

  9. 下一步,打开事件图表,右键点击 图表,从 蓝图上下文菜单(Blueprint Context Menu) 中选择 添加时间轴(Add Timeline)。将你的时间轴命名为 DoorTimelineComponent

    图像替换文本

此时,BP_DoorActor的类默认值应如下例中所示:

图像替换文本

设置门静态网格体

接下来,你需要设置 组件(Components) 选项卡的附件层级。

你还需要设置静态网格体资产,直观地表示你的 DoorFrameDoor 静态网格体组件。

  1. BP_DoorActor 的组件(Components)选项卡中,选择 DoorFrame 静态网格体并将其拖动到 DefaultSceneRoot组件 上,使其成为新的 根组件

    图像替换文本

  2. 接下来,在组件(Components)选项卡中选择 DoorFrame 静态网格体,从 细节面板(Details panel) 中将静态网格体更改为 SM_DoorFrame

    图像替换文本

  3. 接下来,从组件(Components)面板中选择DoorMesh组件。导航至细节面板,将静态网格体更改为 SM_Door

    图像替换文本

  4. 然后导航至 变换(Transform) 类别,将 Y位置(Y Location) 值更改为 45.0

    图像替换文本

  5. 点击 保存(Save)编译(Compile),将这些更改保存到Bp_DoorActor。

创建时间轴浮点轨道

时间轴组件需要时间轴曲线来描述其移动动画。每个轨道都可以包含多个键,用于定义时间和值。曲线内插这些键,以计算时间轴中任何点的值。

  1. 首先,在事件图表中双击DoorTimelineComponent,打开时间轴编辑器。

  2. 点击 添加浮点曲线(Add Float Curve) 向该轨道添加新曲线,将该曲线命名为 DoorRotationZ

    图像替换文本

  3. 右键点击,向浮点曲线轨道添加两个键。两个键的值分别为(0,0)和(5,90)。

    图像替换文本

  4. 按住Shift键并选中这两个键,点击右键,从 键插值(Key Interpolation) 下拉菜单中选择 自动(Auto) 插值。

  5. 保存你的浮点轨道。

更新事件轨道逻辑

现在你需要创建更新逻辑,以旋转你的门静态网格体。

  1. 导航至BP_DoorActor的组件(Components)选项卡,将门静态网格体拖动到事件图表上

    图像替换文本

  2. 拖移门引脚,从操作上下文菜单中选择 SetRelativeRotation

    图像替换文本

  3. 右键点击事件图表,从上下文菜单中选择 制作旋转体(Make Rotator)

    图像替换文本

  4. DoorTimelineComponent 节点上,拖动 Door Rotation Z 浮点引脚,将其连接至 Make Rotator 节点的 Z(Yaw) 引脚。

    图像替换文本

  5. DoorTimelineComponent 节点上,拖移 更新(Update) 引脚,将其连接至 SetRelativeRotation 节点的输入执行引脚。

  6. Make Rotator 节点上,将 返回值(Return Value) 引脚连接至SetRelativeRotation节点的 新旋转(New Rotation) 引脚。

    图像替换文本

  7. 编译保存

创建绑定盒体碰撞重叠事件

盒体组件需要拥有在Actor进入或离开碰撞边界时做出反应的能力。

  1. 导航至BP_DoorActor的组件(Components)选项卡,选择盒体组件。

  2. 从细节面板中,向下滚动到事件类别,点击 在组件开始重叠时(On Component Begin Overlap) 事件旁的 + 图标。

    图像替换文本

  3. On Component Begin Overlap(Box) 节点上,拖移执行引脚,将其连接至DoorTimelineComponent节点的播放(Play)引脚。

    图像替换文本

  4. 导航至BP_DoorActor的组件(Components)选项卡,选择盒体组件。然后,在细节面板向下滚动到事件类别,点击 在组件结束重叠时(On Component End Overlap) 事件旁的 + 图标。

    图像替换文本

  5. On Component End Overlap(Box) 节点上,拖移执行引脚,将其连接至TimelineComponent节点的 反向(Reverse) 引脚。

    图像替换文本

  6. 编译保存

将Actor放到关卡中

  1. 从内容浏览器中,选择你的BP_DoorActor并将其拖动到视口中。

    图像替换文本

  2. 按PIE

    图像替换文本

    可以使用WASD键控制我们的旁观者Pawn。导航至DoorActor的碰撞边界时,可以在门打开时观察时间轴播放。退出边界时,可以观察到时间轴反向播放。

完成后的蓝图

BP_DoorActor

图像替换文本

凭借 引擎初学者内容包 中的可用资源,使用C++ 时间轴 示例创建基于距离的经典开门。

图像替换文本

创建门Actor

  1. 首先,点击 新建(New) > 游戏(Games) > 空白(Blank) > C++ 创建名为 TimelineDoorActor 的项目,并启用 初学者内容包(Starter Content)

  2. C++类向导(C++ Class Wizard) 中新建名为 DoorActorActor 类。导航至你的 DoorActor.h 文件,并声明以下内容:

    #include "Components/TimelineComponent.h"
  3. 接下来,在你的 DoorActor 类定义中实现以下代码:

    protected:
    
        //用于表示门资产的网格体组件
        UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
        UStaticMeshComponent* DoorFrame;
        UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
        UStaticMeshComponent* Door;
    
        //用于对门网格体进行动画处理的时间轴组件
        UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
        UTimelineComponent* DoorTimelineComp;
    
        //将用作我们的距离体积的盒体组件。
        UPROPERTY(EditAnywhere, BlueprintReadWrite)
        class UBoxComponent* DoorProxVolume;
  4. 导航至 DoorActor.cpp。需要包括以下类库,方可利用你的盒体组件。

    #include "Components/BoxComponent.h"
  5. 在你的 ADoorActor::ADoorActor 的构造函数中声明以下内容:

    //创建我们的默认组件
    DoorFrame = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorFrameMesh"));
    Door = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorMesh"));
    DoorTimelineComp = CreateDefaultSubobject<UTimelineComponent>(TEXT("DoorTimelineComp"));
    DoorProxVolume = CreateDefaultSubobject<UBoxComponent>(TEXT("DoorProximityVolume"));
    
    //设置我们的附件
    DoorFrame->SetupAttachment(RootComponent);
    Door->AttachToComponent(DoorFrame,FAttachmentTransformRules::KeepRelativeTransform);
    DoorProxVolume->AttachToComponent(DoorFrame, FAttachmentTransformRules::KeepRelativeTransform);

    注意:我们将门的相对变换保留为附件规则,以便稍后使用门Actor的自定义方法来操作它。 详情请参阅FAttachmentTransformRules

  6. 选择 编译(Compile),在编辑器中 热重载 你的代码。

    图像替换文本

设置门静态网格体

你需要设置静态网格体资产,直观地表示你的DoorFrame和Door静态网格体组件。

  1. 从内容浏览器中导航至你的 C++类文件夹

  2. 右键点击你的DoorActor类,选择 基于门Actor创建蓝图类(Create Blueprint Class based on Door Actor),并将你的蓝图Actor命名为 Bp_DoorActor

  3. 组件(Components) 选项卡中选择DoorFrame静态网格体组件。

  4. 导航至 细节面板,将静态网格体更改为 SM_DoorFrame

    图像替换文本

  5. 接下来,从组件(Components)选项卡中选择DoorMesh组件。导航至细节面板,将静态网格体更改为 SM_Door

    图像替换文本

  6. 然后导航至 变换(Transform) 类别,将 Y位置(Y Location) 值更改为 45.0

    图像替换文本

  7. 点击 保存(Save),将这些更改保存到Bp_DoorActor。

创建UCurveFloat和时间轴事件轨道

时间轴组件需要时间轴曲线。每个轨道都可以包含多个键,用于定义时间和值。曲线内插这些键,以计算时间轴中任何点的值。

此例中,我们将使用UCurveFloat

  1. 导航至 DoorActor.h 中的 ADoorActor 类定义,并声明以下变量:

    public:
        // 用于保留曲线资产的变量
        UPROPERTY(EditAnywhere)
        UCurveFloat* DoorTimelineFloatCurve;
    
    private:
        //用于处理我们的更新轨道事件的浮点轨道签名
        FOnTimelineFloat UpdateFunctionFloat;
    
        //用于使用时间轴图表更新门相对位置的函数
        UFUNCTION()
        void UpdateTimelineComp(float Output);
  2. 接下来,导航至 DoorActor.cpp 并实现 UpdateTimelineComp 方法:

    void ADoorActor::UpdateTimelineComp(float Output)
    {
        // 基于时间轴曲线的输出创建并设置门的新相对位置
        FRotator DoorNewRotation = FRotator(0.0f, Output, 0.f);
        Door->SetRelativeRotation(DoorNewRotation);
    }
  3. 然后,在 BeginPlay 方法中,添加以下代码:

    //将浮点轨道绑定到UpdateTimelineComp函数的输出
    UpdateFunctionFloat.BindDynamic(this, &ADoorActor::UpdateTimelineComp);
    
    //如果有浮点曲线,将其图表绑定到我们的更新函数
    if (DoorTimelineFloatCurve)
    {
       DoorTimelineComp->AddInterpFloat(DoorTimelineFloatCurve, UpdateFunctionFloat);
    }

半成品代码

DoorActor.h

// 版权所有 1998-2021 Epic Games, Inc。保留所有权利。 
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/TimelineComponent.h"
#include "DoorActor.generated.h"

UCLASS()
class TIMELINEDOORACTOR_API ADoorActor : public AActor
{
    GENERATED_BODY()

public: 
    // 为此Actor的属性设置默认值
    ADoorActor();

    /*用于保留曲线资产的变量*/
    UPROPERTY(EditAnywhere)
    UCurveFloat* DoorTimelineFloatCurve;

protected:
    // 当游戏开始或重生(Spawn)时被调用
    virtual void BeginPlay() override;

    //用于表示门资产的网格体组件
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
    UStaticMeshComponent* DoorFrame;
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
    UStaticMeshComponent* Door;

    //用于对门网格体进行动画处理的时间轴组件
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
    UTimelineComponent* DoorTimelineComp;

    //将用作我们的距离体积的盒体组件。
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    class UBoxComponent* DoorProxVolume;

    //用于处理我们的更新轨道事件的浮点轨道签名
    FOnTimelineFloat UpdateFunctionFloat;

    //用于使用时间轴图表更新门相对位置的函数
    UFUNCTION()
    void UpdateTimelineComp(float Output);

public: 
    // 每一帧都被调用
    virtual void Tick(float DeltaTime) override;
};

DoorActor.cpp

//版权所有 1998-2021 Epic Games, Inc。保留所有权利。

#include "DoorActor.h"
#include "Components/BoxComponent.h"

// 设置默认值
ADoorActor::ADoorActor()
{
    // 将此actor设置为每帧调用Tick()。  如果不需要此特性,可以关闭以提升性能。
    PrimaryActorTick.bCanEverTick = true;

    //创建我们的默认组件
    DoorFrame = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorFrameMesh"));
    Door = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorMesh"));
    DoorTimelineComp = CreateDefaultSubobject<UTimelineComponent>(TEXT("DoorTimelineComp"));
    DoorProxVolume = CreateDefaultSubobject<UBoxComponent>(TEXT("DoorProximityVolume"));

    //设置我们的附件
    DoorFrame->SetupAttachment(RootComponent);
    Door->AttachToComponent(DoorFrame,FAttachmentTransformRules::KeepRelativeTransform);
    DoorProxVolume->AttachToComponent(DoorFrame, FAttachmentTransformRules::KeepRelativeTransform); 
}

// 当游戏开始或重生(Spawn)时被调用
void ADoorActor::BeginPlay()
{
    Super::BeginPlay();

    //将浮点轨道绑定到UpdateTimelineComp函数的输出
    UpdateFunctionFloat.BindDynamic(this, &ADoorActor::UpdateTimelineComp);

    //如果有浮点曲线,将其图表绑定到我们的更新函数
    if (DoorTimelineFloatCurve)
    {
    DoorTimelineComp->AddInterpFloat(DoorTimelineFloatCurve, UpdateFunctionFloat);

    }
}

void ADoorActor::UpdateTimelineComp(float Output)
{
    //基于时间轴曲线的输出创建并设置门的新相对位置
    FRotator DoorNewRotation = FRotator(0.0f,Output,0.f);
    Door->SetRelativeRotation(DoorNewRotation);
}

// 每一帧都被调用
void ADoorActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
}

创建并绑定盒体碰撞重叠事件

盒体组件需要拥有在Actor进入或离开碰撞边界时做出反应的能力。

  1. 导航至你的 TimelineDoorActor.h 文件的类定义,并声明以下内容:

    // DoorProxVolume的开始和结束重叠事件
    UFUNCTION()
    void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
    
    UFUNCTION()
    void OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
  2. 接下来,导航至 DoorActor.cpp 文件,以实现 OnOverlapBeginOnOverlapEnd 类方法:

    void ADoorActor::OnOverlapBegin(UPrimitiveComponent * OverlappedComp, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
    {
        DoorTimelineComp->Play();
    }
    
    void ADoorActor::OnOverlapEnd(UPrimitiveComponent * OverlappedComp, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex)
    {
        DoorTimelineComp->Reverse();
    }
  3. BeginPlay 方法中绑定重叠函数,如下所示:

    //将我们的距离盒体组件绑定到我们的重叠函数
    DoorProxVolume->OnComponentBeginOverlap.AddDynamic(this, &ADoorActor::OnOverlapBegin);
    DoorProxVolume->OnComponentEndOverlap.AddDynamic(this, &ADoorActor::OnOverlapEnd);
  4. 编译你的代码。

在虚幻编辑器中创建曲线资产

必须在虚幻编辑器中创建曲线资产,以分配到你的时间轴Actor蓝图。

  1. 内容浏览器 中选择 添加/导入(Add/Import) > 杂项(Miscellaneous) > 曲线(Curve)

    图像替换文本

  2. 选择 CurveFloat 并将CurveFloat资产命名为 DoorCurveFloat

  3. 双击你的DoorCurveFloat资产,以打开 时间轴编辑器

  4. 向你的浮点曲线添加两个键,为一个键赋予时间值(0,0),另一个键赋予时间值(4,90)。

    图像替换文本

    有关编辑时间轴曲线的更多详情,请参阅键和曲线

  5. 按住Shift键并选中这两个键,将它们设置为自动立方体插值,然后保存曲线。

    图像替换文本

  6. 打开Bp_DoorActor,并从组件(Components)选项卡中选择Bp_DoorActor。

  7. 在细节面板中,从门时间轴浮点曲线(Door Timeline Float Curve)下拉菜单中选择DoorCurveFloat。

    图像替换文本

  8. 从关卡编辑器将Bp_DoorActor放置到场景中。

  9. 编译并保存,然后按PIE。

    图像替换文本

    可以使用WASD键进行输入,以控制我们的旁观者Pawn。导航至DoorActor的碰撞边界时,可以观察到时间轴播放,而在退出边界时,可以观察到时间轴反向播放。

已完成代码

DoorActor.h

// 版权所有 1998-2021 Epic Games, Inc。保留所有权利。

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/TimelineComponent.h"
#include "DoorActor.generated.h"

UCLASS()
class TIMELINEDOORACTOR_API ADoorActor : public AActor
{
    GENERATED_BODY()

public: 
    // 为此Actor的属性设置默认值
    ADoorActor();
    //用于保留曲线资产的变量
    UPROPERTY(EditAnywhere)
    UCurveFloat* DoorTimelineFloatCurve;

protected:
    // 当游戏开始或重生(Spawn)时被调用 
    virtual void BeginPlay() override;

    /*用于表示门资产的网格体组件*/
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
    UStaticMeshComponent* DoorFrame;
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
    UStaticMeshComponent* Door;

    //用于对门网格体进行动画处理的时间轴组件
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
    UTimelineComponent* DoorTimelineComp;

    //将用作我们的距离体积的盒体组件。
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    class UBoxComponent* DoorProxVolume;

    //用于处理我们的更新轨道事件的浮点轨道签名
    FOnTimelineFloat UpdateFunctionFloat;

    //用于使用时间轴图表更新门相对位置的函数
    UFUNCTION()
    void UpdateTimelineComp(float Output);

    /*DoorProxVolume的开始和结束重叠事件*/
    UFUNCTION()
    void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
    UFUNCTION()
    void OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

public: 
    // 每一帧都被调用
    virtual void Tick(float DeltaTime) override;
};

DoorActor.cpp

// 版权所有 1998-2021 Epic Games, Inc。保留所有权利。

#include "DoorActor.h"
#include "Components/BoxComponent.h"

// 设置默认值
ADoorActor::ADoorActor()
{
    // 将此actor设置为每帧调用Tick()。  如果不需要此特性,可以关闭以提升性能。
    PrimaryActorTick.bCanEverTick = true;

    //创建我们的默认组件
    DoorFrame = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorFrameMesh"));
    Door = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorMesh"));
    DoorTimelineComp = CreateDefaultSubobject<UTimelineComponent>(TEXT("DoorTimelineComp"));
    DoorProxVolume = CreateDefaultSubobject<UBoxComponent>(TEXT("DoorProximityVolume"));

    //设置我们的附件
    DoorFrame->SetupAttachment(RootComponent);
    Door->AttachToComponent(DoorFrame,FAttachmentTransformRules::KeepRelativeTransform);
    DoorProxVolume->AttachToComponent(DoorFrame, FAttachmentTransformRules::KeepRelativeTransform); 
}

// 当游戏开始或重生(Spawn)时被调用
void ADoorActor::BeginPlay()
{
    Super::BeginPlay();

    UpdateFunctionFloat.BindDynamic(this, &ADoorActor::UpdateTimelineComp);

    //如果有浮点曲线,将其图表绑定到我们的更新函数
    if (DoorTimelineFloatCurve)
    {
        DoorTimelineComp->AddInterpFloat(DoorTimelineFloatCurve, UpdateFunctionFloat);
    }

    //将我们的距离盒体组件绑定到我们的重叠函数
    DoorProxVolume->OnComponentBeginOverlap.AddDynamic(this, &ADoorActor::OnOverlapBegin);
    DoorProxVolume->OnComponentEndOverlap.AddDynamic(this, &ADoorActor::OnOverlapEnd);
}

void ADoorActor::UpdateTimelineComp(float Output)
{
    FRotator DoorNewRotation = FRotator(0.0f,Output,0.f);
    Door->SetRelativeRotation(DoorNewRotation);
}

void ADoorActor::OnOverlapBegin(UPrimitiveComponent * OverlappedComp, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
    DoorTimelineComp->Play();
}

void ADoorActor::OnOverlapEnd(UPrimitiveComponent * OverlappedComp, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex)
{
    DoorTimelineComp->Reverse();
}

// 每一帧都被调用
void ADoorActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
}
Select Skin
Light
Dark
欢迎帮助改进虚幻引擎文档!请告诉我们该如何更好地为您服务。
填写问卷调查
取消

欢迎来到全新虚幻引擎4文档站!

我们正在努力开发新功能,包括反馈系统,以便您能对我们的工作作出评价。但它目前还未正式上线。如果您对此页面有任何意见与在使用中遭遇任何问题,请前往文档反馈论坛告知我们。

新系统上线运行后,我们会及时通知您的。

发表反馈意见