本文将介绍如何建立能够在接触时变色并随时间闪烁的光源Actor。
我们将用到点光源组件,该组件包含一个作为重叠触发器的盒体组件,以及一个用于操控点光源Actor的时间轴组件。
创建能够熄灭的光源Actor
使用空白(Blank)模板新建一个C++项目,将项目命名为FadingLights。
找到内容浏览器,点击C++ Classes文件夹,然后点击添加(+)(Add (+))按钮并选择新建C++类(New C++ Class)。
选择Actor作为父类。
将创建的Actor命名为LightActor。
创建新Actor时,Visual Studio会自动打开
LightActor.h和LightActor.cpp文件。 找到LightActor.h文件并声明如下内容:LightActor.h
C++#include "Components/TimelineComponent.h"接下来,在
LightActor的类定义中添加以下代码:LightActor.h
C++public: UPROPERTY(EditAnywhere) UCurveFloat* PointLightFloatCurve; UPROPERTY(EditAnywhere) UCurveLinearColor* PointLightColorCurve; protected:找到
LightActor.cpp并添加以下类库。LightActor.cpp
C++#include "Components/BoxComponent.h" #include "Components/PointLightComponent.h"在
ALightActor::ALightActor的构造函数中声明以下内容:LightActor.cpp
C++ALightActor::ALightActor() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; //Create our Default Components PointLightComp = CreateDefaultSubobject<UPointLightComponent>(TEXT("PointLightComp")); LightTimelineComp = CreateDefaultSubobject<UTimelineComponent>(TEXT("LightTimelineComp")); LightOverlapVolume = CreateDefaultSubobject<UBoxComponent>(TEXT("LightOverlapVolume"));接下来,实现点光源组件的
UFunction方法:LightActor.cpp
C++void ALightActor::UpdateLightBrightness(float BrightnessOutput) { PointLightComp->SetLightBrightness(BrightnessOutput * 20.0f); } void ALightActor::UpdateLightColor(FLinearColor ColorOutput) { PointLightComp->SetLightColor(ColorOutput); }然后,在
BeginPlay方法中添加以下代码:LightActor.cpp
C++void ALightActor::BeginPlay() { Super::BeginPlay(); //Binding our float and color track to their respective functions UpdateBrightnessTrack.BindDynamic(this, &ALightActor::UpdateLightBrightness); UpdateColorTrack.BindDynamic(this, &ALightActor::UpdateLightColor); //If we have a float curve, bind it's graph to our update function if (PointLightFloatCurve)编译你的代码。
在内容浏览器中找到C++Classes文件夹。
右键点击LightActor,选择 基于LightActor创建蓝图类(Create Blueprint Class based on LightActor),并将蓝图Actor命名为BP_LightActor。
BP_LightActor的类默认值将按照如下方式显示:
阶段性代码
LightActor.h
//Copyright 1998-2022 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Components/TimelineComponent.h"
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "LightActor.generated.h"
UCLASS()
class FADINGLIGHTS_API ALightActor : public AActor
LightActor.cpp
//Copyright 1998-2022 Epic Games, Inc. All Rights Reserved.
#include "LightActor.h"
#include "Components/BoxComponent.h"
#include "Components/PointLightComponent.h"
// Sets default values
ALightActor::ALightActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
创建并绑定碰撞重叠事件
盒体组件需要拥有在Actor进入其碰撞边界时触发TimelineComponent的能力。
找到你的
LightActor.h文件的类定义,并在BrightnessMultiplier下声明如下内容:LightActor.h
C++protected: UFUNCTION() void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);然后,找到
LightActor.cpp文件并实现OnOverlapBegin函数。LightActor.cpp
C++void ALightActor::OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) { LightTimelineComp->Play(); }在
BeginPlay方法中绑定重叠函数:LightActor.cpp
C++//Binding our Box Component to our Light Actor's Overlap Function LightOverlapVolume->OnComponentBeginOverlap.AddDynamic(this, &ALightActor::OnOverlapBegin);编译你的代码。
已完成代码
LightActor.h
//Copyright 1998-2022 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Components/TimelineComponent.h"
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "LightActor.generated.h"
UCLASS()
class FADINGLIGHTS_API ALightActor : public AActor
LightActor.cpp
//Copyright 1998-2022 Epic Games, Inc. All Rights Reserved.
// Fill out your copyright notice in the Description page of Project Settings.
#include "LightActor.h"
#include "Components/BoxComponent.h"
#include "Components/PointLightComponent.h"
// Sets default values
ALightActor::ALightActor()
设置亮度轨道
当玩家与光源Actor的盒体组件边界重叠时,时间轴组件将需要使用浮点曲线来操控点光源组件的亮度值。
亮度的初始值为5000,并将在5秒钟内下降到0。
找到内容浏览器,选择添加(+)(Add (+))> 杂项(Miscellaneous)> 曲线(Curve)。
选择CurveFloat并将资产命名为BrightnessCurveFloat。
双击BrightnessCurveFloat,打开时间轴编辑器。
右键点击图表(Graph),然后选择添加关键点(Add Key),为浮点曲线添加两个关键点。 将第一个关键点的时间值调整为(0, 5000)。 将第二个关键点的时间值调整为(5, 0)。 你的BrightnessCurveFloat应如下所示:
保存BrightnessCurveFloat,然后回到内容浏览器,双击BP_LightActor以打开类默认值(Class Defaults)。
前往细节(Details)面板,在点光源浮点曲线(Point Light Float Curve)下拉菜单中,选择亮度曲线浮点(Brightness Curve Float)。
点击编译(Compile)和保存(Save)按钮。
设置颜色轨道
当玩家与光源Actor的盒体组件边界重叠时,PointLight时间轴将需要使用线性颜色曲线轨道来操控点光源组件的颜色属性。
找到内容浏览器,选择添加(+)(Add (+))> 杂项(Miscellaneous)> 曲线(Curve)。
选择CurveLinearColor并将资产命名为LinearColorCurve。
双击LinearColorCurve以打开时间轴编辑器。
双击第一个颜色关键点并修改,将RGB值修改为:(R:1、G:0.665、B:0.015)。
双击第二个颜色关键点并修改,将RGB值修改为:(R:0、G:0、B:0)。
点击选择图表上的第二个点(Point),并将时间设置为5秒。
你的LinearColorCurve应如下所示:
保存LinearColorCurve,然后回到内容浏览器,双击BP_LightActor以打开类默认值。
前往细节(Details)面板,在点光源浮点曲线(Point Light Float Curve)下拉菜单中,选择亮度曲线浮点(Brightness Curve Float)。
点击编译(Compile)和保存(Save)按钮。
关卡设置
为了充分展示你编写的代码的功能,需要从关卡中删除所有光源Actor。
在内容浏览器中找到BP_LightActor资产,将其选中并拖入关卡。
在世界大纲视图中选择BP_LightActor,找到细节(Details)面板并将位置(Location)设置设为(0, 0, 300),将缩放(Scale)设置设为(10, 10, 10)。
在世界大纲视图中删除定向光源Actor(DirectionalLight Actor)。
关卡内容应如下所示。
最终结果
现在,光源Actor和关卡已经完成设置,点击运行(PIE)(Play (PIE))即可自动持有旁观者Pawn。
你可以控制旁观者Pawn,可以找到光源Actor的盒体组件边界。
触发时间轴组件的播放功能之后,光源应该开始在5秒的时间跨度内变换颜色和亮度。