目录
一,子弹类型
// MyActor.h文件
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/SphereComponent.h"
#include "GameFrameWork/ProjectileMovementComponent.h"
#include "MyActor.generated.h"
// ...
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UStaticMeshComponent> Sphere;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<USphereComponent> SphereCollision;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UProjectileMovementComponent> ProjectileMovement;
// MyActor.cpp文件
AMyActor::AMyActor() {
PrimaryActorTick.bCanEverTick = true;
Sphere = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Sphere"));
SphereCollision = CreateDefaultSubobject<USphereComponent>(TEXT("SphereCollision"));
ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileMovement"));
static ConstructorHelpers::FObjectFinder<UStaticMesh> StaticSphereMesh(TEXT("/Engine/BasicShapes/Sphere.Sphere"));
RootComponent = Sphere;
SphereCollision->SetupAttachment(RootComponent);
ProjectileMovement->SetUpdatedComponent(RootComponent);
Sphere->SetStaticMesh(StaticSphereMesh.Object);
ProjectileMovement->InitialSpeed = 500.0;
ProjectileMovement->MaxSpeed = 2000.0;
}
二,带有增强输入的角色类型
// MyCharacter.h文件
#include "CoreMinimal.h"
#include "InputActionValue.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "GameFramework/Controller.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/Character.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "MyCharacter.generated.h"
class UInputAction;
class UInputMappingContext;
// ...
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<USpringArmComponent> SpringArm;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UCameraComponent> Camera;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UInputMappingContext> DefaultMappingContext;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UInputAction> MoveAction;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UInputAction> LookAction;
public:
void Move(const FInputActionValue& value);
void Look(const FInputActionValue& value);
// ...
// MyCharacter.cpp文件
AMyCharacter::AMyCharacter()
{
PrimaryActorTick.bCanEverTick = true;
SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));
Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
SpringArm->TargetArmLength = 400.0f;
SpringArm->bUsePawnControlRotation = true; // 控制其附加的相机是否随控制器旋转
SpringArm->SetupAttachment(RootComponent);
Camera->SetupAttachment(SpringArm);
// 控制器只影响相机不影响角色
bUseControllerRotationPitch = false;
bUseControllerRotationRoll = false;
bUseControllerRotationYaw = false;
// 控制角色的身体(Yaw轴)平滑地转向其移动方向
GetCharacterMovement()->bOrientRotationToMovement = true;
}
void AMyCharacter::BeginPlay()
{
Super::BeginPlay();
if (auto PlayerController = Cast<APlayerController>(Controller))
if (auto Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if (auto EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent))
{
EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMyCharacter::Move);
EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AMyCharacter::Look);
}
}
void AMyCharacter::Move(const FInputActionValue& value)
{
FVector2D MovementVector = value.Get<FVector2D>();
if (Controller)
{
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
const FVector FowardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
AddMovementInput(FowardDirection, MovementVector.Y);
AddMovementInput(RightDirection, MovementVector.X);
}
}
// 5.7使用IMC_Default 和 IMC_MouseLook 将按键和鼠标操作分开
// IMC_Default → 按键操作(移动、跳跃、冲刺、交互等)
// IMC_MouseLook → 鼠标操作(视角旋转)
void AMyCharacter::Look(const FInputActionValue& value)
{
FVector2D LookAxisVector = value.Get<FVector2D>();
if (Controller)
{
AddControllerYawInput(LookAxisVector.X);
AddControllerPitchInput(LookAxisVector.Y);
}
}
三,Interface 接口
// MyInterface.h文件
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "MyInterface.generated.h"
// 空壳类,仅供虚幻反射系统(UHT)识别,使其在蓝图中可见,不包含函数实现;
// 如使用该类多重继承,会造成菱形继承问题,所以使用IMyInterface;
UINTERFACE(MinimalAPI)
class UMyInterface : public UInterface
{
GENERATED_BODY()
};
class MYCPP_API IMyInterface
{
GENERATED_BODY()
public:
// 接口函数,继承自该接口的类会重写这些函数;
virtual void func1() = 0;
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "MyInterface")
void Func2();
};
// MyActor.h
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyInterface.h"
#include "MyActor.generated.h"
UCLASS()
class CPP_API AMyActor : public AActor, public IMyInterface // UE的UObject体系禁止多重继承
{
GENERATED_BODY()
public:
AMyActor();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
virtual void func1() override;
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "MyInterface")
void func2();
};
// MyActor.cpp
void AMyActor::func1()
{
GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Green, TEXT("AMyActor::func1"));
}
void AMyActor::Func2_Implementation()
{
GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Green, TEXT("IMyInterface::func2_Implementation"));
}
// 判断是否拥有该接口,蓝图则使用Does Object Implement Interface节点
// 通过反射的Uclass来判断
if (IsValid(myActor))
{
if (IMyInterface* MyInterfaceActor = Cast<IMyInterface>(myActor))
{
MyInterfaceActor->func1();
IMyInterface::Execute_func2(myActor);
}
}
四,TimerHandle 定时器
// MyTimerHandle.h
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TimerManager.h"
#include "MyTimerHandle.generated.h"
UCLASS()
class MYCPP_API AMyTimerHandle : public AActor
{
GENERATED_BODY()
public:
AMyTimerHandle();
protected:
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
public:
virtual void Tick(float DeltaTime) override;
// FTimerHandle 是定时器的唯一标识符,通过它来操纵和控制定时器;
// 同一个 FTimerHandle 同时只能绑定一个定时器;
FTimerHandle MyTimerHandle;
// 回调函数
inline void func1() { UE_LOG(LogTemp, Warning, TEXT("func1()")); };
inline void func2() { UE_LOG(LogTemp, Warning, TEXT("func2()")); };
};
// MyTimerHandle.cpp
void AMyTimerHandle::BeginPlay()
{
Super::BeginPlay();
GetWorldTimerManager().SetTimer(
MyTimerHandle, // 传入句柄引用(绑定具体定时器)
this, // 执行回调的对象
&AMyTimerHandle::func1, // 回调函数
2.0f, // 每2秒执行一次
true, // true=循环,false=只执行一次
1.0f // (可选)延迟1秒后首次执行
);
// 第二绑定会覆盖第一个
GetWorld()->GetTimerManager().SetTimer(MyTimerHandle, this, &AMyTimerHandle::func2, 2.0f, true, 1.0f);
}
void AMyTimerHandle::EndPlay(const EEndPlayReason::Type EndPlayReason) {
if (GetWorld())
GetWorld()->GetTimerManager().ClearAllTimersForObject(this);
Super::EndPlay(EndPlayReason);
}
//void AMyTimerHandle::EndPlay(const EEndPlayReason::Type EndPlayReason) {
// if (GetWorld() && MyTimerHandle.IsValid())
// GetWorld()->GetTimerManager().ClearTimer(MyTimerHandle);
// Super::EndPlay(EndPlayReason);
//}
//void AMyTimerHandle::EndPlay(const EEndPlayReason::Type EndPlayReason) {
// GetWorldTimerManager().ClearTimer(MyTimerHandle);
// Super::EndPlay(EndPlayReason);
//}
五,3D Widget
// 注意添加依赖的模块
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });
// MyActor.h
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/WidgetComponent.h"
#include "MyActor.generated.h"
UCLASS()
class MYCPP_API AMyActor : public AActor
{
GENERATED_BODY()
...
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UWidgetComponent> MyWidget;
};
// MyActor.cpp
#include "MyActor.h"
AMyActor::AMyActor()
{
...
MyWidget = CreateDefaultSubobject<UWidgetComponent>(TEXT("MyWidget"));
if (MyWidget)
MyWidget->SetupAttachment(RootComponent);
ConstructorHelpers::FClassFinder<UUserWidget> MyWidgetObject(TEXT("/Game/BP_Widget.BP_Widget_C"));
if (MyWidgetObject.Succeeded())
{
MyWidget->SetWidgetClass(MyWidgetObject.Class);
MyWidget->SetWidgetSpace(EWidgetSpace::Screen);
MyWidget->SetDrawSize(FVector2D(400, 20));
MyWidget->SetRelativeLocation(FVector(0,0,100));
}
}
void AMyActor::test()
{
UUserWidget* UserWidgetObject = MyWidget->GetUserWidgetObject();
if(UserWidgetObject)
{
UClass* UserWidgetClass = UserWidgetObject->GetClass();
// 获取和设置蓝图内的变量CurHealth
FProperty* CurHealthProperty = UserWidgetClass->FindPropertyByName(TEXT("CurHealth"));
if (CurHealthProperty)
{
if (FFloatProperty* FloatProperty = CastField<FFloatProperty>(CurHealthProperty))
{
float Value = FloatProperty->GetPropertyValue_InContainer(UserWidgetObject);
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Blue, FString::Printf(TEXT("CurHealth: %f"), Value));
}
// 虽然在蓝图内设置的是浮点,实际存储的却不是
else if (FNumericProperty* NumericProperty = CastField<FNumericProperty>(CurHealthProperty))
{
void* valueptr = NumericProperty->ContainerPtrToValuePtr<void>(UserWidgetObject);
float Value = NumericProperty->GetFloatingPointPropertyValue(valueptr);
NumericProperty->SetFloatingPointPropertyValue(valueptr, Value - 10);
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Blue, FString::Printf(TEXT("CurHealth: %.2f"), Value - 10));
}
}
}
}
六,Timeline
// MyTimelineActor.h
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/TimelineComponent.h"
#include "MyTimelineActor.generated.h"
UCLASS()
class MYCPP_API AMyTimelineActor : public AActor
{
GENERATED_BODY()
...
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyTimeline")
TObjectPtr<UTimelineComponent> MyTimeline; // 相当于蓝图 Timeline 节点
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyTimeline")
TObjectPtr<UCurveFloat> MyCurveFloat;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyTimeline")
TObjectPtr<UCurveVector> MyCurveVector;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyTimeline")
TObjectPtr<UCurveLinearColor> MyCurveLinearColor;
FOnTimelineFloat MyTimelineFloatDelegate;
FOnTimelineVector MyTimelineVectorDelegate;
FOnTimelineLinearColor MyTimelineLinearColorDelegate;
FOnTimelineEvent MyTimelineEventDelegate;
public:
UFUNCTION()
void FunUpdate_Float(float value);
UFUNCTION()
void FunFinishEvent();
};
// MyTimelineActor.cpp
...
AMyTimelineActor::AMyTimelineActor()
{
PrimaryActorTick.bCanEverTick = true;
ConstructorHelpers::FObjectFinder<UCurveFloat> CurveFloatAsset(TEXT("/Game/_TEST/MyCurveFloat.MyCurveFloat"));
MyCurveFloat = CurveFloatAsset.Object;
MyTimeline = CreateDefaultSubobject<UTimelineComponent>(TEXT("MyTimeLine"));
MyTimeline->SetTimelineLengthMode(TL_TimelineLength);
MyTimeline->SetTimelineLength(2);
}
void AMyTimelineActor::BeginPlay()
{
Super::BeginPlay();
if (MyCurveFloat && MyTimeline)
{
MyTimelineFloatDelegate.BindUFunction(this, FName("FunUpdate_Float"));
MyTimeline->AddInterpFloat(MyCurveFloat, MyTimelineFloatDelegate); // 根据当前的播放进度计算对应Curve值,然后通过委托广播出去;
MyTimelineEventDelegate.BindUFunction(this, FName("FunFinishEvent"));
MyTimeline->SetTimelineFinishedFunc(MyTimelineEventDelegate);
// 可在指定的地方播放
MyTimeline->PlayFromStart();
}
}
// 回调函数
void AMyTimelineActor::FunUpdate_Float(float value)
{
UE_LOG(LogTemp, Warning, TEXT("Fun_Float: %f"), value);
}
void AMyTimelineActor::FunFinishEvent()
{
UE_LOG(LogTemp, Warning, TEXT("FunFinishEvent"));
}
七,射线检查
// MyCharacter.h文件
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "MyCharacter.generated.h"
UCLASS()
class MYCPP_API AMyCharacter : public ACharacter
{
...
public:
...
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
UPROPERTY(EditAnywhere)
TSubclassOf<AActor> MyClass;
void test();
};
// MyCharacter.cpp文件
#include "MyCharacter.h"
AMyCharacter::AMyCharacter()
{
PrimaryActorTick.bCanEverTick = true;
static ConstructorHelpers::FClassFinder<AActor> MyActorAsset(TEXT("/Game/_TEST/BP_TEST.BP_TEST_C"));
if (MyActorAsset.Succeeded())
MyClass = MyActorAsset.Class;
}
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if(PlayerInputComponent)
PlayerInputComponent->BindKey(EKeys::One, IE_Pressed, this, &AMyCharacter::test);
}
void AMyCharacter::test()
{
FHitResult OutHit;
FVector Start = GetActorLocation();
FVector End = Start + GetActorForwardVector() * 200;
if (GetWorld()->LineTraceSingleByChannel(OutHit, Start, End, ECC_Visibility))
DrawDebugSphere(GetWorld(), OutHit.Location, 10.0f, 12, FColor::Green, false, 5.0f);
DrawDebugLine(GetWorld(), Start, End, FColor::Red, false, 5.0f, 0, 1.0f);
}
void AMyCharacter::test()
{
TArray<FHitResult> OutHits;
FVector Start = GetActorLocation();
FVector End = Start + GetActorForwardVector() * 500;
//多通道检测时,击中时即停止检测,输出在其射线路径上交叉的对象
if (GetWorld()->LineTraceMultiByChannel(OutHits, Start, End, ECC_Visibility))
for(FHitResult& OutHit : OutHits)
DrawDebugSphere(GetWorld(), OutHit.Location, 10.0f, 12, FColor::Green, false, 5.0f);
DrawDebugLine(GetWorld(), Start, End, FColor::Red, false, 5.0f, 0, 1.0f);
}
八,软引用

// .h
...
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FSoftObjectPath A;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSoftObjectPtr<UObject> B; //如为AActor类型,则在Detail面板内选择大纲内的对象
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FSoftClassPath C;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSoftClassPtr<UObject> D;
...
// .cpp
#include "MyActor.h"
#include "Engine/AssetManager.h"
void AMyActor::BeginPlay()
{
...
// 同步加载(当前线程会一直等待,直到资源完全加载进内存,如还有LoadObject/LoadClass/StaticLoadObject)
FSoftObjectPath ObjectPath(TEXT("/Game/T_Image.T_Image"));
TSharedPtr<FStreamableHandle> SyncHandle = UAssetManager::GetStreamableManager().RequestSyncLoad(ObjectPath);
if (SyncHandle)
{
UTexture2D* Image = Cast<UTexture2D>(SyncHandle->GetLoadedAsset());
if (Image)
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, FString::Printf(TEXT("Image Name: %s"), *Image->GetName()));
}
// 异步加载(不阻塞当前线程,资源在后台线程加载,完成后通过回调(Delegate) 通知)
FSoftObjectPath ObjectPath1(TEXT("/Game/T_Image1.T_Image1"));
TSharedPtr<FStreamableHandle> AsyncHandle = UAssetManager::GetStreamableManager().RequestAsyncLoad(ObjectPath1);
if (AsyncHandle)
{
UTexture2D* Image1 = Cast<UTexture2D>(AsyncHandle->GetLoadedAsset());
if (Image1)
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, FString::Printf(TEXT("Image1 Name: %s"), *Image1->GetName()));
}
}
九,共享指针
class TestClass
{
public:
TestClass(int a = 0):_a(a){}
~TestClass(){UE_LOG(LogTemp, Warning, TEXT("~TestClass()"));}
int32 _a = 0;
};
TestClass* ptr = new TestClass(1); // 原生指针
TSharedPtr<TestClass> SharedPtr1(ptr); // 不推荐
ptr = nullptr;
TSharedPtr<TestClass> SharedPtr2(new TestClass(2));
TSharedPtr<TestClass> SharedPtr3(SharedPtr2);
TSharedPtr<TestClass> SharedPtr4 = nullptr;
SharedPtr4 = MakeShareable(new TestClass(4));
TSharedPtr<TestClass, ESPMode::ThreadSafe> SharedPtr5(new TestClass(5));
if (SharedPtr4.IsValid())
{
auto val4 = SharedPtr4->_a;
auto Count4_1 = SharedPtr4.GetSharedReferenceCount();
UE_LOG(LogTemp, Warning, TEXT("SharedPtr4 val: %d, ReferenceCount: %d!"), val4, Count4_1);
if (SharedPtr4.IsUnique())
UE_LOG(LogTemp, Warning, TEXT("SharedPtr4 Is Unique!"));
SharedPtr4.Reset();
auto Count4_2 = SharedPtr4.GetSharedReferenceCount();
UE_LOG(LogTemp, Warning, TEXT("SharedPtr4 Reset and ReferenceCount: %d!"), Count4_2);
}
TSharedRef<TestClass> SharedRef(new TestClass(40)); // 共享引用必须指向有效对象
if (SharedRef.IsUnique())
{
auto val = SharedRef->_a; // SharedRef.Get()._a;
UE_LOG(LogTemp, Warning, TEXT("SharedRef Is Unique, val: %d!"), val);
SharedRef = SharedPtr2.ToSharedRef(); // 共享指针转化为共享引用,引用计数+1
auto Count = SharedRef.GetSharedReferenceCount();
UE_LOG(LogTemp, Warning, TEXT("SharedRef ReferenceCount: %d!"), Count);
SharedPtr3 = SharedRef; //共享引用可直接转化为共享指针
auto val3 = SharedPtr3->_a;
UE_LOG(LogTemp, Warning, TEXT("SharedPtr3 val: %d!, ReferenceCount: %d!"), val3, Count);
}
TSharedPtr<TestClass> SharedPtr6 = MakeShareable(new TestClass(6));
TSharedRef<TestClass> SharedRef6(new TestClass(60));
TWeakPtr<TestClass> WeakPtr1(SharedPtr6);
TWeakPtr<TestClass> WeakPtr2(SharedRef6);
if (WeakPtr1.IsValid())
{
TSharedPtr<TestClass> SharedPtr7 = WeakPtr1.Pin();
if (SharedPtr7.IsValid()) {
UE_LOG(LogTemp, Warning, TEXT("SharedPtr7 val: %d!"), SharedPtr7->_a);
UE_LOG(LogTemp, Warning, TEXT("SharedPtr7 ReferenceCount: %d!"), SharedPtr7.GetSharedReferenceCount());
}
}
十,蓝图函数库
// #include "Kismet/BlueprintFunctionLibrary.h"
// 所有暴露给蓝图函数库的抽象基类,其子类的函数或方法应为静态
UCLASS(Abstract, MinimalAPI)
class UBlueprintFunctionLibrary : public UObject
{
// 会自动把访问权限重置为 public,并要求你手动写构造函数
GENERATED_UCLASS_BODY()
// 决定了当前该函数库函数在调用时应该运行在哪个“空间”
// 返回值为:FUNCTIONCALLSPACE_Server/FUNCTIONCALLSPACE_Client/FUNCTIONCALLSPACE_Anywhere
ENGINE_API virtual int32 GetFunctionCallspace(UFunction* Function, FFrame* Stack) override;
};
// UGameplayStatics 是UE提供的一个蓝图函数库,有很多静态辅助函数;
UCLASS(MinimalAPI)
class UGameplayStatics : public UBlueprintFunctionLibrary
{
GENERATED_UCLASS_BODY()
// --- Create Object
UFUNCTION(BlueprintCallable, Category = "Spawning", meta = (BlueprintInternalUseOnly = "true", DefaultToSelf = "Outer"))
static ENGINE_API UObject* SpawnObject(TSubclassOf<UObject> ObjectClass, UObject* Outer);
// --- Spawning functions ------------------------------
UFUNCTION(BlueprintCallable, Category = "Spawning", meta = (WorldContext = "WorldContextObject", UnsafeDuringActorConstruction = "true", BlueprintInternalUseOnly = "true", DeprecatedFunction = "Note", DeprecationMessage = "Use BeginSpawningActorFromClass"))
static ENGINE_API class AActor* BeginSpawningActorFromBlueprint(const UObject * WorldContextObject, const class UBlueprint* Blueprint, const FTransform & SpawnTransform, bool bNoCollisionFail);
UFUNCTION(BlueprintCallable, Category = "Spawning", meta = (WorldContext = "WorldContextObject", UnsafeDuringActorConstruction = "true", BlueprintInternalUseOnly = "true"))
static ENGINE_API class AActor* BeginDeferredActorSpawnFromClass(const UObject * WorldContextObject, TSubclassOf<AActor> ActorClass, const FTransform & SpawnTransform, ESpawnActorCollisionHandlingMethod CollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::Undefined, AActor * Owner = nullptr, ESpawnActorScaleMethod TransformScaleMethod = ESpawnActorScaleMethod::MultiplyWithRoot);
UFUNCTION(BlueprintCallable, Category = "Spawning", meta = (UnsafeDuringActorConstruction = "true", BlueprintInternalUseOnly = "true"))
static ENGINE_API class AActor* FinishSpawningActor(class AActor* Actor, const FTransform & SpawnTransform, ESpawnActorScaleMethod TransformScaleMethod = ESpawnActorScaleMethod::MultiplyWithRoot);
// --- Actor functions ------------------------------
UFUNCTION(BlueprintCallable, Category="Transformation")
static ENGINE_API FVector GetActorArrayAverageLocation(const TArray<AActor*>& Actors);
UFUNCTION(BlueprintCallable, Category="Collision")
static ENGINE_API void GetActorArrayBounds(const TArray<AActor*>& Actors, bool bOnlyCollidingComponents, FVector& Center, FVector& BoxExtent);
UFUNCTION(BlueprintCallable, Category="Actor", meta=(WorldContext="WorldContextObject", DeterminesOutputType="ActorClass"))
static ENGINE_API class AActor* GetActorOfClass(const UObject* WorldContextObject, TSubclassOf<AActor> ActorClass);
UFUNCTION(BlueprintCallable, Category="Actor", meta=(WorldContext="WorldContextObject", DeterminesOutputType="ActorClass", DynamicOutputParam="OutActors"))
static ENGINE_API void GetAllActorsOfClass(const UObject* WorldContextObject, TSubclassOf<AActor> ActorClass, TArray<AActor*>& OutActors);
UFUNCTION(BlueprintCallable, Category="Actor", meta=(WorldContext="WorldContextObject", DeterminesOutputType="Interface", DynamicOutputParam="OutActors"))
static ENGINE_API void GetAllActorsWithInterface(const UObject* WorldContextObject, TSubclassOf<UInterface> Interface, TArray<AActor*>& OutActors);
UFUNCTION(BlueprintCallable, Category="Actor", meta=(WorldContext="WorldContextObject"))
static ENGINE_API void GetAllActorsWithTag(const UObject* WorldContextObject, FName Tag, TArray<AActor*>& OutActors);
UFUNCTION(BlueprintCallable, Category = "Actor", meta = (WorldContext="WorldContextObject", DeterminesOutputType="ActorClass", DynamicOutputParam="OutActors"))
static ENGINE_API void GetAllActorsOfClassWithTag(const UObject* WorldContextObject, TSubclassOf<AActor> ActorClass, FName Tag, TArray<AActor*>& OutActors);
UFUNCTION(BlueprintPure, Category = "Actor")
static ENGINE_API AActor* FindNearestActor(FVector Origin, const TArray<AActor*>& ActorsToCheck, float& Distance);
// --- Player functions ------------------------------
UFUNCTION(BlueprintPure, Category = "Game", meta = (WorldContext = "WorldContextObject"))
static ENGINE_API class UGameInstance* GetGameInstance(const UObject * WorldContextObject);
UFUNCTION(BlueprintPure, Category = "Game", meta = (WorldContext = "WorldContextObject", UnsafeDuringActorConstruction = "true"))
static ENGINE_API int32 GetNumPlayerStates(const UObject * WorldContextObject);
UFUNCTION(BlueprintPure, Category = "Game", meta = (WorldContext = "WorldContextObject", UnsafeDuringActorConstruction = "true"))
static ENGINE_API class APlayerState* GetPlayerState(const UObject * WorldContextObject, int32 PlayerStateIndex);
UFUNCTION(BlueprintPure, Category = "Game", meta = (WorldContext = "WorldContextObject", UnsafeDuringActorConstruction = "true"))
static ENGINE_API class APlayerState* GetPlayerStateFromUniqueNetId(const UObject * WorldContextObject, const FUniqueNetIdRepl & UniqueId);
UFUNCTION(BlueprintPure, Category = "Game", meta = (WorldContext = "WorldContextObject", UnsafeDuringActorConstruction = "true"))
static ENGINE_API int32 GetNumPlayerControllers(const UObject * WorldContextObject);
UFUNCTION(BlueprintPure, Category = "Game", meta = (WorldContext = "WorldContextObject", UnsafeDuringActorConstruction = "true"))
static ENGINE_API int32 GetNumLocalPlayerControllers(const UObject * WorldContextObject);
UFUNCTION(BlueprintPure, Category = "Game", meta = (WorldContext = "WorldContextObject", UnsafeDuringActorConstruction = "true"))
static ENGINE_API class APlayerController* GetPlayerController(const UObject * WorldContextObject, int32 PlayerIndex);
UFUNCTION(BlueprintPure, Category = "Game", meta = (WorldContext = "WorldContextObject", UnsafeDuringActorConstruction = "true"))
static ENGINE_API class APawn* GetPlayerPawn(const UObject * WorldContextObject, int32 PlayerIndex);
UFUNCTION(BlueprintPure, Category = "Game", meta = (WorldContext = "WorldContextObject", UnsafeDuringActorConstruction = "true"))
static ENGINE_API class ACharacter* GetPlayerCharacter(const UObject * WorldContextObject, int32 PlayerIndex);
UFUNCTION(BlueprintPure, Category = "Game", meta = (WorldContext = "WorldContextObject", UnsafeDuringActorConstruction = "true"))
static ENGINE_API class APlayerCameraManager* GetPlayerCameraManager(const UObject * WorldContextObject, int32 PlayerIndex);
UFUNCTION(BlueprintCallable, Category = "Game", meta = (DisplayName = "Create Local Player", WorldContext = "WorldContextObject", AdvancedDisplay = "2", UnsafeDuringActorConstruction = "true"))
static ENGINE_API class APlayerController* CreatePlayer(const UObject * WorldContextObject, int32 ControllerId = -1, bool bSpawnPlayerController = true);
UFUNCTION(BlueprintCallable, Category = "Game", meta = (DisplayName = "Remove Local Player", UnsafeDuringActorConstruction = "true"))
static ENGINE_API void RemovePlayer(APlayerController * Player, bool bDestroyPawn);
// --- Level Streaming functions ------------------------
UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", Latent = "", LatentInfo = "LatentInfo", DisplayName = "Load Stream Level (by Name)"), Category = "Game")
static ENGINE_API void LoadStreamLevel(const UObject * WorldContextObject, FName LevelName, bool bMakeVisibleAfterLoad, bool bShouldBlockOnLoad, FLatentActionInfo LatentInfo);
UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", Latent = "", LatentInfo = "LatentInfo", DisplayName = "Load Stream Level (by Object Reference)"), Category = "Game")
static ENGINE_API void LoadStreamLevelBySoftObjectPtr(const UObject * WorldContextObject, const TSoftObjectPtr<UWorld> Level, bool bMakeVisibleAfterLoad, bool bShouldBlockOnLoad, FLatentActionInfo LatentInfo);
UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", Latent = "", LatentInfo = "LatentInfo", DisplayName = "Unload Stream Level (by Name)"), Category = "Game")
static ENGINE_API void UnloadStreamLevel(const UObject * WorldContextObject, FName LevelName, FLatentActionInfo LatentInfo, bool bShouldBlockOnUnload);
UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", Latent = "", LatentInfo = "LatentInfo", DisplayName = "Unload Stream Level (by Object Reference)"), Category = "Game")
static ENGINE_API void UnloadStreamLevelBySoftObjectPtr(const UObject * WorldContextObject, const TSoftObjectPtr<UWorld> Level, FLatentActionInfo LatentInfo, bool bShouldBlockOnUnload);
UFUNCTION(BlueprintPure, meta = (WorldContext = "WorldContextObject"), Category = "Game")
static ENGINE_API class ULevelStreaming* GetStreamingLevel(const UObject * WorldContextObject, FName PackageName);
UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject"), Category = "Game")
static ENGINE_API void FlushLevelStreaming(const UObject * WorldContextObject);
UFUNCTION(BlueprintCallable, Category = "Game")
static ENGINE_API void CancelAsyncLoading();
UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", AdvancedDisplay = "2", DisplayName = "Open Level (by Name)"), Category = "Game")
static ENGINE_API void OpenLevel(const UObject * WorldContextObject, FName LevelName, bool bAbsolute = true, FString Options = FString(TEXT("")));
UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", AdvancedDisplay = "2", DisplayName = "Open Level (by Object Reference)"), Category = "Game")
static ENGINE_API void OpenLevelBySoftObjectPtr(const UObject * WorldContextObject, const TSoftObjectPtr<UWorld> Level, bool bAbsolute = true, FString Options = FString(TEXT("")));
UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", AdvancedDisplay = "1"), Category = "Game")
static ENGINE_API FString GetCurrentLevelName(const UObject * WorldContextObject, bool bRemovePrefixString = true);
// --- Global functions ------------------------------
UFUNCTION(BlueprintPure, Category = "Game", meta = (WorldContext = "WorldContextObject"))
static ENGINE_API class AGameModeBase* GetGameMode(const UObject * WorldContextObject);
UFUNCTION(BlueprintPure, Category = "Game", meta = (WorldContext = "WorldContextObject"))
static ENGINE_API class AGameStateBase* GetGameState(const UObject * WorldContextObject);
UFUNCTION(BlueprintPure, meta = (DisplayName = "Get Class", DeterminesOutputType = "Object"), Category = "Utilities")
static ENGINE_API class UClass* GetObjectClass(const UObject * Object);
UFUNCTION(BlueprintPure, meta = (DisplayName = "IsA"), Category = "Utilities")
static ENGINE_API bool ObjectIsA(const UObject * Object, TSubclassOf<UObject> ObjectClass);
UFUNCTION(BlueprintPure, Category = "Utilities|Time", meta = (WorldContext = "WorldContextObject"))
static ENGINE_API float GetGlobalTimeDilation(const UObject * WorldContextObject);
UFUNCTION(BlueprintCallable, Category = "Utilities|Time", meta = (WorldContext = "WorldContextObject"))
static ENGINE_API void SetGlobalTimeDilation(const UObject * WorldContextObject, float TimeDilation);
UFUNCTION(BlueprintCallable, Category = "Game", meta = (WorldContext = "WorldContextObject"))
static ENGINE_API bool SetGamePaused(const UObject * WorldContextObject, bool bPaused);
UFUNCTION(BlueprintPure, Category = "Game", meta = (WorldContext = "WorldContextObject"))
static ENGINE_API bool IsGamePaused(const UObject * WorldContextObject);
UFUNCTION(BlueprintCallable, Category = "Viewport", meta = (WorldContext = "WorldContextObject"))
static ENGINE_API void SetForceDisableSplitscreen(const UObject * WorldContextObject, bool bDisable);
UFUNCTION(BlueprintPure, Category = "Viewport", meta = (WorldContext = "WorldContextObject"))
static ENGINE_API bool IsSplitscreenForceDisabled(const UObject * WorldContextObject);
UFUNCTION(BlueprintCallable, Category = "Rendering", meta = (WorldContext = "WorldContextObject"))
static ENGINE_API void SetEnableWorldRendering(const UObject * WorldContextObject, bool bEnable);
UFUNCTION(BlueprintCallable, Category = "Rendering", meta = (WorldContext = "WorldContextObject"))
static ENGINE_API bool GetEnableWorldRendering(const UObject * WorldContextObject);
UFUNCTION(BlueprintPure, Category = "Viewport", meta = (WorldContext = "WorldContextObject"))
static ENGINE_API EMouseCaptureMode GetViewportMouseCaptureMode(const UObject * WorldContextObject);
UFUNCTION(BlueprintCallable, Category = "Viewport", meta = (WorldContext = "WorldContextObject"))
static ENGINE_API void SetViewportMouseCaptureMode(const UObject * WorldContextObject, const EMouseCaptureMode MouseCaptureMode);
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "Game|Damage", meta = (WorldContext = "WorldContextObject", AutoCreateRefTerm = "IgnoreActors"))
static ENGINE_API bool ApplyRadialDamage(const UObject * WorldContextObject, float BaseDamage, const FVector & Origin, float DamageRadius, TSubclassOf<class UDamageType> DamageTypeClass, const TArray<AActor*>&IgnoreActors, AActor * DamageCauser = NULL, AController * InstigatedByController = NULL, bool bDoFullDamage = false, ECollisionChannel DamagePreventionChannel = ECC_Visibility);
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "Game|Damage", meta = (WorldContext = "WorldContextObject", AutoCreateRefTerm = "IgnoreActors"))
static ENGINE_API bool ApplyRadialDamageWithFalloff(const UObject * WorldContextObject, float BaseDamage, float MinimumDamage, const FVector & Origin, float DamageInnerRadius, float DamageOuterRadius, float DamageFalloff, TSubclassOf<class UDamageType> DamageTypeClass, const TArray<AActor*>&IgnoreActors, AActor * DamageCauser = NULL, AController * InstigatedByController = NULL, ECollisionChannel DamagePreventionChannel = ECC_Visibility);
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "Game|Damage")
static ENGINE_API float ApplyPointDamage(AActor * DamagedActor, float BaseDamage, const FVector & HitFromDirection, const FHitResult & HitInfo, AController * EventInstigator, AActor * DamageCauser, TSubclassOf<class UDamageType> DamageTypeClass);
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "Game|Damage")
static ENGINE_API float ApplyDamage(AActor * DamagedActor, float BaseDamage, AController * EventInstigator, AActor * DamageCauser, TSubclassOf<class UDamageType> DamageTypeClass);
// --- Camera functions ------------------------------
UFUNCTION(BlueprintCallable, Category = "Camera", meta = (WorldContext = "WorldContextObject", UnsafeDuringActorConstruction = "true"))
static ENGINE_API void PlayWorldCameraShake(const UObject * WorldContextObject, TSubclassOf<class UCameraShakeBase> Shake, FVector Epicenter, float InnerRadius, float OuterRadius, float Falloff = 1.f, bool bOrientShakeTowardsEpicenter = false);
// --- Particle functions ------------------------------
UFUNCTION(BlueprintCallable, Category = "Effects", meta = (Keywords = "particle system", WorldContext = "WorldContextObject", UnsafeDuringActorConstruction = "true"))
static ENGINE_API UParticleSystemComponent* SpawnEmitterAtLocation(const UObject * WorldContextObject, UParticleSystem * EmitterTemplate, FVector Location, FRotator Rotation = FRotator::ZeroRotator, FVector Scale = FVector(1.f), bool bAutoDestroy = true, EPSCPoolMethod PoolingMethod = EPSCPoolMethod::None, bool bAutoActivateSystem = true);
static ENGINE_API UParticleSystemComponent* SpawnEmitterAtLocation(const UObject * WorldContextObject, UParticleSystem * EmitterTemplate, FVector Location, FRotator Rotation, bool bAutoDestroy, EPSCPoolMethod PoolingMethod = EPSCPoolMethod::None, bool bAutoActivateSystem = true);
static ENGINE_API UParticleSystemComponent* SpawnEmitterAtLocation(UWorld * World, UParticleSystem * EmitterTemplate, const FTransform & SpawnTransform, bool bAutoDestroy = true, EPSCPoolMethod PoolingMethod = EPSCPoolMethod::None, bool bAutoActivate = true);
}
UCLASS(meta=(BlueprintThreadSafe, ScriptName="StringLibrary"), MinimalAPI)
class UKismetStringLibrary : public UBlueprintFunctionLibrary
{
GENERATED_UCLASS_BODY()
UFUNCTION(BlueprintPure, Category="Utilities|String", meta=(Keywords = "empty"))
static ENGINE_API bool IsEmpty(const FString& InString);
UFUNCTION(BlueprintPure, Category = "Utilities|String")
static ENGINE_API bool IsNumeric(const FString& SourceString);
UFUNCTION(BlueprintPure, Category="Utilities|String", meta=(CompactNodeTitle = "LEN", Keywords = "length"))
static ENGINE_API int32 Len(const FString& S);
UFUNCTION(BlueprintPure, Category = "Utilities|String")
static ENGINE_API bool Contains(const FString& SearchIn, const FString& Substring, bool bUseCase = false, bool bSearchFromEnd = false);
UFUNCTION(BlueprintPure, Category="Utilities|String")
static ENGINE_API FString GetSubstring(const FString& SourceString, int32 StartIndex = 0, int32 Length = 1);
UFUNCTION(BlueprintPure, Category = "Utilities|String")
static ENGINE_API int32 FindSubstring(const FString& SearchIn, const FString& Substring, bool bUseCase = false, bool bSearchFromEnd = false, int32 StartPosition = -1);
UFUNCTION(BlueprintPure, Category="Utilities|String")
static ENGINE_API int32 GetCharacterAsNumber(const FString& SourceString, int32 Index = 0);
UFUNCTION(BlueprintPure, Category = "Utilities|String")
static ENGINE_API TArray<FString> GetCharacterArrayFromString(const FString& SourceString);
UFUNCTION(BlueprintPure, Category="Utilities|String")
static ENGINE_API FString ToUpper(const FString& SourceString);
UFUNCTION(BlueprintPure, Category = "Utilities|String")
static ENGINE_API FString ToLower(const FString& SourceString);
UFUNCTION(BlueprintPure, Category = "Utilities|String")
static ENGINE_API FString LeftPad(const FString& SourceString, int32 ChCount);
UFUNCTION(BlueprintPure, Category = "Utilities|String")
static ENGINE_API FString RightPad(const FString& SourceString, int32 ChCount);
UFUNCTION(BlueprintPure, Category = "Utilities|String")
static ENGINE_API bool StartsWith(const FString& SourceString, const FString& InPrefix, ESearchCase::Type SearchCase = ESearchCase::IgnoreCase);
UFUNCTION(BlueprintPure, Category = "Utilities|String")
static ENGINE_API bool EndsWith(const FString& SourceString, const FString& InSuffix, ESearchCase::Type SearchCase = ESearchCase::IgnoreCase);
UFUNCTION(BlueprintPure, Category = "Utilities|String")
static ENGINE_API FString Replace(const FString& SourceString, const FString& From, const FString& To, ESearchCase::Type SearchCase = ESearchCase::IgnoreCase);
UFUNCTION(BlueprintPure, Category = "Utilities|String")
static ENGINE_API FString Left(const FString& SourceString, int32 Count);
UFUNCTION(BlueprintPure, Category = "Utilities|String")
static ENGINE_API FString Right(const FString& SourceString, int32 Count);
UFUNCTION(BlueprintPure, Category = "Utilities|String")
static ENGINE_API FString LeftChop(const FString& SourceString, int32 Count);
UFUNCTION(BlueprintPure, Category = "Utilities|String")
static ENGINE_API FString RightChop(const FString& SourceString, int32 Count);
UFUNCTION(BlueprintPure, Category = "Utilities|String")
static ENGINE_API FString Mid(const FString& SourceString, int32 Start, int32 Count);
}
UCLASS(meta=(ScriptName="SystemLibrary"), MinimalAPI)
class UKismetSystemLibrary : public UBlueprintFunctionLibrary
{
GENERATED_UCLASS_BODY()
...
UFUNCTION(BlueprintCallable, Category="Utilities|FlowControl", meta=(Latent, WorldContext="WorldContextObject", LatentInfo="LatentInfo", Duration="0.2", Keywords="sleep"))
static ENGINE_API void Delay(const UObject* WorldContextObject, float Duration, struct FLatentActionInfo LatentInfo );
UFUNCTION(BlueprintCallable, meta=(Latent, LatentInfo="LatentInfo", WorldContext="WorldContextObject", Duration="0.2", Keywords="sleep"), Category="Utilities|FlowControl")
static ENGINE_API void RetriggerableDelay(const UObject* WorldContextObject, float Duration, FLatentActionInfo LatentInfo);
UFUNCTION(BlueprintCallable, meta=(Latent, LatentInfo="LatentInfo", WorldContext="WorldContextObject", ExpandEnumAsExecs="MoveAction", OverTime="0.2"), Category="Components")
static ENGINE_API void MoveComponentTo(USceneComponent* Component, FVector TargetRelativeLocation, FRotator TargetRelativeRotation, bool bEaseOut, bool bEaseIn, float OverTime, bool bForceShortestRotationPath, TEnumAsByte<EMoveComponentAction::Type> MoveAction, FLatentActionInfo LatentInfo);
...
}
十一,文件
文件路径操作
// BlueprintPathsLibrary.h 内有内置的关于path的蓝图库函数,其调用的就是FPaths内的函数
class UBlueprintPathsLibrary : public UBlueprintFunctionLibrary
// 头文件为 #include "Misc/Paths.h",一般默认该头文件可不包括
// 用于跨平台地处理文件和目录路径,避免手动拼接字符串时出现的平台差异问题
class FPaths {
public:
static CORE_API bool CanGetProjectDir();
static CORE_API bool IsStaged();
static CORE_API bool ShouldSaveToUserDir();
static CORE_API bool IsRestrictedPath(const FString& InPath);
static CORE_API bool IsProjectFilePathSet();
static CORE_API bool FileExists(const FString& InPath);
static CORE_API bool DirectoryExists(const FString& InPath);
static CORE_API bool IsDrive(const FString& InPath);
static CORE_API bool IsRelative(const FString& InPath);
static CORE_API bool IsSamePath(const FString& PathA, const FString& PathB);
static CORE_API bool IsUnderDirectory(const FString& InPath, const FString& InDirectory);
static CORE_API bool HasProjectPersistentDownloadDir();
static CORE_API bool MakePathRelativeTo( FString& InPath, const TCHAR* InRelativeTo );
static CORE_API bool ValidatePath( const FString& InPath, FText* OutReason = nullptr );
static CORE_API bool CollapseRelativeDirectories(FString& InPath, bool bCollapseAllPossible = false);
static CORE_API void Split( const FString& InPath, FString& PathPart, FString& FilenamePart, FString& ExtensionPart );
static CORE_API FString ConvertRelativePathToFull(const FString& InPath);
static CORE_API FString ConvertRelativePathToFull(FString&& InPath);
static CORE_API FString ConvertRelativePathToFull(const FString& BasePath, const FString& InPath);
static CORE_API FString ConvertRelativePathToFull(const FString& BasePath, FString&& InPath);
static CORE_API FString ConvertRelativePathToFull(FString&& BasePath, const FString& InPath);
static CORE_API FString ConvertRelativePathToFull(FString&& BasePath, FString&& InPath);
static CORE_API FString ConvertToSandboxPath( const FString& InPath, const TCHAR* InSandboxName );
static CORE_API FString ConvertFromSandboxPath( const FString& InPath, const TCHAR* InSandboxName );
static CORE_API FString FindCorrectCase(const FString& Path);
static CORE_API const FString& GetRelativePathToRoot();
static CORE_API FString GetProjectFilePath();
static CORE_API void SetProjectFilePath( const FString& NewGameProjectFilePath );
static CORE_API FString GetPath(FString&& InPath);
static CORE_API FString GetPathLeaf(const FString& InPath);
static CORE_API FString ConvertPath(const FString& Path, EPathConversion Method, const TCHAR* ExtraData=nullptr, const TCHAR* OverrideProjectDir=nullptr);
static CORE_API const TArray<FString>& GetEngineLocalizationPaths();
static CORE_API const TArray<FString>& GetEditorLocalizationPaths();
static CORE_API const TArray<FString>& GetPropertyNameLocalizationPaths();
static CORE_API const TArray<FString>& GetToolTipLocalizationPaths();
static CORE_API const TArray<FString>& GetGameLocalizationPaths();
static CORE_API void NormalizeFilename(FString& InPath);
static CORE_API void NormalizeDirectoryName(FString& InPath);
static CORE_API FString GetCleanFilename(const FString& InPath);
static CORE_API FString GetBaseFilename(const FString& InPath, bool bRemovePath=true );
static CORE_API FString GetPlatformLocalizationFolderName();
static CORE_API const TArray<FString>& GetRestrictedFolderNames();
static CORE_API FString CreateStandardFilename(const FString& InPath);
static CORE_API void MakeStandardFilename(FString& InPath);
static CORE_API void MakePlatformFilename(FString& InPath);
static CORE_API FString MakeValidFileName(const FString& InString, const TCHAR InReplacementChar = TEXT('\0'));
static CORE_API FString CreateTempFilename( const TCHAR* Path, const TCHAR* Prefix = TEXT(""), const TCHAR* Extension = TEXT(".tmp") );
static CORE_API FString GetExtension( const FString& InPath, bool bIncludeDot=false );
static CORE_API FString SetExtension(const FString& InPath, const FString& InNewExtension);
static CORE_API FString RootDir();
static CORE_API FString LaunchDir();
static CORE_API FString EngineDir();
static CORE_API FString EngineUserDir();
static CORE_API FString EngineContentDir();
static CORE_API FString EngineConfigDir();
static CORE_API FString EngineEditorSettingsDir();
static CORE_API FString EngineIntermediateDir();
static CORE_API FString EngineSavedDir();
static CORE_API FString EnginePluginsDir();
static CORE_API FString EngineDefaultLayoutDir();
static CORE_API FString EngineProjectLayoutDir();
static CORE_API FString EngineUserLayoutDir();
static CORE_API FString EnterpriseDir();
static CORE_API FString EnterprisePluginsDir();
static CORE_API FString EnterpriseFeaturePackDir();
static CORE_API TArray<FString> GetExtensionDirs(const FString& BaseDir, const FString& SubDir, bool bCheckValid);
static CORE_API FString EngineVersionAgnosticUserDir();
static FString EnginePlatformExtensionDir(const TCHAR* Platform);
static FString ProjectPlatformExtensionDir(const TCHAR* Platform);
static CORE_API FString ProjectDir();
static CORE_API FString ProjectContentDir();
static CORE_API FString ProjectUserDir();
static CORE_API FString ProjectConfigDir();
static CORE_API const FString& ProjectSavedDir();
static CORE_API FString ProjectIntermediateDir();
static CORE_API FString ProjectPluginsDir();
static CORE_API FString ProjectModsDir();
static CORE_API FString ProjectPersistentDownloadDir();
static CORE_API FString ProjectLogDir();
static CORE_API FString ShaderWorkingDir();
static CORE_API FString SourceConfigDir();
static CORE_API FString GeneratedConfigDir();
static CORE_API FString SandboxesDir();
static CORE_API FString ProfilingDir();
static CORE_API FString ScreenShotDir();
static CORE_API FString BugItDir();
static CORE_API FString VideoCaptureDir();
static CORE_API FString AudioCaptureDir();
static CORE_API FString AutomationDir();
static CORE_API FString AutomationTransientDir();
static CORE_API FString AutomationReportsDir();
static CORE_API FString AutomationLogDir();
static CORE_API FString CloudDir();
static CORE_API FString GameDevelopersDir();
static CORE_API FStringView DevelopersFolderName();
static CORE_API FString GameUserDeveloperFolderName();
static CORE_API FString GameUserDeveloperDir();
static CORE_API FString DiffDir();
static CORE_API FString GameAgnosticSavedDir();
static CORE_API FString EngineSourceDir();
static CORE_API FString GameSourceDir();
static CORE_API FString FeaturePackDir();
static CORE_API void RemoveDuplicateSlashes(FString& InPath);
static CORE_API FString GetInvalidFileSystemChars();
static CORE_API void TearDown();
}
文件I/O操作
// 路径字符串层
FPaths
├── Combine / Normalize / ConvertRelativePathToFull
├── ProjectDir / EngineDir / LaunchDir
└── FileExists() // 委托 IFileManager::Get()
// 内容读写便利层(内部调用 IFileManager::Get())
FFileHelper
├── LoadFileToString / SaveStringToFile
└── LoadFileToArray / SaveArrayToFile
// 上层文件管理工具(文件管理抽象层,持有 IPlatformFile* 委托底层操作)
IFileManager
└── FFileManagerGeneric // 通用实现,持有并委托 IPlatformFile*
├── FFileManagerGeneric::Get() 获取对应单例
├── FileExists / Delete / Move / Copy
├── FindFiles / IterateDirectory
└── CreateFileReader / CreateFileWriter
// 底层平台文件管理器(负责管理 IPlatformFile 链)
FPlatformFileManager
├── FPlatformFileManager::Get() 获取对应单例
└── GetPlatformFile() // 返回低层 IPlatformFile
// 平台文件抽象层
IPlatformFile
├── FileExists / FileSize / DeleteFile
├── OpenRead / OpenWrite
├── IterateDirectory / FindFiles
└── 派生实现
├── 平台具体实现
│ ├── FWindowsPlatformFile
│ └── FLinuxPlatformFile
└── 包装/装饰层
├── FPakPlatformFile
└── FLoggedPlatformFile
// 头文件为 #include "Misc/FileHelper.h",一般默认该头文件可不包括 // FFileHelper 是提供静态文件读写功能的工具结构体,非常适合用于处理文本、二进制文件以及序列化数据(如 JSON); struct FFileHelper { ... // 底层为 IFileManager::Get().CreateFileReader() static CORE_API bool LoadFileToString(FString& Result, const TCHAR* Filename, EHashOptions VerifyFlags = EHashOptions::None, uint32 ReadFlags = 0 ); static CORE_API bool LoadFileToStringArray( TArray<FString>& Result, const TCHAR* Filename ); static CORE_API bool LoadFileToArray( TArray<uint8>& Result, const TCHAR* Filename, uint32 Flags = 0 ); // 底层为 FileManager->CreateFileWriter(Filename, WriteFlags) static CORE_API bool SaveStringToFile( FStringView String, const TCHAR* Filename, EEncodingOptions EncodingOptions = EEncodingOptions::AutoDetect, IFileManager* FileManager = &IFileManager::Get(), uint32 WriteFlags = 0 ); static CORE_API bool SaveStringArrayToFile( const TArray<FString>& Lines, const TCHAR* Filename, EEncodingOptions EncodingOptions = EEncodingOptions::AutoDetect, IFileManager* FileManager = &IFileManager::Get(), uint32 WriteFlags = 0 ); static CORE_API bool SaveArrayToFile(TArrayView64<const uint8> Array, const TCHAR* Filename, IFileManager* FileManager = &IFileManager::Get(), uint32 WriteFlags = 0); ... }#include "CoreMinimal.h" #include "Kismet/BlueprintFunctionLibrary.h" #include "MyBlueprintFunctionLibrary.generated.h" UCLASS() class MYCPP_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary { GENERATED_BODY() public: // 可在蓝图中调用这些函数,Filename为带路径的完整名字(可使用ProjectContentDir获取内容文件夹路径) UFUNCTION(BlueprintCallable, Category = "File") static bool LoadFileToString(FString& Ret, FString Filename); UFUNCTION(BlueprintCallable, Category = "File") static bool LoadFileToStringArray(TArray<FString>& Ret, FString Filename); UFUNCTION(BlueprintCallable, Category = "File") static bool SaveStringToFile(FString String, FString Filename); UFUNCTION(BlueprintCallable, Category = "File") static bool SaveStringArrayToFile(TArray<FString> Strings, FString Filename); };#include "MyBlueprintFunctionLibrary.h" bool UMyBlueprintFunctionLibrary::LoadFileToString(FString& Ret, FString Filename) { return FFileHelper::LoadFileToString(Ret, *Filename); } bool UMyBlueprintFunctionLibrary::LoadFileToStringArray(TArray<FString>& Ret, FString Filename) { return FFileHelper::LoadFileToStringArray(Ret, *Filename); } bool UMyBlueprintFunctionLibrary::SaveStringToFile(FString String, FString Filename) { return FFileHelper::SaveStringToFile(String, *Filename); } bool UMyBlueprintFunctionLibrary::SaveStringArrayToFile(TArray<FString> Strings, FString Filename) { return FFileHelper::SaveStringArrayToFile(Strings, *Filename); }
// #include "GenericPlatform/GenericPlatformFile.h" // UE文件I/O体系的底层抽象接口,定义引擎与操作系统文件系统交互的标准协议,主要定义了核心接口类:IFileHandle/IPlatformFile // 用于实现平台文件系统、Pak包、缓存、日志等底层功能,需要直接控制文件句柄时使用; class IPlatformFile // 提供对文件和目录的整体操作 { ... // 纯虚函数会在具体派生平台实现 virtual const TCHAR* GetName() const = 0; virtual bool FileExists(const TCHAR* Filename) = 0; virtual int64 FileSize(const TCHAR* Filename) = 0; virtual bool DeleteFile(const TCHAR* Filename) = 0; virtual bool DeleteFiles(const TArrayView<const TCHAR*>& Filenames) virtual IFileHandle* OpenRead(const TCHAR* Filename, bool bAllowWrite = false) = 0; virtual IFileHandle* OpenWrite(const TCHAR* Filename, bool bAppend = false, bool bAllowRead = false) = 0; virtual bool DirectoryExists(const TCHAR* Directory) = 0; virtual bool CreateDirectory(const TCHAR* Directory) = 0; virtual bool DeleteDirectory(const TCHAR* Directory) = 0; CORE_API virtual bool CreateDirectoryTree(const TCHAR* Directory); CORE_API virtual bool CopyDirectoryTree(const TCHAR* DestinationDirectory, const TCHAR* Source, bool bOverwriteAllExisting); CORE_API virtual bool CopyFile(const TCHAR* To, const TCHAR* From, EPlatformFileRead ReadFlags = EPlatformFileRead::None, EPlatformFileWrite WriteFlags = EPlatformFileWrite::None); CORE_API virtual bool DeleteDirectoryRecursively(const TCHAR* Directory); CORE_API virtual void FindFiles(TArray<FString>& FoundFiles, const TCHAR* Directory, const TCHAR* FileExtension); CORE_API virtual void FindFilesRecursively(TArray<FString>& FoundFiles, const TCHAR* Directory, const TCHAR* FileExtension); ... } class IFileHandle // 单个文件的具体读写操作 { public: virtual int64 Tell() = 0; virtual bool Seek(int64 NewPosition) = 0; virtual bool SeekFromEnd(int64 NewPositionRelativeToEnd = 0) = 0; virtual bool Read(uint8* Destination, int64 BytesToRead) = 0; virtual bool ReadAt(uint8* Destination, int64 BytesToRead, int64 Offset) = 0; virtual bool Write(const uint8* Source, int64 BytesToWrite) = 0; virtual bool Flush(const bool bFullFlush = false) = 0; virtual bool Truncate(int64 NewSize) = 0; ... }// IPlatformFile 应用 IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile(); // 获取平台文件系统实例(获取具体派生类的实例) PlatformFile.FileExists(*FilePath); // 判断文件是否存在 PlatformFile.DeleteFile(*FilePath); // 删除文件 // 打开文件进行读取 FString FilePath = TEXT("D:/MyProject/Data.bin"); TUniquePtr<IFileHandle> FileHandle(PlatformFile.OpenRead(*FilePath)); if (FileHandle) { int64 FileSize = FileHandle->Size(); uint8* Buffer = new uint8[FileSize]; if (FileHandle->Read(Buffer, FileSize)) { // 处理读取的数据 } delete[] Buffer; // FileHandle 析构时自动关闭文件 }
// #include "HAL/FileManagerGeneric.h" 是IPlatformFile上层封装 // 实现了 IFileManager 接口,提供了跨平台的文件读写、目录操作等底层功能; // 用于游戏逻辑中常见的文件读写、查询、目录管理等,API更友好; class FFileManagerGeneric : public IFileManager { UE_FORCEINLINE_HINT IPlatformFile& GetLowLevel() const { return FPlatformFileManager::Get().GetPlatformFile(); } public: FArchive* CreateFileReader( const TCHAR* Filename, uint32 ReadFlags=0 ) override; FArchive* CreateFileWriter( const TCHAR* Filename, uint32 WriteFlags=0 ) override; CORE_API bool Delete( const TCHAR* Filename, bool RequireExists=0, bool EvenReadOnly=0, bool Quiet=0 ) override; CORE_API bool IsReadOnly( const TCHAR* Filename ) override; CORE_API bool Move( const TCHAR* Dest, const TCHAR* Src, bool Replace=1, bool EvenIfReadOnly=0, bool Attributes=0, bool bDoNotRetryOrError=0 ) override; CORE_API bool FileExists( const TCHAR* Filename ) override; CORE_API bool DirectoryExists(const TCHAR* InDirectory) override; CORE_API void FindFiles( TArray<FString>& Result, const TCHAR* Filename, bool Files, bool Directories ) override; CORE_API void FindFilesRecursive( TArray<FString>& FileNames, const TCHAR* StartDirectory, const TCHAR* Filename, bool Files, bool Directories, bool bClearFileNames=true) override; CORE_API virtual uint32 Copy( const TCHAR* Dest, const TCHAR* Src, bool Replace = 1, bool EvenIfReadOnly = 0, bool Attributes = 0, FCopyProgress* Progress = nullptr, EFileRead ReadFlags = FILEREAD_None, EFileWrite WriteFlags = FILEWRITE_None ) override; CORE_API virtual bool MakeDirectory( const TCHAR* Path, bool Tree=0 ) override; CORE_API virtual bool DeleteDirectory( const TCHAR* Path, bool RequireExists=0, bool Tree=0 ) override; ... }// FFileManagerGeneric 应用 FFileManagerGeneric::Get().FileExists(*FilePath) // 判断文件是否存在 FFileManagerGeneric::Get().FindFiles(FoundFiles, *Directory, TEXT(".txt")); // 查找目录下的所有 .txt 文件 FFileManagerGeneric::Get().DeleteDirectory(*FolderToDelete, true, true); // 删除一个目录及其所有内容 FString FileName = TEXT("D:/MyProject/Output.txt"); TUniquePtr<FArchive> Ar(FFileManagerGeneric::Get().CreateFileWriter(*FileName)); if (Ar) { FString Data = TEXT("Hello, Unreal!"); *Ar << Data; // FArchive 析构时会自动关闭文件 }
十二,Delay节点的C++实现
// LatentActionManager.h // 蓝图里的 Delay、Retriggerable Delay、Move Component To 等节点底层依赖它实现; USTRUCT(BlueprintInternalUseOnly) struct FLatentActionInfo { GENERATED_USTRUCT_BODY() UPROPERTY(meta=(NeedsLatentFixup = true)) int32 Linkage; UPROPERTY() int32 UUID; UPROPERTY() FName ExecutionFunction; UPROPERTY(meta=(LatentCallbackTarget = true)) TObjectPtr<UObject> CallbackTarget; FLatentActionInfo() : Linkage(INDEX_NONE) , UUID(INDEX_NONE) , ExecutionFunction(NAME_None) , CallbackTarget(NULL) {} FORCENOINLINE FLatentActionInfo(int32 InLinkage, int32 InUUID, const TCHAR* InFunctionName, UObject* InCallbackTarget) : Linkage(InLinkage) , UUID(InUUID) , ExecutionFunction(InFunctionName) , CallbackTarget(InCallbackTarget) {} };void UKismetSystemLibrary::Delay(const UObject* WorldContextObject, float Duration, FLatentActionInfo LatentInfo ) { if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull)) { FLatentActionManager& LatentActionManager = World->GetLatentActionManager(); if (LatentActionManager.FindExistingAction<FDelayAction>(LatentInfo.CallbackTarget, LatentInfo.UUID) == NULL) { LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, new FDelayAction(Duration, LatentInfo)); } } }
十三,JSON
// 注意添加依赖的模块
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "Json", "JsonUtilities" });
// Json文件,注意为英文标点符号
{
"Name": "Tom",
"Age": 25,
"IsReady": true,
"Data":
{
"UserName": "ABC",
"UserID": 123
}
}
void AMyJSONActor::JsonRead(FString JsonString)
{
TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(JsonString);
TSharedPtr<FJsonObject> JsonObject;
if (FJsonSerializer::Deserialize(JsonReader, JsonObject) && JsonObject.IsValid())
{
FString Name;
if (JsonObject->TryGetStringField(TEXT("Name"), Name))
UE_LOG(LogTemp, Warning, TEXT("Name: %s"), *Name);
int32 Age;
if (JsonObject->TryGetNumberField(TEXT("Age"), Age))
UE_LOG(LogTemp, Warning, TEXT("Age: %d"), Age);
double Score;
if (JsonObject->TryGetNumberField(TEXT("Score"), Score))
UE_LOG(LogTemp, Warning, TEXT("Score: %f"), Score);
bool bIsReady = false;
if (JsonObject->TryGetBoolField(TEXT("IsReady"), bIsReady))
UE_LOG(LogTemp, Warning, TEXT("IsReady: %s"), bIsReady ? TEXT("true") : TEXT("false"));
const TSharedPtr<FJsonObject>* OutObject = nullptr;
if (JsonObject->TryGetObjectField(TEXT("Data"), OutObject) && OutObject && (*OutObject).IsValid())
{
FString UserName;
if ((*OutObject)->TryGetStringField(TEXT("UserName"), UserName))
UE_LOG(LogTemp, Warning, TEXT("UserName: %s"), *UserName);
int32 UserID;
if ((*OutObject)->TryGetNumberField(TEXT("UserID"), UserID))
UE_LOG(LogTemp, Warning, TEXT("UserID: %d"), UserID);
}
}
else
{
UE_LOG(LogTemp, Error, TEXT("Failed to parse JSON: %s"), *JsonString);
}
}
FString AMyJSONActor::JsonRead(FString InJsonString)
{
TSharedRef<TJsonReader<>> JsonReader = TJsonReaderFactory<>::Create(InJsonString);
TSharedPtr<FJsonObject> JsonObject;
FString OutString;
if (FJsonSerializer::Deserialize(JsonReader, JsonObject) && JsonObject.IsValid())
{
TSharedRef<TJsonWriter<>> JsonWriter = TJsonWriterFactory<>::Create(&OutString);
FJsonSerializer::Serialize(JsonObject, JsonWriter);
}
return OutString;
}
FString AMyJSONActor::JsonWrite(const TMap<FString, FString>& InMap)
{
FString JsonString;
TSharedRef<TJsonWriter<>> JsonWriter = TJsonWriterFactory<>::Create(&JsonString);
JsonWriter->WriteObjectStart();
for (const TPair<FString, FString>& Pair : InMap)
{
JsonWriter->WriteValue(Pair.Key, Pair.Value);
}
JsonWriter->WriteObjectEnd();
JsonWriter->Close();
return JsonString;
}
十四,Runnable
// MyRunnable.h
#include "CoreMinimal.h"
class MYCPP_API FMyRunnable : public FRunnable
{
public:
FMyRunnable();
~FMyRunnable();
virtual bool Init() override;
virtual uint32 Run() override;
virtual void Stop() override;
virtual void Exit() override;
private:
FThreadSafeBool bStopRequested;
};
// MyRunnable.CPP
#include "MyRunnable.h"
FMyRunnable::FMyRunnable()
{
UE_LOG(LogTemp, Warning, TEXT("MyRunnable FMyRunnable()!"));
}
FMyRunnable::~FMyRunnable()
{
UE_LOG(LogTemp, Warning, TEXT("MyRunnable ~FMyRunnable()!"));
}
bool FMyRunnable::Init()
{
UE_LOG(LogTemp, Warning, TEXT("MyRunnable Init()!"));
return true;
}
uint32 FMyRunnable::Run()
{
while (!bStopRequested)
{
FPlatformProcess::Sleep(0.1f);
UE_LOG(LogTemp, Warning, TEXT("MyRunnable Run() ... !"));
}
return uint32();
}
void FMyRunnable::Stop()
{
bStopRequested = true;
UE_LOG(LogTemp, Warning, TEXT("MyRunnable Stop()!"));
}
void FMyRunnable::Exit()
{
UE_LOG(LogTemp, Warning, TEXT("MyRunnable Exit()!"));
}
// MyActor.h
UCLASS()
class MYCPP_API AMyActor : public AActor
{
GENERATED_BODY()
...
public:
UFUNCTION(BlueprintCallable)
void StartThread();
UFUNCTION(BlueprintCallable)
void StopThread();
FMyRunnable* MyRunnable = nullptr;
FRunnableThread* MyRunnableThread = nullptr;
};
// MyActor.cpp
void AMyGameplayStaticsActor::StartThread()
{
if(!MyRunnableThread)
{
MyRunnable = new FMyRunnable();
MyRunnableThread = FRunnableThread::Create(MyRunnable, TEXT("MyRunnable"));
if (!MyRunnableThread)
{
UE_LOG(LogTemp, Error, TEXT("Failed to create MyRunnableThread!"));
delete MyRunnable;
MyRunnable = nullptr;
}
}
else
{
UE_LOG(LogTemp, Warning, TEXT("MyRunnableThread already running!"));
}
}
void AMyGameplayStaticsActor::StopThread()
{
// 先请求停止
if (MyRunnable)
{
MyRunnable->Stop();
}
// 再等待线程退出
if (MyRunnableThread)
{
MyRunnableThread->WaitForCompletion();
delete MyRunnableThread;
MyRunnableThread = nullptr;
}
// 最后删除 Runnable
delete MyRunnable;
MyRunnable = nullptr;
}
十五,编码
// MyCPP.Build.cs
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput", "Json", "JsonUtilities", "HTTP" });
// MyBlueprintFunctionLibrary.h
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyBlueprintFunctionLibrary.generated.h"
UCLASS()
class MYPROJECT_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
/** 文本 -> Base64(内部按 UTF-8 转字节) */
UFUNCTION(BlueprintPure, Category="MyLib|Base64")
static FString Base64EncodeString(const FString& Source);
/** 原始字节 -> Base64 */
UFUNCTION(BlueprintPure, Category="MyLib|Base64")
static FString Base64EncodeBytes(const TArray<uint8>& Source);
/** Base64 -> 文本(按 UTF-8 解码) */
UFUNCTION(BlueprintPure, Category="MyLib|Base64")
static bool Base64DecodeToString(const FString& Source, FString& OutDest);
/** Base64 -> 原始字节 */
UFUNCTION(BlueprintPure, Category="MyLib|Base64")
static bool Base64DecodeToBytes(const FString& Source, TArray<uint8>& OutDest);
UFUNCTION(BlueprintPure, Category="MyLib|Url")
static FString UrlEncode(const FString& Source);
UFUNCTION(BlueprintPure, Category="MyLib|Url")
static FString UrlDecode(const FString& Source);
UFUNCTION(BlueprintPure, Category = "MyLib|MD5")
static FString MD5Encode(const FString& Source);
};
// MyBlueprintFunctionLibrary.cpp
#include "MyBlueprintFunctionLibrary.h"
#include "Misc/Base64.h"
#include "GenericPlatform/GenericPlatformHttp.h"
FString UMyBlueprintFunctionLibrary::Base64EncodeString(const FString& Source)
{
return FBase64::Encode(Source);
}
FString UMyBlueprintFunctionLibrary::Base64EncodeBytes(const TArray<uint8>& Source)
{
return FBase64::Encode(Source);
}
bool UMyBlueprintFunctionLibrary::Base64DecodeToString(const FString& Source, FString& OutDest)
{
return FBase64::Decode(Source, OutDest);
}
bool UMyBlueprintFunctionLibrary::Base64DecodeToBytes(const FString& Source, TArray<uint8>& OutDest)
{
return FBase64::Decode(Source, OutDest);
}
FString UMyBlueprintFunctionLibrary::UrlEncode(const FString& Source)
{
return FGenericPlatformHttp::UrlEncode(Source);
}
FString UMyBlueprintFunctionLibrary::UrlDecode(const FString& Source)
{
return FGenericPlatformHttp::UrlDecode(Source);
}
FString UMyBlueprintFunctionLibrary::MD5Encode(const FString& Source)
{
return FMD5::HashAnsiString(*Source);
}
十六,时间戳
// 构造一个具体的日期时间:2026年11月6日 14点30分0秒
FDateTime SpecificDate(2026, 11, 6, 14, 30, 0);
// 通过 Ticks 构造(通常用于从序列化数据中恢复)
FDateTime FromTicks(638000000000000000LL);
FDateTime Now = FDateTime::Now();
int32 Year = Now.GetYear();
int32 Month = Now.GetMonth(); // 1-12
int32 Day = Now.GetDay();
int32 Hour = Now.GetHour(); // 0-23
int32 Minute = Now.GetMinute();
int32 Second = Now.GetSecond();
int32 Millisecond = Now.GetMillisecond(); // 0-999
// 当前时间点
FDateTime NowLocal = FDateTime::Now();
FDateTime NowUtc = FDateTime::UtcNow();
FString HttpDate = NowUtc.ToHttpDate(); // RFC 1123 格式,如Fri, 06 Nov 2026 06:30:00 GMT
// 构造时间段
FTimespan FiveMinutes = FTimespan::FromMinutes(5);
FTimespan TwoHours = FTimespan::FromHours(2);
// 获取总时长
double TotalSeconds = FiveMinutes.GetTotalSeconds();
double TotalHours = TwoHours.GetTotalHours();
// 与FTimespan的算术运算
FDateTime Start = FDateTime::Now();
FDateTime End = Start + FTimespan::FromMinutes(5);
// 格式化为字符串
FString TimeString = FDateTime::Now().ToString();
// 从字符串解析
FString TimeStr = TEXT("2026.11.06-14.30.00.000");
FDateTime ParsedTime;
FDateTime::Parse(TimeStr, ParsedTime);
// 与Unix时间戳互转
int64 UnixSec = Now.ToUnixTimestamp(); // 转换为秒级时间戳
FDateTime FromUnix = FDateTime::FromUnixTimestamp(UnixSec); // 从时间戳还原
2351



被折叠的 条评论
为什么被折叠?



