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字段说明