# DecorateConfigEditor SO集成升级说明

## 📋 概述

已将 `DecorateConfigEditor` 从直接加载图片路径升级为使用 ScriptableObject (SO) 资源系统。

## 🎯 主要改动

### 1. **资源加载方式变更**

#### 旧方式（已废弃）
```
Icon列：Icon/first/s1_icon_renwu_5
加载：从 Assets/GameMain/UI/UISprites/Decorate/ 路径直接加载
```

#### 新方式（当前）
```
Icon列：s1_icon_renwu_5
加载：从 ArtTableSO 中根据 Name 查找对应的 Sprite
```

### 2. **SO资源分类**

#### DecorateScene（场景资源）
- **路径**: `Assets/Art_SubModule/Art_SO/DecorateScene/Scene{AreaId}Resource.asset`
- **用途**: 存储 `SortId=0` 的初始化场景物体图片
- **命名规则**: Scene1Resource, Scene2Resource, ..., Scene50Resource
- **示例**: AreaId=1 → 从 Scene1Resource.asset 中查找

#### DecorateIcon（图标资源）
- **路径**: `Assets/Art_SubModule/Art_SO/DecorateIcon/DecorateIconResource.asset`
- **用途**: 存储 `SortId>0` 的步骤装饰图标
- **所有步骤图标**: 统一存放在 DecorateIconResource.asset

### 3. **核心功能修改**

#### ✅ 已修改的功能

1. **表格路径转换工具**
   - 新增：`蹊径 > 转换DecorateCost表格`
   - 功能：将Icon列完整路径转换为文件名
   - 自动备份原文件

2. **配置保存验证**
   - 保存前验证Icon名称是否存在于对应SO中
   - 显示详细的验证错误信息
   - 支持强制保存（不推荐）

3. **图片预览加载**
   - 步骤编辑UI的Icon预览
   - 初始状态编辑UI的Icon预览
   - 装饰按钮预览

4. **自动设置Icon**
   - 从SO中查找匹配的Icon名称
   - 支持批量设置

5. **场景物体Action执行**
   - `init_img`: 从SO加载Sprite
   - `replace_image`: 从SO加载替换图片

6. **拖入Sprite处理**
   - 自动从SO中查找对应Name
   - 兼容旧路径格式（自动转换）

## 🚀 使用流程

### 步骤1: 转换现有表格

1. 打开Unity编辑器
2. 菜单栏选择：`蹊径 > 转换DecorateCost表格`
3. 确认Excel路径：`E:\WorkSpace\Docs\config\DecorateCost.xlsx`
4. 点击"开始转换"
5. 检查转换日志，确认成功

**转换示例**：
```
Icon/first/s1_icon_renwu_5  →  s1_icon_renwu_5
Icon/first/s2_icon_renwu_3  →  s2_icon_renwu_3
cat/old/old_curtain         →  old_curtain
```

### 步骤2: 准备SO资源

#### 确保SO中包含所需资源

**DecorateScene SO** (初始化场景)
```
Assets/Art_SubModule/Art_SO/DecorateScene/Scene1Resource.asset
└── Items
    ├── Name: "old_curtain"       → Sprite: cat/old/old_curtain.png
    ├── Name: "back_box_2"        → Sprite: cat/old/back_box_2.png
    └── Name: "old_gabage"        → Sprite: cat/old/old_gabage.png
```

**DecorateIcon SO** (步骤图标)
```
Assets/Art_SubModule/Art_SO/DecorateIcon/DecorateIconResource.asset
└── Items
    ├── Name: "s1_icon_renwu_1"   → Sprite: Icon/first/s1_icon_renwu_1.png
    ├── Name: "s1_icon_renwu_2"   → Sprite: Icon/first/s1_icon_renwu_2.png
    └── Name: "s2_icon_renwu_1"   → Sprite: Icon/first/s2_icon_renwu_1.png
```

### 步骤3: 使用编辑器

1. 打开：`蹊径 > 场景建造工具`
2. 加载配置（会自动从SO中加载图片）
3. 编辑步骤配置
4. 保存时自动验证Icon名称是否存在

## 📝 配置示例

### DecorateCost.xlsx 表格格式

| Id | AreaId | SortId | Title | Icon | Pos | Action |
|----|--------|--------|-------|------|-----|--------|
| 1 | 1 | 0 | show | old_curtain | 150#625 | init_img#bg/clearObj/1 |
| 2 | 1 | 1 | 炉火 | s1_icon_renwu_1 | first | clear#bg/clearObj/10 |
| 3 | 1 | 2 | 窗户 | s1_icon_renwu_2 | second | add#bg/clearObj/18 |

### SO配置规则

```csharp
// SortId = 0 → 从 DecorateScene 加载
if (row.SortId == 0) {
    // 查找 Scene{AreaId}Resource.asset
    // 例如：AreaId=1 → Scene1Resource.asset
}

// SortId > 0 → 从 DecorateIcon 加载
if (row.SortId > 0) {
    // 查找 DecorateIconResource.asset
}
```

## ⚠️ 注意事项

### 1. Icon名称规范
- **必须与SO中Item的Name完全匹配**
- 区分大小写
- 不包含路径前缀（如 `Icon/first/`）

### 2. SO资源管理
- 定期检查SO中是否包含所有需要的资源
- 保持Name的唯一性
- Sprite引用不能为空

### 3. 保存验证
- 保存前会检查Icon名称有效性
- 无效的Icon会显示详细错误信息
- 建议修复后再保存（强制保存可能导致运行时错误）

### 4. 兼容性
- 支持拖入Sprite自动提取Name
- 兼容旧路径格式（自动转换为Name）
- 旧表格需要先运行转换工具

## 🔧 故障排查

### 问题1: 保存时提示"Icon名称在SO中不存在"

**原因**: Icon名称与SO中的Item Name不匹配

**解决方案**:
1. 检查Icon列的值是否正确
2. 打开对应的SO资源（Scene{AreaId}Resource 或 DecorateIconResource）
3. 确认Items列表中是否有匹配Name的项
4. 修正Icon名称或在SO中添加缺失的Item

### 问题2: Icon预览显示为空

**原因**: 无法从SO中加载Sprite

**解决方案**:
1. 检查SO资源是否存在
2. 确认Item.Name与Icon名称匹配
3. 确认Item.Sprite引用不为空
4. 查看Console日志获取详细错误信息

### 问题3: 自动设置Icon失败

**原因**: SO中找不到对应的Icon资源

**解决方案**:
1. 确认图标资源已添加到DecorateIconResource.asset
2. 确认Name格式：`s{AreaId}_icon_renwu_{StepId}`
3. 例如：AreaId=1, Step=5 → Name应为 `s1_icon_renwu_5`

### 问题4: 拖入Sprite后路径错误

**原因**: Sprite不在SO中，使用了旧路径提取逻辑

**解决方案**:
1. 确保拖入的Sprite已添加到对应SO的Items中
2. 如果是新Sprite，先在SO中添加，设置Name，再拖入编辑器

## 📚 API参考

### 新增方法

```csharp
// 加载装饰图标SO
ArtTableSO LoadDecorateIconSO()

// 加载场景资源SO
ArtTableSO LoadDecorateSceneSO(int areaId)

// 从SO中查找Sprite
Sprite FindSpriteInSO(string iconName, int areaId, bool isInitScene)

// 验证Icon名称
bool ValidateIconNameInSO(string iconName, int areaId, bool isInitScene, out string errorMsg)

// 从Icon名称加载Sprite（兼容旧格式）
Sprite LoadSpriteFromIconName(string iconNameOrPath, int areaId, bool isInitScene)
```

## 🎉 优势

1. **统一资源管理**: 所有图片资源集中在SO中管理
2. **编辑器友好**: 可视化管理，支持拖拽
3. **运行时高效**: 通过Name快速查找，无需路径解析
4. **类型安全**: 在保存时验证资源存在性
5. **易于维护**: SO结构清晰，便于扩展

## 📌 版本信息

- **升级日期**: 2026年1月31日
- **影响范围**: DecorateConfigEditor, DecorateCost.xlsx
- **兼容性**: 完全向后兼容（需先运行转换工具）

---

如有问题，请联系技术支持或查看详细日志。
