原文链接:http://blog.csdn.net/u010153703/article/details/38062627
1. 单例
Unreal Engine的wiki上,Rama给了一个教程,教大家如何存储不常改变的全局数据,便于运行时从任何cpp或者Blueprint访问之。
要点如下:
1. 创建一个继承自UObject的class Single,需要标注UClass(Blueprintable, BlueprintType)。
在创建的class Single里放置一些全局变量后,需要添加UFunction,实现全局访问数据的接口函数。
2. 最重要的是,运行工程后,在Editor里需要设置工程的单例。
运行打开编辑器后,创建基于步骤1里的class Single的Blueprint, BP_MySingle;
然后修改编辑器的配置参数:Project Settings->Engine->General, 将Game Singleton Class设置为你自己的单例BP: BP_MySingle! 注意,用的是基于class Single的Blueprint, 不是class Single本身!
单例更偏向于数据的存取和访问,而且是一些很少改变的数据。 如何处理那些全局的功能函数呢?
2. BlueprintFunctionLibrary
创建可以在任意BP里访问的功能函数。
创建一个继承自UBlueprintFunctionLibrary的class, 在其中声明你需要的功能函数。
UFUNCTION(BlueprintPure) or UFUNCTION(BlueprintCallable)声明。同时函数请设置为static属性。
若函数带有BlueprintPure属性,则说明此函数不会修改任何游戏状态,因此无需exec链的触发(在Blueprint中体现为没有白线输入),可以在任何时刻被调用获取其结果。
.h
- #pragma once
- #include "SolusDataSingleton.h"
- #include "SolusDataSingletonLibrary.generated.h"
- UCLASS()
- class USolusDataSingletonLibrary : public UBlueprintFunctionLibrary
- {
- GENERATED_UCLASS_BODY()
- UFUNCTION(BlueprintPure, Category = "Solus Data Singleton")
- static USolusDataSingleton* GetSolusData(bool& IsValid);
- UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
- static FString GetHappyMessage();
- UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
- static bool SaveStringTextToFile(FString SaveDirectory, FString FileName, FString SaveText, bool AllowOverWriting=false);
- UFUNCTION(BlueprintCallable, Category = "ScreenResolution")
- static void GetDisplayAdapterScreenResolutions();
- };
.cpp
- #include "MyThirdPersonCode.h"
- #include "SolusDataSingletonLibrary.h"
- USolusDataSingletonLibrary::USolusDataSingletonLibrary(const class FPostConstructInitializeProperties& PCIP)
- : Super(PCIP)
- {
- }
- USolusDataSingleton* USolusDataSingletonLibrary::GetSolusData(bool& IsValid)
- {
- IsValid = false;
- USolusDataSingleton* DataInstance = Cast<USolusDataSingleton>(GEngine->GameSingleton);
- if (!DataInstance)
- {
- return NULL;
- }
- if (!DataInstance->IsValidLowLevel())
- {
- return NULL;
- }
- IsValid = true;
- return DataInstance;
- }
- FString USolusDataSingletonLibrary::GetHappyMessage()
- {
- return FString("Victory! Give me a big Smile. Victory BP Works!");
- }
- bool USolusDataSingletonLibrary::SaveStringTextToFile(FString SaveDirectory, FString FileName, FString SaveText, bool AllowOverWriting/* =false */)
- {
- IPlatformFile& F = FPlatformFileManager::Get().GetPlatformFile();
- if (!F.DirectoryExists(*SaveDirectory))
- {
- F.CreateDirectoryTree(*SaveDirectory);
- if (!F.DirectoryExists(*SaveDirectory))
- {
- return false;
- }
- }
- SaveDirectory += "\\";
- SaveDirectory += FileName;
- if (!AllowOverWriting)
- {
- if (!F.FileExists(*SaveDirectory))
- {
- return false;
- }
- }
- return FFileHelper::SaveStringToFile(SaveText, *SaveDirectory);
- }
- DEFINE_LOG_CATEGORY_STATIC(MyLog, All, All)
- void USolusDataSingletonLibrary::GetDisplayAdapterScreenResolutions()
- {
- FScreenResolutionArray Resolutions;
- if (RHIGetAvailableResolutions(Resolutions, false))
- {
- for (const FScreenResolutionRHI& EachResolution : Resolutions)
- {
- FString disInfo = FString("X=") + FString::FromInt(EachResolution.Width) + FString(" Y=") + FString::FromInt(EachResolution.Height);
- GEngine->AddOnScreenDebugMessage(-1, 5.0, FColor::Blue, disInfo);
- UE_LOG(MyLog, Warning, TEXT("DefaultAdapter - %4d x %4d @ %d"), EachResolution.Width, EachResolution.Height, EachResolution.RefreshRate);
- }
- }
- else
- {
- GEngine->AddOnScreenDebugMessage(-1, 5.0, FColor::Blue, "Screen Resolutions could not be obtained");
- UE_LOG(MyLog, Error, TEXT("Screen Resolutions could not be obtained"));
- }
- }