258 lines
7.1 KiB
Markdown
258 lines
7.1 KiB
Markdown
# 模型导入优化方案 - Quixel风格自动化导入
|
||
|
||
## 📋 改进概述
|
||
|
||
本次优化将插件的模型导入方式从简单的 `AssetTools.ImportAssets()` 升级为 **Quixel Bridge** 风格的自动化导入流程,使用 `UAssetImportTask` 实现。
|
||
|
||
---
|
||
|
||
## ✅ 已完成改进(第一阶段)
|
||
|
||
### 核心变更
|
||
|
||
#### 1. **无弹窗自动导入**
|
||
```cpp
|
||
Task->bAutomated = true; // 禁用所有UI弹窗
|
||
Task->bSave = true; // 自动保存
|
||
Task->bReplaceExisting = bOverwrite;
|
||
```
|
||
|
||
#### 2. **FBX文件自动配置**
|
||
```cpp
|
||
if (Extension == TEXT("fbx"))
|
||
{
|
||
UFbxImportUI* ImportUI = NewObject<UFbxImportUI>();
|
||
|
||
// 禁用自动检测,明确指定为静态网格体
|
||
ImportUI->bAutomatedImportShouldDetectType = false;
|
||
ImportUI->MeshTypeToImport = FBXIT_StaticMesh;
|
||
|
||
// 自动导入材质和纹理
|
||
ImportUI->bImportMaterials = true;
|
||
ImportUI->bImportTextures = true;
|
||
|
||
// 静态网格体设置
|
||
ImportUI->StaticMeshImportData->bAutoGenerateCollision = true;
|
||
ImportUI->StaticMeshImportData->bCombineMeshes = true;
|
||
|
||
Task->Options = ImportUI;
|
||
}
|
||
```
|
||
|
||
#### 3. **批量导入任务**
|
||
```cpp
|
||
AssetTools.ImportAssetTasks(ImportTasks); // 替代了 ImportAssets()
|
||
```
|
||
|
||
---
|
||
|
||
## 🎯 当前效果
|
||
|
||
| 特性 | 旧方式 | **新方式(已实现)** |
|
||
|------|--------|-------------------|
|
||
| **UI弹窗** | ❌ 可能弹出 | ✅ **完全禁用** |
|
||
| **FBX配置** | ❌ 使用默认设置 | ✅ **自动配置导入选项** |
|
||
| **材质导入** | ⚠️ 引擎默认 | ✅ **自动导入材质和纹理** |
|
||
| **批量处理** | ✅ 支持 | ✅ **改用Task机制** |
|
||
| **碰撞生成** | ❌ 需手动 | ✅ **自动生成碰撞** |
|
||
|
||
---
|
||
|
||
## 🚀 进阶改进方向(可选的第二阶段)
|
||
|
||
如果您希望进一步实现 **Quixel级别的PBR材质自动生成**,可以考虑以下方向:
|
||
|
||
### 方案A:基于命名规则的智能材质生成
|
||
|
||
Quixel的核心技术是识别纹理命名模式,例如:
|
||
- `Hero_Albedo.png`
|
||
- `Hero_Normal.png`
|
||
- `Hero_Roughness.png`
|
||
- `Hero_Metallic.png`
|
||
- `Hero_AO.png`
|
||
|
||
**实现步骤:**
|
||
1. 导入完成后,扫描导入的纹理资产
|
||
2. 使用正则表达式或命名约定识别贴图类型
|
||
3. 自动创建 `UMaterialInstanceConstant`
|
||
4. 将识别的贴图自动连接到PBR Master Material
|
||
|
||
### 方案B:自定义导入Factory
|
||
|
||
创建继承自 `UFbxFactory` 的自定义Factory:
|
||
- 完全控制导入流程
|
||
- 在导入过程中自动创建和配置材质
|
||
- 实现自定义命名规范
|
||
|
||
### 方案C:后置处理Hook
|
||
|
||
使用 `FAssetEditorManager` 或 `AssetTools` 的回调:
|
||
- 监听资产导入完成事件
|
||
- 自动执行材质创建和配置
|
||
- 应用项目特定的标准
|
||
|
||
---
|
||
|
||
## 📝 使用示例
|
||
|
||
### TypeScript调用(无变化)
|
||
```typescript
|
||
const result = await wsService.callRequest('content.import', {
|
||
files: ['C:/Downloads/Hero.fbx', 'C:/Downloads/Texture_Albedo.png'],
|
||
destination_path: '/Game/Characters/Hero',
|
||
overwrite: false
|
||
});
|
||
```
|
||
|
||
### 预期效果
|
||
1. ✅ **无弹窗** - 不会出现任何导入确认对话框
|
||
2. ✅ **自动配置** - FBX文件自动使用优化的导入设置
|
||
3. ✅ **材质导入** - 自动导入FBX内嵌的材质和纹理
|
||
4. ✅ **碰撞生成** - 自动生成碰撞网格
|
||
|
||
---
|
||
|
||
## 🔧 技术细节
|
||
|
||
### 关键API变更
|
||
|
||
#### 旧代码
|
||
```cpp
|
||
TArray<UObject*> ImportedAssets = AssetTools.ImportAssets(FilesToImport, DestinationPath);
|
||
```
|
||
|
||
#### 新代码
|
||
```cpp
|
||
// 1. 创建任务
|
||
UAssetImportTask* Task = NewObject<UAssetImportTask>();
|
||
Task->Filename = FilePath;
|
||
Task->DestinationPath = DestinationPath;
|
||
Task->bAutomated = true; // 核心:禁用UI
|
||
|
||
// 2. 配置选项(针对FBX)
|
||
UFbxImportUI* ImportUI = NewObject<UFbxImportUI>();
|
||
ImportUI->bAutomatedImportShouldDetectType = false;
|
||
ImportUI->MeshTypeToImport = FBXIT_StaticMesh;
|
||
ImportUI->bImportMaterials = true;
|
||
Task->Options = ImportUI;
|
||
|
||
// 3. 执行批量导入
|
||
AssetTools.ImportAssetTasks(ImportTasks);
|
||
|
||
// 4. 从Task获取结果
|
||
Task->ImportedObjectPaths // 导入的资产路径列表
|
||
```
|
||
|
||
### 添加的头文件
|
||
```cpp
|
||
#include "AssetImportTask.h"
|
||
#include "Factories/FbxImportUI.h"
|
||
```
|
||
|
||
---
|
||
|
||
## 🎨 Quixel完整实现需要什么?
|
||
|
||
要达到 **完全的Quixel水平**,还需要:
|
||
|
||
### 1. **智能纹理识别系统**
|
||
```cpp
|
||
// 伪代码示例
|
||
TMap<FString, UTexture2D*> ClassifyTextures(const TArray<UTexture2D*>& Textures)
|
||
{
|
||
TMap<FString, UTexture2D*> ClassifiedTextures;
|
||
|
||
for (UTexture2D* Texture : Textures)
|
||
{
|
||
FString Name = Texture->GetName().ToLower();
|
||
|
||
if (Name.Contains("albedo") || Name.Contains("diffuse"))
|
||
ClassifiedTextures.Add("Albedo", Texture);
|
||
else if (Name.Contains("normal"))
|
||
ClassifiedTextures.Add("Normal", Texture);
|
||
else if (Name.Contains("rough"))
|
||
ClassifiedTextures.Add("Roughness", Texture);
|
||
// ... 其他类型
|
||
}
|
||
|
||
return ClassifiedTextures;
|
||
}
|
||
```
|
||
|
||
### 2. **PBR材质实例自动生成**
|
||
```cpp
|
||
UMaterialInstanceConstant* CreatePBRMaterial(
|
||
const FString& AssetName,
|
||
const TMap<FString, UTexture2D*>& Textures,
|
||
UMaterial* MasterMaterial)
|
||
{
|
||
// 创建材质实例
|
||
UMaterialInstanceConstant* MatInst = CreateAsset<UMaterialInstanceConstant>(
|
||
DestinationPath, AssetName + "_Mat");
|
||
|
||
MatInst->SetParentEditorOnly(MasterMaterial);
|
||
|
||
// 设置纹理参数
|
||
if (Textures.Contains("Albedo"))
|
||
MatInst->SetTextureParameterValueEditorOnly("AlbedoTexture", Textures["Albedo"]);
|
||
|
||
if (Textures.Contains("Normal"))
|
||
MatInst->SetTextureParameterValueEditorOnly("NormalTexture", Textures["Normal"]);
|
||
|
||
// ... 设置其他参数
|
||
|
||
return MatInst;
|
||
}
|
||
```
|
||
|
||
### 3. **标准化命名系统**
|
||
```cpp
|
||
FString StandardizeName(const FString& OriginalName, const FString& AssetType)
|
||
{
|
||
// 示例:T_Hero_Albedo, SM_Hero, M_Hero_Inst
|
||
FString Prefix;
|
||
if (AssetType == "Texture") Prefix = "T_";
|
||
else if (AssetType == "StaticMesh") Prefix = "SM_";
|
||
else if (AssetType == "Material") Prefix = "M_";
|
||
|
||
return Prefix + CleanName(OriginalName);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 💬 下一步建议
|
||
|
||
### 选项1:保持当前实现(推荐)
|
||
- 当前的改进已经解决了**弹窗问题**
|
||
- FBX**自动导入材质和纹理**
|
||
- 满足大部分自动化需求
|
||
|
||
### 选项2:实现完整的PBR自动生成
|
||
如果您需要:
|
||
1. 创建一个 **PBR Master Material**
|
||
2. 实现 **`content.import_pbr`** 新命令,包含:
|
||
- 纹理分类算法
|
||
- 自动材质实例创建
|
||
- 标准化命名
|
||
3. 将材质自动应用到导入的模型
|
||
|
||
### 选项3:混合方案
|
||
- 保留当前的 `content.import`(通用导入)
|
||
- 新增 `content.import_pbr`(Quixel风格PBR导入)
|
||
- 让用户根据需求选择使用哪个
|
||
|
||
---
|
||
|
||
## 📚 参考资料
|
||
|
||
- **Unreal Engine文档**: [UAssetImportTask](https://docs.unrealengine.com/5.3/en-US/API/Editor/UnrealEd/AssetImportTask/)
|
||
- **FBX导入**: [UFbxImportUI](https://docs.unrealengine.com/5.3/en-US/API/Editor/UnrealEd/Factories/FbxImportUI/)
|
||
- **AssetTools**: [IAssetTools::ImportAssetTasks](https://docs.unrealengine.com/5.3/en-US/API/Developer/AssetTools/IAssetTools/ImportAssetTasks/)
|
||
|
||
---
|
||
|
||
**作者:** Antigravity AI Assistant
|
||
**日期:** 2025-12-11
|
||
**版本:** v1.0 - 基础自动化导入实现
|