常用组件
UActorComponent:
ActorComponent 是组件的基础类,定义可被添加到不同类型 Actor 的重复使用行为。它们主要用于将几何体与 Actor 关联起来,如碰撞几何体或渲染网格体,控制 Actor 在世界场景中的移动方式、播放与 Actor 相关的声效、使 Actor 能投射光影到世界场景等。
UsceneComponent:
SceneComponent 是 ActorComponent 的延伸,拥有一个变形,即位置、旋转和尺寸。附加的一个变形意味着 SceneComponent 可以相互附着。
UPrimitiveComponent
UPrimitiveComponent
是虚幻引擎(UE)中用于渲染和物理交互的基础组件类。它继承自USceneComponent
,具有可视化的功能,可作为可视性剔除的粒度和渲染属性规范(如投射阴影等)。
UPrimitiveComponent
是UE中用于定义Actor几何形状和渲染属性的重要组件类,它为游戏的可视化和物理模拟提供了基础。
UCameraComponent:用于控制相机的组件。
ULightComponent:用于控制灯光的组件。
静态网格组件(Static Mesh Component)
UStaticMeshComponent* StaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMeshComponent"));
StaticMeshComponent->SetStaticMesh(YourStaticMesh);
动画组件(Animation Component)
UAnimInstance* AnimInstance = CreateDefaultSubobject<UAnimInstance>(TEXT("AnimationComponent"));
音频组件(Audio Component)
UAudioComponent* AudioComponent = CreateDefaultSubobject<UAudioComponent>(TEXT("AudioComponent"));
AudioComponent->SetSound(YourSound);
粒子系统组件(Particle System Component)
UParticleSystemComponent* ParticleComponent = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("ParticleComponent"));
ParticleComponent->SetTemplate(YourParticleSystem);
动画蒙太奇通知窗口组件
void UPlayMontageNotifyWindow::BranchingPointNotifyBegin(FBranchingPointNotifyPayload& BranchingPointPayload)
{
// 输出 BranchingPointPayload 的某些成员变量的值
UE_LOG(LogTemp, Display, TEXT("BranchingPointPayload Value: %f"), BranchingPointPayload.payloadValue);
}
“FBranchingPointNotifyPayload”通常是一个自定义的数据结构(结构体或类),用于传递与分支点通知相关的数据。
它包含了各种与动画蒙太奇(Montage)中的分支点相关的信息。具体包含哪些成员变量取决于项目的具体需求和设计。
它包含以下类型的信息:
- 分支点的标识或名称,以便识别特定的分支点。
- 与分支点相关的参数或数据,这些参数可能用于控制动画的流程、行为或其他相关逻辑。
- 可能还包含其他与动画状态、条件或事件相关的数据。
常用函数
UGameplayStatics
是一个静态类,提供了许多与游戏玩法相关的静态函数。通过这个类,你可以在不需要拥有该类实例的情况下,直接调用其中的函数来执行各种操作。
SpawnObject
:创建一个对象。BeginSpawningActorFromBlueprint
:从蓝图中生成实例,但不会自动执行它的构造脚本。BeginDeferredActorSpawnFromClass
:生成一个Actor
类的实例,但是不会自动执行它的构造脚本。FinishSpawningActor
:结束生成Actor
,执行构造脚本。GetActorArrayAverageLocation
:获取Actor
数组的平均位置。GetActorArrayBounds
:获取Actor
数组的边界。GetAllActorsOfClass
:获取此类的Actor
数组。GetAllActorsWithInterface
:获取拥有此接口的Actor
数组。GetAllActorsWithTag
:获取此Tag
的Actor
数组。GetGameInstance
:获取UGameInstance
。GetPlayerController
:获取APlayerController
。GetPawn
:获取APawn
。GetCharacter
:获取ACharacter
。GetPlayerCameraManager
:获取APlayerCameraManager
。OpenLevel
:加载关卡。LoadStreamLevel
:加载StreamLevel
。UnloadStreamLevel
:卸载StreamLevel
。GetWorld
:获取当前世界。GetAuthGameMode
:获取当前授权的游戏模式。GetGameStateBase
:获取游戏状态。ApplyDamage
:应用伤害。PlayWorldCameraShake
:播放世界相机震动。SpawnEmitterAtLocation
:在目标位置生成粒子。
TSubclassOf
是一个提供 UClass 类型安全性的模板类。例如,假设您正在创建一个弹丸类,该类允许设计器指定损坏类型。可以只创建一个 UClass 类型的 UPROPERTY,并希望设计器始终分配派生自 UDamageType 的类,或者可以使用 TSubclassOf 模板强制执行该选择。下面的示例代码说明了其中的区别:
/** type of damage */
UPROPERTY(EditDefaultsOnly, Category=Damage)
UClass* DamageType;
与
/** type of damage */
UPROPERTY(EditDefaultsOnly, Category=Damage)
TSubclassOf<UDamageType> DamageType;
在第二个声明中,模板类告诉编辑器的属性窗口仅列出派生自 UDamageType 的类作为属性的选项。在第一个声明中,可以选择任何 UClass。下图说明了这一点。
StrategyGame的弹丸蓝图示例
除了这种 UPROPERTY 安全性之外,您还可以获得 C++ 级别的类型安全性。如果尝试将不兼容的 TSubclassOf 类型相互分配,则会出现编译错误。如果尝试分配泛型 UClass,它将执行运行时检查以验证它是否可以执行分配。如果运行时检查失败,则结果值为 nullptr。
UClass* ClassA = UDamageType::StaticClass();
TSubclassOf<UDamageType> ClassB;
ClassB = ClassA; // Performs a runtime check
TSubclassOf<UDamageType_Lava> ClassC;
ClassB = ClassC; // Performs a compile time check
GetWorldTimerManager()
是UE4中用于获取全局定时器管理器的函数。全局定时器管理器用于管理游戏中的定时器,它存在于游戏实例对象上以及每个场景中。
通过调用GetWorldTimerManager()
,可以获取到全局定时器管理器的引用,然后可以使用该管理器来设置、暂停、恢复、清除定时器等操作。
以下是一个使用GetWorldTimerManager()
的示例代码:
FTimerHandle timerHandle;
GetWorldTimerManager().SetTimer(timerHandle, this, &YourClass::YourFunction, 5.0f, true);
在上述代码中,首先创建了一个FTimerHandle
类型的变量timerHandle
,用于保存定时器的句柄。然后,使用GetWorldTimerManager().SetTimer()
函数来设置一个定时器。该函数的参数包括:
timerHandle
:定时器句柄的引用,用于保存设置的定时器。this
:指定定时器所属的对象。&YourClass::YourFunction
:定时器到期时要执行的函数指针。5.0f
:定时器的时间间隔,单位为秒。true
:表示定时器是否循环执行。
这样,就设置了一个每隔5秒执行一次YourFunction
函数的定时器。
获取自身自带的组件
目标类型* 变量名= Cast<目标类型>(this->GetComponentByClass(目标类型::StaticClass()));
//用于根据指定的组件类来获取该类的组件实例。
//StaticClass() 是一个用于获取类的静态信息的函数。
需要注意的是,GetComponentByClass
返回的是 UActorComponent*
类型的指针,需要使用 Cast
函数进行类型转换以获取特定类型的组件指针。如果转换失败(即组件不是指定的类型),则转换后的指针为 nullptr
,可以通过判断指针是否为空来处理这种情况。
角色运动绑定函数
“BindAction”通常用于在 Unreal Engine 4(UE4)中绑定输入动作到特定的函数或方法。它是一种将用户输入(例如按下键盘按键、点击鼠标等)与游戏中的操作或事件关联起来的方式。
PlayerInputComponent->BindAction("DiscardWeapon", IE_Pressed, this, &AMyCharacter::DiscardWeapon);
在上述代码中,通过PlayerInputComponent->BindAction
将名为“DiscardWeapon”的动作与AMyCharacter
类中的DiscardWeapon
函数进行绑定,当该动作被触发(例如按下对应的按键)时,将调用AMyCharacter::DiscardWeapon
函数。
除了IE_Pressed
,还有其他的触发条件可用于BindAction
,它们定义在EInputEvent
枚举中,具体包括:
IE_Released
:表示当按键被松开时触发。IE_Repeat
:用于连续触发的情况,例如按住按键时会不断重复触发相关操作。IE_DoubleClick
:表示双击按键时触发。IE_Axis
:轴事件类型,通常用于处理类似摇杆或鼠标移动等持续性的输入,并会返回一个值。IE_MAX
:枚举的最大值,一般不用于实际的绑定操作。
调整鼠标灵敏度
“AddControllerYawInput”是 Unreal Engine 4(UE4)中 Pawn 类的一个函数,用于给控制器的控制旋转添加输入(影响偏航),前提是该控制器是本地玩家控制器。
此函数的值会乘以玩家控制器的“InputYawScale”值。通常用于实现角色或 pawn 根据输入(例如鼠标移动)来进行左右方向的旋转。
PlayerInputComponent->BindAxis("Turn", this, &AMonsterPlayer::YawCamera);
PlayerInputComponent->BindAxis("LookUp", this, &AMonsterPlayer::PitchCamera);
void AMonsterPlayer::YawCamera(float AxisValue)
{
AddControllerYawInput(AxisValue * MouseSpeed);
}
通过改变自己定义的MouseSpeed的值来更改鼠标移动速度
延迟函数
首先,创建一个 FLatentActionInfo
结构体,用于存储异步操作的相关信息,例如延迟后要执行的函数、函数的归属者以及异步操作的 ID 等。然后,通过 UKismetSystemLibrary::Delay
函数来设置延迟。
#include "Kismet/GameplayStatics.h"
#include "Engine/World.h"
UCLASS()
class YOURCLASS : public AActor
{
public:
// 延迟结束后的回调函数,声明处必须加 UFUNCTION,否则反射系统找不到这个函数
UFUNCTION()
void DelayFinish();
void BeginPlay() override
{
Super::BeginPlay();
// 创建一个 LatentInfo,用不到 Linkage 直接传 0(不能是-1),UUID 随机生成,指定延迟后要执行的函数 ExecutionFunction,以及 ExecutionFunction 的归属者 this
const FLatentActionInfo LatentInfo(0, FMath::Rand(), TEXT("DelayFinish"), this);
UKismetSystemLibrary::Delay(this, 3.0f, LatentInfo);
}
};
// 定义延迟结束后的回调函数
void YOURCLASS::delayFinish()
{
// 在这里添加延迟结束后要执行的具体操作
UE_LOG(LogTemp, Log, TEXT("Delay 结束!"));
}
定义了一个 delayFinish
函数作为延迟结束后的回调函数。在 BeginPlay
函数中,创建了 FLatentActionInfo
结构体实例 LatentInfo
,设置了 Linkage
为 0(虽然资料较少,但一般直接传 0 即可),使用 FMath::Rand
生成随机的 UUID
,指定延迟结束后要执行的函数为 delayFinish
,并将 this
作为 ExecutionFunction
的归属者(即表明 delayFinish
是当前类的成员函数)。最后,通过 UKismetSystemLibrary::Delay
函数传入当前对象 this
、延迟时间 3.0f
和 LatentInfo
来启动延迟操作。
FLatentActionInfo
是一个结构体,用于存储异步操作的相关信息。它包含了以下几个成员:
Linkage
:执行函数中的恢复点,是一个整数。一般情况下,如果用不到可以直接传 0,但不能是-1。UUID
:本次异步操作的 ID,用于标识此次操作。通常可以使用FMath::Rand()
生成一个随机数,或者通过其他方式生成一个唯一的标识。ExecutionFunction
:要执行的函数名,类型为FName
。需要使用TEXT()
宏进行转换。CallbackTarget
:执行函数的归属者,即表明ExecutionFunction
是CallbackTarget
的成员函数。它是一个TObjectPtr<UObject>
类型的弱指针。
UKismetSystemLibrary
UKismetSystemLibrary
是虚幻引擎(Unreal Engine)中的一个类,它包含了许多有用的函数,可用于各种不同的操作,例如打印调试信息、进行射线检测、移动组件、加载资产、获取游戏相关信息等。
以下是UKismetSystemLibrary
中一些常见函数的介绍:
StackTrace
:打印一个堆栈跟踪到日志,以便查看蓝图是如何到达某个节点的。IsValid
:判断一个对象是否可用(非空且未被标记为待删除)。GetObjectName
:返回指定对象的实际对象名称。GetPathName
:返回指定对象的完整路径名。GetDisplayName
:返回对象的显示名称(在编辑器构建中是 actor 标签,在非编辑器构建中是实际对象名称),主要用于调试辅助显示,不应被用于唯一标识 actor,也不适合用于向游戏的最终用户显示,因为它没有被本地化。GetClassDisplayName
:返回一个类的显示名称。GetEngineVersion
:获取引擎的版本号,用于向最终用户显示。GetGameName
:获取当前游戏的名称。GetPlatformUserName
:获取操作系统中的当前用户名。GetGameTimeInSeconds
:获取当前游戏时间(以秒为单位),当游戏暂停时它会停止,并且会受到慢动作的影响。此函数需要传入一个WorldContextObject
参数,表示世界上下文。IsServer
:根据提供的世界上下文对象,判断该对象所在的世界是否为主机。IsDedicatedServer
:判断是否运行在专用服务器上。IsPackagedForDistribution
:判断是否是为了分发而打包的构建。GetUniqueDeviceId
/GetDeviceId
:获取平台特定的唯一设备 ID。MakeLiteralInt
/MakeLiteralFloat
/MakeLiteralBool
:分别创建一个指定值的整型、浮点型或布尔型的字面值。Delay
:用于实现延迟操作。可以创建一个FLatentActionInfo
结构体来设置延迟的相关信息,例如延迟后要执行的函数、函数的归属者以及异步操作的 ID 等,然后通过该函数来启动延迟。LineTraceSingleByProfile
:进行基于配置文件的单次射线检测。
射线检测
虚幻引擎中的射线检测主要分为单通道和多通道检测,根据检测目标还可分为通道检测和目标物体类型检测。常见的射线检测类型包括:
单通道射线检测:通过指定通道类型(如ECC_Visibility
)进行检测。定义射线的起始位置、方向和碰撞返回数据(FHitResult
)。需注意被检测对象在该通道的“Visibility”需设置为阻挡状态,否则可能检测不到。例如:
FHitResult hitResult;
bool bTempHit = UKismetSystemLibrary::LineTraceSingleByProfile(GetWorld(),hitResult, startLocation, endLocation, ECC_Visibility);
单通道根据目标物体类型进行检测:首先定义FCollisionObjectQueryParams
的参数,然后使用AddObjectTypesToQuery
方法添加目标通道。例如:
FCollisionObjectQueryParams tempObjectType;
tempObjectType.AddObjectTypesToQuery(ECC_WorldDynamic);
bool bTempHit2 = UKismetSystemLibrary::LineTraceSingleByProfile(GetWorld(),hitResult, startLocation, endLocation, tempObjectType);
根据 Profile 的名称进行检测:可以根据在项目设置-碰撞-Preset 中新建的碰撞预设的名字进行检测,例如“CPPTest”。也可以通过FCollisionQueryParams
类型参数添加忽略检测的 Actor。例如:
bool bTempHit5 = UKismetSystemLibrary::LineTraceSingleByProfile(GetWorld(),hitResult, startLocation, endLocation, "CPPTest");
// 或添加忽略检测的 Actor
FCollisionQueryParams tempQueryParams;
tempQueryParams.AddIgnoredActor(this->GetUniqueID());
bool bTempHit5 = GetWorld()->LineTraceSingleByProfile(hitResult, startLocation, endLocation, "CPPTest", tempQueryParams);
多通道射线检测:
- 根据通道直接使用
LineTraceMultiByChannel
,与单通道使用类似,但可返回多个结果。 - 多对象类型检测使用
LineTraceMultiByObjectType
,通过FCollisionObjectQueryParams
的AddObjectTypesToQuery
添加多个目标通道。 - 根据碰撞预设名进行多通道检测的方式可参考单通道根据 Profile 名称检测的使用方式。
float SeekRadius = 100.0f;
TArray<FHitResult> HitResults;
FVector BeginLocation = FollowCamera->GetComponentLocation(); // 起点位置
FVector EndLocation = BeginLocation + FollowCamera->GetForwardVector() * 1000; // 终点位置
TArray<TEnumAsByte<EObjectTypeQuery>> ObjectTypes;
ObjectTypes.Add(EObjectTypeQuery::ObjectTypeQuery2); // 添加要检测的对象类型,例如 Pawn
TArray<AActor*> IgnoreActors; // 忽略的 Actor 数组
bool bIsHit = UKismetSystemLibrary::SphereTraceMultiForObjects(GetWorld(), BeginLocation, EndLocation, SeekRadius, ObjectTypes, true, IgnoreActors, EDrawDebugTrace::ForDuration, HitResults, true);
if (bIsHit) {
for (FHitResult HitResult : HitResults) {
if (HitResult.GetActor()!= NULL) {
// 对检测到的 Actor 进行相应的处理
}
}
}
SphereTraceMultiForObjects
是 Unreal Engine 中用于进行球形碰撞检测的函数。它可以检测从起始点到结束点形成的球体范围内的多个对象。
以下是该函数的参数说明:
WorldContextObject
:提供世界上下文的对象指针,通常是GetWorld()
。Start
:球体检测的起始位置向量。End
:球体检测的结束位置向量(用于确定球体的方向和范围)。Radius
:球体的半径。ObjectTypes
:要检测的对象类型数组。通过TEnumAsByte<EObjectTypeQuery>
枚举指定对象类型。bTraceComplex
:是否追踪复杂碰撞。IgnoreActors
:要忽略的Actor数组。DrawDebugType
:调试绘制类型,例如EDrawDebugTrace::ForDuration
表示在一段时间内显示调试痕迹。OutHits
:用于存储碰撞结果的FHitResult
数组。bIgnoreSelf
(可选):是否忽略自身。
该函数返回一个布尔值,表示是否检测到碰撞。如果检测到碰撞,碰撞结果将存储在 OutHits
数组中
另外,还有其他形状的扫描射线检测,如SweepSingleByChannel
,需提前定义扫描形状,可通过大小、类型、方向决定扫描形状效果。其相关函数SweepMultiByObjectType
、SweepMultiByProfile
的使用方式类似。
在进行射线检测时,需定义起始位置坐标和方向,同时设置相关变量的值,通常会与摄像机进行绑定。结束位置一般设置得足够远,以确保射线能够检测到目标物体。