ULCCUtilLibrary:藍圖工具函數庫
靜態工具函數庫,提供路徑校驗、格式識別、剪貼板操作、版本查詢等輔助能力。
| 模塊 | LCC4UnrealRuntime |
| 頭文件 | Tools/LCCUtilLibrary.h |
| 父類 | UBlueprintFunctionLibrary |
#include "Tools/LCCUtilLibrary.h"
全部是靜態函數,直接用類名調用,不需要實例:
const bool bValid = ULCCUtilLibrary::CheckPathValid(Path);
藍圖裏這些節點不需要 Target 引腳,直接搜函數名即可。
Path and Format Validation
加載數據前先校驗,能把「路徑不對」和「數據本身有問題」區分開,省掉大量排查時間。
CheckPathValid
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static bool CheckPathValid(FString Path);
檢查文件是否存在。
| 參數 | 類型 | 說明 |
|---|---|---|
Path | FString | 待檢查的文件路徑 |
返回 bool:文件存在返回 true。
用法要點:
- 只判斷文件,傳目錄路徑會返回
false。 內部用的是文件存在性檢查。 - 只查存在性,不查內容是否是合法的 LCC 數據。
- 加載流程的第一道檢查,先排除掉路徑拼錯、文件被移走這類問題。
if (!ULCCUtilLibrary::CheckPathValid(Path))
{
UE_LOG(LogTemp, Error, TEXT("Path does not exist: %s"), *Path);
return;
}
CheckLCCValid
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static bool CheckLCCValid(FString Path, FString& OutWorkPath);
檢查是否為有效的 LCC1 數據。
| 參數 | 類型 | 說明 |
|---|---|---|
Path | FString | .lcc 文件路徑,文件名不固定 |
OutWorkPath | FString& | 輸出工作目錄,即數據文件所在的目錄 |
返回 bool:有效返回 true。
用法要點:
- LCC1 需要
.lcc文件本身,加上同目錄下的data.bin與index.bin,缺一個就返回false。.lcc的文件名不固定。 - 輸出的
OutWorkPath是去掉文件名後的目錄,需要拼接同目錄其他文件時用得上。 - 支持相對路徑:傳入路徑不存在時,會自動再試一次
Content/<傳入路徑>,與Load()的規則一致。
FString WorkPath;
if (ULCCUtilLibrary::CheckLCCValid(Path, WorkPath))
{
UE_LOG(LogTemp, Log, TEXT("Valid LCC1 data, work path: %s"), *WorkPath);
}
CheckLCC2Valid
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static bool CheckLCC2Valid(FString Path, FString& OutWorkPath);
檢查 LCC2 路徑並取出工作目錄。參數含義同上。
用法要點:
- LCC2 不需要
data.bin與index.bin,所以這個函數只確認路徑存在、然後取父目錄作為OutWorkPath,不校驗數據內容完整性。真正的內容校驗發生在加載階段。 - 拿到一個路徑不確定是 LCC1 還是 LCC2 時,先看擴展名(
.lcc還是.lcc2)最直接。也可以兩個校驗函數都試一次:
FString WorkPath;
if (Path.EndsWith(TEXT(".lcc2"), ESearchCase::IgnoreCase))
{
if (ULCCUtilLibrary::CheckLCC2Valid(Path, WorkPath))
{
// 用 ALCC2Actor
}
}
else if (Path.EndsWith(TEXT(".lcc"), ESearchCase::IgnoreCase))
{
if (ULCCUtilLibrary::CheckLCCValid(Path, WorkPath))
{
// 用 ALCCActor
}
}
else
{
UE_LOG(LogTemp, Error, TEXT("Not an LCC dataset: %s"), *Path);
}
注:不要靠「
CheckLCC2Valid返回 true 就當作 LCC2」來區分。它的校驗很寬鬆,.lcc路徑同樣會返回true,那樣會把 LCC1 數據誤判成 LCC2。先看擴展名。
DetermineFileFormat
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static EFileFormat DetermineFileFormat(const FString& Path);
判斷文件格式。
返回 EFileFormat。實際按擴展名判斷,且要求路徑存在:
| 擴展名 | 返回值 |
|---|---|
.lcc | LCC |
.splats | Splats |
.las | LAS |
.ply | PLY |
| 其他,或路徑不存在 | None |
用法要點:
- 這個函數不識別
.lcc2、.sog、.spz,它們都會返回None。 需要覆蓋這些格式時自行判斷擴展名。 - 路徑不存在也返回
None,所以返回None有兩種可能:格式不支持,或者文件根本不在。想區分開就先調 CheckPathValid。
因為覆蓋不全,做通用加載器時更穩的做法是直接看擴展名:
UClass* PickActorClass(const FString& Path)
{
const FString Ext = FPaths::GetExtension(Path).ToLower();
if (Ext == TEXT("lcc")) return ALCCActor::StaticClass();
if (Ext == TEXT("lcc2")) return ALCC2Actor::StaticClass();
if (Ext == TEXT("sog")) return ASogActor::StaticClass();
if (Ext == TEXT("spz")) return ASpzActor::StaticClass();
if (Ext == TEXT("ply")) return APlyActor::StaticClass();
return nullptr;
}
完整示例見 SOG / SPZ / PLY Actors。
DetermineSourceType
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static ELCCSourceType DetermineSourceType(const FString& Path);
判斷數據來源類型。
返回 ELCCSourceType:Local 本地文件,Http 網絡地址。
用於區分處理邏輯,比如網絡數據需要先下載或走流式加載。
DetermineCollisionType
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static ECollisionType DetermineCollisionType(const FString& Path);
判斷碰撞數據格式。
| 參數 | 類型 | 說明 |
|---|---|---|
Path | const FString& | 數據所在目錄,不是 .lcc 文件路徑。函數在該目錄下查找 collision.lci、collision.bin 等文件 |
返回 ECollisionType:
| 取值 | 含義 |
|---|---|
None | 無碰撞數據 |
Bin | 舊版 .bin 格式 |
Lci | 新版 .lci 格式 |
Ply | 點雲 .ply 碰撞 |
用法要點:
- 傳目錄,不要傳文件路徑。 傳
.lcc文件路徑會一律返回None。目錄可以從CheckLCCValid的OutWorkPath拿到。 - 返回
None說明數據不帶碰撞,此時開啟bEnableCollision不會有效果。 - 數據已經加載完成的話,用 Component 上的
HaveValidCollisionData()更省事,不用自己拼目錄。
Version and Environment
GetLCC4UnrealVersion
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static FString GetLCC4UnrealVersion();
返回插件版本號字符串。
用途:顯示在關於界面、寫進日誌、提交問題時附帶。
UE_LOG(LogTemp, Log, TEXT("LCC4Unreal version: %s"),
*ULCCUtilLibrary::GetLCC4UnrealVersion());
GetProjectId
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static FString GetProjectId();
返回當前工程的標識。申請授權、排查授權問題時需要提供。
GetLCCConfigPath
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static FString GetLCCConfigPath();
返回插件配置文件路徑。
GetLCC4UnrealRootPath
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static FString GetLCC4UnrealRootPath();
返回插件根目錄路徑。需要訪問插件自帶資源時用它拼路徑。
GetLocale
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static ELocale GetLocale();
返回當前語言環境,ELocale::EN_US 或 ELocale::ZH_CN。
判斷順序:先看項目設置裏的 Language 項,若為 Always English 直接返回 EN_US;否則按編輯器當前語言判斷,中文返回 ZH_CN。
用途:自己的 UI 跟隨插件語言設置切換文案,或者按地區選擇官網域名。
const FString DownloadUrl = (ULCCUtilLibrary::GetLocale() == ELocale::ZH_CN)
? TEXT("https://xgrids.cn/support/download")
: TEXT("https://xgrids.com/intl/support/download");
Viewport Identifiers
GetPlayerUniqueID
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static bool GetPlayerUniqueID(class APlayerController* PlayerController, int32& OutUniqueID);
獲取玩家控制器的唯一標識。
| 參數 | 類型 | 說明 |
|---|---|---|
PlayerController | APlayerController* | 目標玩家控制器 |
OutUniqueID | int32& | 輸出唯一標識 |
返回 bool:獲取成功返回 true。
用法要點:
- 需要自己維護「每個視口一套配置」的映射表時用它當鍵。
- 常規的多視口渲染配置直接用
SetPlayerLoadMode、SetPlayerRenderMode傳控制器指針即可,不需要手動取 ID。
GetSceneCaptureUniqueID
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static bool GetSceneCaptureUniqueID(class USceneCaptureComponent2D* SceneCaptureComponent2D,
int32& OutUniqueID);
獲取 SceneCapture 組件的唯一標識。參數與返回值含義同上。
Clipboard
CopyToClipboard
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static void CopyToClipboard(FString CopyString);
把字符串寫入系統剪貼板。
| 參數 | 類型 | 說明 |
|---|---|---|
CopyString | FString | 要複製的內容 |
典型用途:做一個「複製診斷信息」按鈕,方便用戶反饋問題。
void AMyDebugUI::CopyDiagnostics()
{
const FString Info = FString::Printf(
TEXT("Plugin: %s\nProject: %s\nSplats: %d"),
*ULCCUtilLibrary::GetLCC4UnrealVersion(),
*ULCCUtilLibrary::GetProjectId(),
Component->GetSplatNumber());
ULCCUtilLibrary::CopyToClipboard(Info);
}
GetClipboardString
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static FString GetClipboardString();
讀取系統剪貼板內容。
典型用途:做一個「從剪貼板粘貼路徑」按鈕,省掉手輸長路徑。
void AMyLoader::LoadFromClipboard()
{
const FString Path = ULCCUtilLibrary::GetClipboardString();
if (ULCCUtilLibrary::CheckPathValid(Path))
{
LCCActor->Load(Path);
}
}
文本藍圖:
[Button Clicked: PasteAndLoad]
│
▼
[Get Clipboard String]
│ Return Value ──┐
▼ │
[Check Path Valid] ◀─────┘
Path = (Return Value)
│ Return Value ──┐
▼ │
[Branch] ◀───────────────┘
│ True
▼
[Load]
Target = LCCActor
String = (剪貼板內容)
Texture
GetTextureFromBase64
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static UTexture2D* GetTextureFromBase64(const FString& Base64String);
把 Base64 編碼的圖像數據轉成運行時紋理。
| 參數 | 類型 | 說明 |
|---|---|---|
Base64String | const FString& | Base64 編碼的圖像數據 |
返回 UTexture2D*:轉換失敗返回 nullptr。
用途:從網絡接口或配置文件裏拿到 Base64 圖像,直接生成紋理用於 UI,不需要落盤再導入。
UTexture2D* Texture = ULCCUtilLibrary::GetTextureFromBase64(Base64Data);
if (Texture)
{
MyImageWidget->SetBrushFromTexture(Texture);
}
SOG Metadata Parsing
這幾個函數用於在不加載渲染數據的前提下讀取 .sog 文件的元信息,適合做數據預覽、列表頁展示。
ParseSogMetaFromFile
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static bool ParseSogMetaFromFile(const FString& FilePath, FLCC2SogMeta& OutMeta);
從文件解析 SOG 元信息。
| 參數 | 類型 | 說明 |
|---|---|---|
FilePath | const FString& | .sog 文件路徑 |
OutMeta | FLCC2SogMeta& | 輸出元信息 |
返回 bool:解析成功返回 true。
用法要點:
- 只讀元信息,不加載 Splat 數據,開銷很小。
- 可以據此在加載前就知道點數、是否含高階球諧,用於判斷是否需要降級配置。
FLCC2SogMeta Meta;
if (ULCCUtilLibrary::ParseSogMetaFromFile(TEXT("D:/Data/scene.sog"), Meta))
{
UE_LOG(LogTemp, Log, TEXT("Splat count: %d, has high-order SH: %s"),
Meta.Count, Meta.HasShN() ? TEXT("yes") : TEXT("no"));
// 點數過大時提前降配置
if (Meta.Count > 5000000)
{
Component->SetMaxSplatNum(1000);
}
}
ParseSogMetaFromData
UFUNCTION(BlueprintCallable, Category = "XGrids|Util")
static bool ParseSogMetaFromData(const TArray<uint8>& Data, FLCC2SogMeta& OutMeta);
從內存中的字節數組解析 SOG 元信息。
數據來自網絡下載、尚未落盤時用這個版本。
FLCC2SogMeta 字段說明見 Structs。
C++ Only
以下函數沒有 UFUNCTION 標記,只能在 C++ 中調用。
ConvertStrToMetaInfo
static FLCCMetaInfo ConvertStrToMetaInfo(const FString& JsonStr);
把 .lcc 文件的 JSON 內容轉成 FLCCMetaInfo 結構體。
用於自己讀取並解析元信息文件,比如做數據管理工具時批量掃描數據集。
ConvertStrToLCC2MetaInfo
static FLCC2MetaInfo ConvertStrToLCC2MetaInfo(const FString& JsonStr);
把 .lcc2 文件的 JSON 內容轉成 FLCC2MetaInfo 結構體。
SelectFile
static FString SelectFile(ELCCVersion LCCVersion);
彈出文件選擇對話框,按版本過濾擴展名。返回選中的路徑,取消則返回空字符串。
僅編輯器可用。Actor 上的 SelectFile() 內部調用的就是它。
注:
ULCCUtilLibrary裏還有若干僅供插件內部使用的靜態函數(視錐體計算、SOG 解析的內部實現、子目錄擴展名檢查等),它們編譯上可見但不屬於對外 API,行為可能隨版本變化,請勿依賴。
Complete Example: Validate Before Load
#include "Tools/LCCUtilLibrary.h"
#include "LCCActor.h"
#include "LCC2Actor.h"
bool AMyLoader::ValidateAndLoad(const FString& Path)
{
// 1. 路徑存在性
if (!ULCCUtilLibrary::CheckPathValid(Path))
{
UE_LOG(LogTemp, Error, TEXT("Path does not exist: %s"), *Path);
return false;
}
// 2. 按擴展名分辨格式
const FString Ext = FPaths::GetExtension(Path).ToLower();
const bool bIsLCC1 = (Ext == TEXT("lcc"));
const bool bIsLCC2 = (Ext == TEXT("lcc2"));
if (!bIsLCC1 && !bIsLCC2)
{
// .sog / .spz / .ply 的分發見 SOG / SPZ / PLY Actors 頁
UE_LOG(LogTemp, Error, TEXT("Not an LCC dataset: %s"), *Path);
return false;
}
// 3. 校驗數據完整性,同時取出工作目錄
FString WorkPath;
const bool bValid = bIsLCC2
? ULCCUtilLibrary::CheckLCC2Valid(Path, WorkPath)
: ULCCUtilLibrary::CheckLCCValid(Path, WorkPath);
if (!bValid)
{
UE_LOG(LogTemp, Error, TEXT("Incomplete LCC dataset: %s"), *Path);
return false;
}
// 4. 生成對應 Actor 並加載
UClass* ActorClass = bIsLCC2 ? ALCC2Actor::StaticClass() : ALCCActor::StaticClass();
ALCCActorBase* Actor = GetWorld()->SpawnActor<ALCCActorBase>(ActorClass);
if (!Actor)
{
return false;
}
Actor->Load(Path);
// 5. 順手確認碰撞數據是否存在。注意傳的是工作目錄,不是文件路徑
const ECollisionType CollisionType =
ULCCUtilLibrary::DetermineCollisionType(WorkPath);
UE_LOG(LogTemp, Log, TEXT("Collision type: %d"),
static_cast<int32>(CollisionType));
return true;
}
See Also
- SOG / SPZ / PLY Actors:按格式分發的完整示例
- Enums:
EFileFormat、ECollisionType、ELocale等取值說明 - Structs:
FLCCMetaInfo、FLCC2SogMeta字段說明