# 模型导入优化方案 - 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 - 基础自动化导入实现
