using System; using System.IO; using OfficeOpenXml; using UnityEditor; using UnityEngine; using Debug = UnityEngine.Debug; namespace DesignTools.Scene { /// /// 最大场景配置工具 /// 读取 Docs/config/Constant.xlsx 的 ConstantInt Sheet,仅编辑 MaxAreaId 的 ConstantValue。 /// public class MaxAreaIdEditor : BaseDesignToolEditor { private const string CONSTANT_EXCEL_NAME = "Constant.xlsx"; private const string CONSTANT_INT_SHEET_NAME = "ConstantInt"; private const int HEADER_ROW = 1; private const int DATA_START_ROW = 3; private const string TARGET_CONSTANT_KEY = "MaxAreaId"; private ConstantIntEntry maxAreaIdEntry; private int keyColumnIndex = -1; private int valueColumnIndex = -1; [MenuItem("策划工具/场景/最大场景")] public static void ShowWindow() { MaxAreaIdEditor window = GetWindow("最大场景"); window.minSize = window.GetMinWindowSize(); window.Show(); } protected override string GetDocsPathPrefKey() { return "MaxAreaIdEditor_DocsPath"; } protected override string GetWindowTitle() { return "最大场景工具"; } protected override Vector2 GetMinWindowSize() { return new Vector2(640, 320); } protected override void LoadConfigData() { LoadConstantIntSheet(); } protected override void DrawDataEditor() { EditorGUILayout.BeginVertical("box"); EditorGUILayout.HelpBox("此工具只会读取并写回 Constant.xlsx 的 ConstantInt Sheet 中 ConstantKey=MaxAreaId 这一条数据。", MessageType.Info); EditorGUILayout.EndVertical(); EditorGUILayout.Space(6); if (maxAreaIdEntry == null) { EditorGUILayout.HelpBox("未找到 MaxAreaId 配置。", MessageType.Warning); return; } EditorGUILayout.BeginVertical("box"); EditorGUILayout.LabelField("配置项", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("ConstantKey", GUILayout.Width(100)); EditorGUILayout.SelectableLabel(maxAreaIdEntry.ConstantKey, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight)); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(4); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("ConstantValue", GUILayout.Width(100)); maxAreaIdEntry.ConstantValue = EditorGUILayout.IntField(maxAreaIdEntry.ConstantValue, GUILayout.Width(180)); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(4); EditorGUILayout.LabelField($"Excel 行号:{maxAreaIdEntry.RowIndex}", EditorStyles.miniLabel); EditorGUILayout.EndVertical(); } protected override void SaveDataToExcel() { SaveConstantIntSheet(); } private void LoadConstantIntSheet() { maxAreaIdEntry = null; keyColumnIndex = -1; valueColumnIndex = -1; string excelPath = GetDocsConfigFilePath(CONSTANT_EXCEL_NAME); if (!File.Exists(excelPath)) { throw new FileNotFoundException($"未找到 {CONSTANT_EXCEL_NAME}", excelPath); } using (ExcelPackage package = new ExcelPackage(new FileInfo(excelPath))) { ExcelWorksheet worksheet = package.Workbook.Worksheets[CONSTANT_INT_SHEET_NAME]; if (worksheet == null) { throw new Exception($"{CONSTANT_EXCEL_NAME} 中未找到 Sheet: {CONSTANT_INT_SHEET_NAME}"); } if (worksheet.Dimension == null) { throw new Exception($"{CONSTANT_EXCEL_NAME}/{CONSTANT_INT_SHEET_NAME} 没有可读取的数据"); } keyColumnIndex = FindColumnIndex(worksheet, "ConstantKey"); valueColumnIndex = FindColumnIndex(worksheet, "ConstantValue"); if (keyColumnIndex < 0 || valueColumnIndex < 0) { throw new Exception($"{CONSTANT_EXCEL_NAME}/{CONSTANT_INT_SHEET_NAME} 表结构不正确,缺少 ConstantKey 或 ConstantValue 列"); } int rowCount = worksheet.Dimension.End.Row; for (int row = DATA_START_ROW; row <= rowCount; row++) { string constantKey = worksheet.Cells[row, keyColumnIndex].Text.Trim(); if (string.IsNullOrEmpty(constantKey) || constantKey != TARGET_CONSTANT_KEY) { continue; } string valueText = worksheet.Cells[row, valueColumnIndex].Text.Trim(); if (!int.TryParse(valueText, out int constantValue)) { throw new Exception($"{CONSTANT_INT_SHEET_NAME} Sheet 第 {row} 行 MaxAreaId 的 ConstantValue 不是有效整数:{valueText}"); } maxAreaIdEntry = new ConstantIntEntry { ConstantKey = constantKey, ConstantValue = constantValue, RowIndex = row }; break; } } if (maxAreaIdEntry == null) { throw new Exception($"{CONSTANT_INT_SHEET_NAME} Sheet 中未找到 ConstantKey={TARGET_CONSTANT_KEY} 的配置"); } Debug.Log($"最大场景配置读取完成,当前 {TARGET_CONSTANT_KEY}={maxAreaIdEntry.ConstantValue}"); } private void SaveConstantIntSheet() { if (maxAreaIdEntry == null) { EditorUtility.DisplayDialog("提示", "当前没有可保存的数据,请先加载配置。", "确定"); return; } string excelPath = GetDocsConfigFilePath(CONSTANT_EXCEL_NAME); if (!File.Exists(excelPath)) { EditorUtility.DisplayDialog("错误", $"未找到文件:{excelPath}", "确定"); return; } try { using (ExcelPackage package = new ExcelPackage(new FileInfo(excelPath))) { ExcelWorksheet worksheet = package.Workbook.Worksheets[CONSTANT_INT_SHEET_NAME]; if (worksheet == null) { EditorUtility.DisplayDialog("错误", $"未找到 Sheet: {CONSTANT_INT_SHEET_NAME}", "确定"); return; } worksheet.Cells[maxAreaIdEntry.RowIndex, valueColumnIndex].Value = maxAreaIdEntry.ConstantValue; package.Save(); } EditorUtility.DisplayDialog("成功", $"{TARGET_CONSTANT_KEY} 已保存到 Excel!", "确定"); Debug.Log($"最大场景配置保存成功,{TARGET_CONSTANT_KEY}={maxAreaIdEntry.ConstantValue}"); } catch (Exception e) { EditorUtility.DisplayDialog("错误", $"保存失败: {e.Message}", "确定"); Debug.LogError($"保存最大场景配置失败: {e}"); } } private int FindColumnIndex(ExcelWorksheet worksheet, string columnName) { int columnCount = worksheet.Dimension?.End.Column ?? 0; for (int col = 1; col <= columnCount; col++) { if (string.Equals(worksheet.Cells[HEADER_ROW, col].Text.Trim(), columnName, StringComparison.OrdinalIgnoreCase)) { return col; } } return -1; } [Serializable] private class ConstantIntEntry { public string ConstantKey; public int ConstantValue; public int RowIndex; } } }