You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
4.0 KiB
91 lines
4.0 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.IO; |
|
using System.Reflection; |
|
using OfficeOpenXml; |
|
using Sirenix.OdinInspector; |
|
using UnityEditor; |
|
using UnityEngine; |
|
|
|
namespace Tools.ExcelResolver.Editor |
|
{ |
|
public sealed partial class ExcelResolverEditorWindow |
|
{ |
|
[FoldoutGroup("Hide Setting")] |
|
[ShowInInspector] private Dictionary<ExcelWorksheet, ClassCodeData> classCodeDataDict = new(); |
|
|
|
private void WriteSOData() |
|
{ |
|
foreach (var classCodeDataDictPair in classCodeDataDict) |
|
{ |
|
var worksheet = classCodeDataDictPair.Key; |
|
var classCodeData = classCodeDataDictPair.Value; |
|
|
|
Type soType = ExcelResolverUtil.GetOrCacheTypeByName(classCodeData.className); |
|
|
|
if (soType == null) |
|
{ |
|
Debug.LogError($"Class '{classCodeData.className}SO' not found. Please generate classes first (or check namespace)."); |
|
return; |
|
} |
|
var path = $"{excelResolverConfig.SOPathRoot}/{classCodeData.className}/"; |
|
|
|
string[] assetGuids = AssetDatabase.FindAssets($"t:{soType}", new[] { path }); |
|
Dictionary<string, ScriptableObject> assets = new(); |
|
for (int i = 0; i < assetGuids.Length; i++) |
|
{ |
|
string assetPath = AssetDatabase.GUIDToAssetPath(assetGuids[i]); |
|
ScriptableObject scriptableObject = AssetDatabase.LoadAssetAtPath<ScriptableObject>(assetPath); |
|
assets.Add(scriptableObject.name, scriptableObject); |
|
} |
|
|
|
for (int row = 1; row <= worksheet.Dimension.End.Row; row++) |
|
{ |
|
var assetName = $"{classCodeData.className}_{row}"; |
|
var fullPath = $"{path}{assetName}.asset"; |
|
// 跳过注释行 |
|
if (worksheet.Cells[row, 1].Text.StartsWith("##")) continue; |
|
|
|
if (assets.ContainsKey(assetName)) |
|
{ |
|
set(assets[assetName], soType, worksheet, row, classCodeData); |
|
EditorUtility.SetDirty(assets[assetName]); |
|
Debug.Log($"刷新:{assetName}", assets[assetName]); |
|
assets.Remove(assetName); |
|
} |
|
else |
|
{ |
|
ScriptableObject instance = ScriptableObject.CreateInstance(soType); |
|
set(instance, soType, worksheet, row, classCodeData); |
|
AssetDatabase.CreateAsset(instance, fullPath); |
|
Debug.Log($"创建:{assetName}", instance); |
|
} |
|
} |
|
|
|
foreach (var value in assets.Values) |
|
{ |
|
Debug.LogError($"删除:{value.name}", value); |
|
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(value)); |
|
} |
|
} |
|
AssetDatabase.SaveAssets(); |
|
GC.Collect(); |
|
GC.WaitForPendingFinalizers(); |
|
|
|
void set(ScriptableObject instance, Type soType, ExcelWorksheet worksheet, int row, ClassCodeData classCodeData) |
|
{ |
|
foreach (var pair in classCodeData.fields) |
|
{ |
|
var col = pair.Key; |
|
var fieldData = pair.Value; |
|
|
|
var cell = worksheet.Cells[row, col]; |
|
object convertedValue = ExcelResolverUtil.ConvertCellValue(cell, fieldData.type, classCodeData.className); |
|
FieldInfo fieldInfo = soType.GetField(fieldData.varName); |
|
if (fieldInfo == null) throw new Exception($"{classCodeData.className}中不存在字段:{fieldData.varName}"); |
|
fieldInfo.SetValue(instance, convertedValue); |
|
} |
|
} |
|
} |
|
} |
|
} |