using System; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using System.Text; using Framework; public class LevelTextureExporter : EditorWindow { [MenuItem("Tools/*关卡数据工具/关卡贴图导出")] public static void ShowWindow() { GetWindow("关卡贴图导出工具"); } private void OnGUI() { GUILayout.Label("关卡贴图导出工具", EditorStyles.boldLabel); GUILayout.Space(10); if (GUILayout.Button("开始导出关卡贴图到CSV", GUILayout.Height(30))) { ExportLevelTextures(); } GUILayout.Space(10); GUILayout.Label("调试工具:", EditorStyles.boldLabel); if (GUILayout.Button("检查当前场景", GUILayout.Height(25))) { CheckCurrentScene(); } GUILayout.Space(10); GUILayout.Label("说明:", EditorStyles.boldLabel); GUILayout.Label("1. 此工具会遍历所有关卡配置"); GUILayout.Label("2. 打开每个关卡对应的场景"); GUILayout.Label("3. 获取场景中NLDSceneManager的地面贴图路径"); GUILayout.Label("4. 同时检查Ground和Ground_2物体的贴图"); GUILayout.Label("5. 导出到CSV文件"); GUILayout.Label("注意:此过程可能需要较长时间,请耐心等待"); } private void CheckCurrentScene() { try { Debug.Log("=== 开始检查当前场景 ==="); // 获取当前场景信息 var currentScene = EditorSceneManager.GetActiveScene(); Debug.Log($"当前场景: {currentScene.name}"); Debug.Log($"场景路径: {currentScene.path}"); // 查找NLDSceneManager var sceneManager = FindObjectOfType(); if (sceneManager == null) { Debug.LogError("未找到NLDSceneManager组件"); return; } Debug.Log("找到NLDSceneManager组件"); // 检查Art节点 var artTransform = sceneManager.Art; if (artTransform == null) { Debug.LogError("未找到Art节点"); return; } Debug.Log($"找到Art节点: {artTransform.name}"); // 检查Ground节点 var groundTransform = artTransform.Find("Ground"); if (groundTransform == null) { Debug.LogError("未找到Ground节点"); } else { Debug.Log($"找到Ground节点: {groundTransform.name}"); // 检查MeshRenderer var groundRenderer = groundTransform.GetComponent(); if (groundRenderer == null) { Debug.LogError("Ground节点没有MeshRenderer组件"); } else { Debug.Log("找到Ground的MeshRenderer组件"); // 检查材质 if (groundRenderer.sharedMaterial == null) { Debug.LogError("Ground的MeshRenderer没有材质"); } else { var material = groundRenderer.sharedMaterial; Debug.Log($"Ground材质名称: {material.name}"); Debug.Log($"Ground材质路径: {AssetDatabase.GetAssetPath(material)}"); // 检查主贴图 var mainTexture = material.mainTexture; if (mainTexture == null) { Debug.LogError("Ground材质没有主贴图"); } else { Debug.Log($"Ground主贴图名称: {mainTexture.name}"); string texturePath = AssetDatabase.GetAssetPath(mainTexture); Debug.Log($"Ground主贴图路径: {texturePath}"); } } } } // 检查Ground_2节点 var ground2Transform = artTransform.Find("Ground_2"); if (ground2Transform == null) { Debug.Log("未找到Ground_2节点"); } else { Debug.Log($"找到Ground_2节点: {ground2Transform.name}"); // 检查MeshRenderer var ground2Renderer = ground2Transform.GetComponent(); if (ground2Renderer == null) { Debug.LogError("Ground_2节点没有MeshRenderer组件"); } else { Debug.Log("找到Ground_2的MeshRenderer组件"); // 检查材质 if (ground2Renderer.sharedMaterial == null) { Debug.LogError("Ground_2的MeshRenderer没有材质"); } else { var material = ground2Renderer.sharedMaterial; Debug.Log($"Ground_2材质名称: {material.name}"); Debug.Log($"Ground_2材质路径: {AssetDatabase.GetAssetPath(material)}"); // 检查主贴图 var mainTexture = material.mainTexture; if (mainTexture == null) { Debug.LogError("Ground_2材质没有主贴图"); } else { Debug.Log($"Ground_2主贴图名称: {mainTexture.name}"); string texturePath = AssetDatabase.GetAssetPath(mainTexture); Debug.Log($"Ground_2主贴图路径: {texturePath}"); } } } } Debug.Log("=== 检查完成 ==="); // 使用新的方法获取贴图路径 var (groundTexturePath, ground2TexturePath) = GetGroundTexturePaths(sceneManager); string message = $"Ground贴图路径: {groundTexturePath}\nGround_2贴图路径: {ground2TexturePath}"; EditorUtility.DisplayDialog("检查完成", message, "确定"); } catch (Exception ex) { Debug.LogError($"检查场景时出错: {ex.Message}"); EditorUtility.DisplayDialog("错误", $"检查场景时出错: {ex.Message}", "确定"); } } private void ExportLevelTextures() { try { // 获取关卡配置表 var levelConfig = EditorTableManager.instance.tables.Level; if (levelConfig == null) { EditorUtility.DisplayDialog("错误", "无法获取关卡配置表", "确定"); return; } var levelDataList = levelConfig.DataList; if (levelDataList == null || levelDataList.Count == 0) { EditorUtility.DisplayDialog("错误", "关卡配置表为空", "确定"); return; } // 保存当前场景 string currentScenePath = EditorSceneManager.GetActiveScene().path; bool hasCurrentScene = !string.IsNullOrEmpty(currentScenePath); var results = new List(); int totalCount = levelDataList.Count; int currentIndex = 0; EditorUtility.DisplayProgressBar("导出进度", "正在处理关卡...", 0f); foreach (var levelData in levelDataList) { currentIndex++; float progress = (float)currentIndex / totalCount; EditorUtility.DisplayProgressBar("导出进度", $"正在处理关卡 {levelData.Id} ({currentIndex}/{totalCount})", progress); var levelTextureInfo = new LevelTextureInfo { LevelId = levelData.Id, LevelScenePath = levelData.LevelScene, TexturePath = "未找到", Ground2TexturePath = "未找到" }; // 检查场景文件是否存在 if (string.IsNullOrEmpty(levelData.LevelScene) || !File.Exists(levelData.LevelScene)) { levelTextureInfo.TexturePath = "场景文件不存在"; results.Add(levelTextureInfo); continue; } try { Debug.Log($"=== 处理关卡 {levelData.Id} ==="); Debug.Log($"场景路径: {levelData.LevelScene}"); // 打开场景 EditorSceneManager.OpenScene(levelData.LevelScene, OpenSceneMode.Single); // 获取当前场景信息 var currentScene = EditorSceneManager.GetActiveScene(); Debug.Log($"当前场景: {currentScene.name}"); // 查找所有GameObject var allGameObjects = FindObjectsOfType(); Debug.Log($"场景中GameObject数量: {allGameObjects.Length}"); // 查找NLDSceneManager var sceneManager = FindObjectOfType(); if (sceneManager == null) { Debug.LogError($"关卡 {levelData.Id}: 未找到NLDSceneManager组件"); // 列出场景中所有组件的类型 var allComponents = FindObjectsOfType(); Debug.Log($"场景中组件类型:"); var componentTypes = new HashSet(); foreach (var comp in allComponents) { componentTypes.Add(comp.GetType().Name); } foreach (var type in componentTypes.OrderBy(t => t)) { Debug.Log($" - {type}"); } levelTextureInfo.TexturePath = "未找到NLDSceneManager"; } else { Debug.Log($"关卡 {levelData.Id}: 找到NLDSceneManager组件"); // 获取地面贴图路径 var (groundTexturePath, ground2TexturePath) = GetGroundTexturePaths(sceneManager); levelTextureInfo.TexturePath = groundTexturePath; levelTextureInfo.Ground2TexturePath = ground2TexturePath; Debug.Log($"关卡 {levelData.Id}: 地面贴图路径 = {groundTexturePath}"); Debug.Log($"关卡 {levelData.Id}: Ground_2贴图路径 = {ground2TexturePath}"); } results.Add(levelTextureInfo); } catch (Exception ex) { levelTextureInfo.TexturePath = $"错误: {ex.Message}"; results.Add(levelTextureInfo); Debug.LogError($"处理关卡 {levelData.Id} 时出错: {ex.Message}"); } } EditorUtility.ClearProgressBar(); // 恢复原始场景 if (hasCurrentScene) { EditorSceneManager.OpenScene(currentScenePath, OpenSceneMode.Single); } // 导出到CSV ExportToCSV(results); EditorUtility.DisplayDialog("完成", $"成功导出 {results.Count} 个关卡的数据到CSV文件", "确定"); } catch (Exception ex) { EditorUtility.ClearProgressBar(); EditorUtility.DisplayDialog("错误", $"导出过程中发生错误: {ex.Message}", "确定"); Debug.LogError($"导出过程中发生错误: {ex.Message}"); } } private (string groundTexturePath, string ground2TexturePath) GetGroundTexturePaths(NLDSceneManager sceneManager) { string groundTexturePath = "未找到Ground节点"; string ground2TexturePath = "未找到Ground_2节点"; try { // 获取Art节点下的Ground对象 var artTransform = sceneManager.Art; if (artTransform == null) { return ("未找到Art节点", "未找到Art节点"); } // 查找Ground节点 var groundTransform = artTransform.Find("Ground"); if (groundTransform != null) { var groundRenderer = groundTransform.GetComponent(); if (groundRenderer != null && groundRenderer.sharedMaterial != null) { var material = groundRenderer.sharedMaterial; var mainTexture = material.mainTexture; if (mainTexture != null) { string texturePath = AssetDatabase.GetAssetPath(mainTexture); if (!string.IsNullOrEmpty(texturePath)) { groundTexturePath = texturePath; } else { groundTexturePath = "无法获取贴图路径"; } } else { groundTexturePath = "材质没有主贴图"; } } else { groundTexturePath = "未找到地面材质"; } } // 查找Ground_2节点 var ground2Transform = artTransform.Find("Ground_2"); if (ground2Transform != null) { var ground2Renderer = ground2Transform.GetComponent(); if (ground2Renderer != null && ground2Renderer.sharedMaterial != null) { var material = ground2Renderer.sharedMaterial; var mainTexture = material.mainTexture; if (mainTexture != null) { string texturePath = AssetDatabase.GetAssetPath(mainTexture); if (!string.IsNullOrEmpty(texturePath)) { ground2TexturePath = texturePath; } else { ground2TexturePath = "无法获取贴图路径"; } } else { ground2TexturePath = "材质没有主贴图"; } } else { ground2TexturePath = "未找到Ground_2材质"; } } return (groundTexturePath, ground2TexturePath); } catch (Exception ex) { return ($"获取Ground贴图路径时出错: {ex.Message}", $"获取Ground_2贴图路径时出错: {ex.Message}"); } } private void ExportToCSV(List results) { try { var csvBuilder = new StringBuilder(); // 添加表头 csvBuilder.AppendLine("关卡ID,场景路径,地面贴图路径,Ground_2贴图路径"); // 添加数据 foreach (var result in results) { // 处理CSV中的特殊字符(逗号、引号、换行符) string levelId = result.LevelId.ToString(); string scenePath = EscapeCSVField(result.LevelScenePath); string texturePath = EscapeCSVField(result.TexturePath); string ground2TexturePath = EscapeCSVField(result.Ground2TexturePath); csvBuilder.AppendLine($"{levelId},{scenePath},{texturePath},{ground2TexturePath}"); } // 保存文件 string fileName = $"关卡贴图信息_{DateTime.Now:yyyyMMdd_HHmmss}.csv"; string savePath = EditorUtility.SaveFilePanel("保存CSV文件", Application.dataPath, fileName, "csv"); if (!string.IsNullOrEmpty(savePath)) { File.WriteAllText(savePath, csvBuilder.ToString(), Encoding.UTF8); Debug.Log($"CSV文件已保存到: {savePath}"); } } catch (Exception ex) { Debug.LogError($"导出CSV时出错: {ex.Message}"); throw; } } private string EscapeCSVField(string field) { if (string.IsNullOrEmpty(field)) return ""; // 如果字段包含逗号、引号或换行符,需要用引号包围并转义内部引号 if (field.Contains(",") || field.Contains("\"") || field.Contains("\n") || field.Contains("\r")) { return "\"" + field.Replace("\"", "\"\"") + "\""; } return field; } [System.Serializable] public class LevelTextureInfo { public int LevelId { get; set; } public string LevelScenePath { get; set; } public string TexturePath { get; set; } public string Ground2TexturePath { get; set; } } }