NLDClient-yudde/ProjectNLD/Assets/Editor/Tools/LevelTextureExporter.cs

463 lines
18 KiB
C#
Raw Normal View History

2025-06-13 15:56:25 +08:00
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
{
2025-12-11 12:04:06 +08:00
[MenuItem("Tools/*关卡数据工具/关卡贴图导出")]
2025-06-13 15:56:25 +08:00
public static void ShowWindow()
{
GetWindow<LevelTextureExporter>("关卡贴图导出工具");
}
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的地面贴图路径");
2025-06-16 13:32:10 +08:00
GUILayout.Label("4. 同时检查Ground和Ground_2物体的贴图");
GUILayout.Label("5. 导出到CSV文件");
2025-06-13 15:56:25 +08:00
GUILayout.Label("注意:此过程可能需要较长时间,请耐心等待");
}
private void CheckCurrentScene()
{
try
{
Debug.Log("=== 开始检查当前场景 ===");
// 获取当前场景信息
var currentScene = EditorSceneManager.GetActiveScene();
Debug.Log($"当前场景: {currentScene.name}");
Debug.Log($"场景路径: {currentScene.path}");
// 查找NLDSceneManager
var sceneManager = FindObjectOfType<NLDSceneManager>();
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节点");
}
2025-06-16 13:32:10 +08:00
else
2025-06-13 15:56:25 +08:00
{
2025-06-16 13:32:10 +08:00
Debug.Log($"找到Ground节点: {groundTransform.name}");
// 检查MeshRenderer
var groundRenderer = groundTransform.GetComponent<MeshRenderer>();
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}");
}
}
}
2025-06-13 15:56:25 +08:00
}
2025-06-16 13:32:10 +08:00
// 检查Ground_2节点
var ground2Transform = artTransform.Find("Ground_2");
if (ground2Transform == null)
2025-06-13 15:56:25 +08:00
{
2025-06-16 13:32:10 +08:00
Debug.Log("未找到Ground_2节点");
2025-06-13 15:56:25 +08:00
}
2025-06-16 13:32:10 +08:00
else
2025-06-13 15:56:25 +08:00
{
2025-06-16 13:32:10 +08:00
Debug.Log($"找到Ground_2节点: {ground2Transform.name}");
// 检查MeshRenderer
var ground2Renderer = ground2Transform.GetComponent<MeshRenderer>();
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}");
}
}
}
2025-06-13 15:56:25 +08:00
}
Debug.Log("=== 检查完成 ===");
2025-06-16 13:32:10 +08:00
// 使用新的方法获取贴图路径
var (groundTexturePath, ground2TexturePath) = GetGroundTexturePaths(sceneManager);
string message = $"Ground贴图路径: {groundTexturePath}\nGround_2贴图路径: {ground2TexturePath}";
EditorUtility.DisplayDialog("检查完成", message, "确定");
2025-06-13 15:56:25 +08:00
}
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<LevelTextureInfo>();
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,
2025-06-16 13:32:10 +08:00
TexturePath = "未找到",
Ground2TexturePath = "未找到"
2025-06-13 15:56:25 +08:00
};
// 检查场景文件是否存在
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<GameObject>();
Debug.Log($"场景中GameObject数量: {allGameObjects.Length}");
// 查找NLDSceneManager
var sceneManager = FindObjectOfType<NLDSceneManager>();
if (sceneManager == null)
{
Debug.LogError($"关卡 {levelData.Id}: 未找到NLDSceneManager组件");
// 列出场景中所有组件的类型
var allComponents = FindObjectsOfType<MonoBehaviour>();
Debug.Log($"场景中组件类型:");
var componentTypes = new HashSet<string>();
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组件");
// 获取地面贴图路径
2025-06-16 13:32:10 +08:00
var (groundTexturePath, ground2TexturePath) = GetGroundTexturePaths(sceneManager);
levelTextureInfo.TexturePath = groundTexturePath;
levelTextureInfo.Ground2TexturePath = ground2TexturePath;
Debug.Log($"关卡 {levelData.Id}: 地面贴图路径 = {groundTexturePath}");
Debug.Log($"关卡 {levelData.Id}: Ground_2贴图路径 = {ground2TexturePath}");
2025-06-13 15:56:25 +08:00
}
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}");
}
}
2025-06-16 13:32:10 +08:00
private (string groundTexturePath, string ground2TexturePath) GetGroundTexturePaths(NLDSceneManager sceneManager)
2025-06-13 15:56:25 +08:00
{
2025-06-16 13:32:10 +08:00
string groundTexturePath = "未找到Ground节点";
string ground2TexturePath = "未找到Ground_2节点";
2025-06-13 15:56:25 +08:00
try
{
// 获取Art节点下的Ground对象
var artTransform = sceneManager.Art;
if (artTransform == null)
{
2025-06-16 13:32:10 +08:00
return ("未找到Art节点", "未找到Art节点");
2025-06-13 15:56:25 +08:00
}
2025-06-16 13:32:10 +08:00
// 查找Ground节点
2025-06-13 15:56:25 +08:00
var groundTransform = artTransform.Find("Ground");
2025-06-16 13:32:10 +08:00
if (groundTransform != null)
2025-06-13 15:56:25 +08:00
{
2025-06-16 13:32:10 +08:00
var groundRenderer = groundTransform.GetComponent<MeshRenderer>();
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 = "未找到地面材质";
}
2025-06-13 15:56:25 +08:00
}
2025-06-16 13:32:10 +08:00
// 查找Ground_2节点
var ground2Transform = artTransform.Find("Ground_2");
if (ground2Transform != null)
2025-06-13 15:56:25 +08:00
{
2025-06-16 13:32:10 +08:00
var ground2Renderer = ground2Transform.GetComponent<MeshRenderer>();
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材质";
}
2025-06-13 15:56:25 +08:00
}
2025-06-16 13:32:10 +08:00
return (groundTexturePath, ground2TexturePath);
2025-06-13 15:56:25 +08:00
}
catch (Exception ex)
{
2025-06-16 13:32:10 +08:00
return ($"获取Ground贴图路径时出错: {ex.Message}", $"获取Ground_2贴图路径时出错: {ex.Message}");
2025-06-13 15:56:25 +08:00
}
}
private void ExportToCSV(List<LevelTextureInfo> results)
{
try
{
var csvBuilder = new StringBuilder();
// 添加表头
2025-06-16 13:32:10 +08:00
csvBuilder.AppendLine("关卡ID,场景路径,地面贴图路径,Ground_2贴图路径");
2025-06-13 15:56:25 +08:00
// 添加数据
foreach (var result in results)
{
// 处理CSV中的特殊字符逗号、引号、换行符
string levelId = result.LevelId.ToString();
string scenePath = EscapeCSVField(result.LevelScenePath);
string texturePath = EscapeCSVField(result.TexturePath);
2025-06-16 13:32:10 +08:00
string ground2TexturePath = EscapeCSVField(result.Ground2TexturePath);
2025-06-13 15:56:25 +08:00
2025-06-16 13:32:10 +08:00
csvBuilder.AppendLine($"{levelId},{scenePath},{texturePath},{ground2TexturePath}");
2025-06-13 15:56:25 +08:00
}
// 保存文件
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; }
2025-06-16 13:32:10 +08:00
public string Ground2TexturePath { get; set; }
2025-06-13 15:56:25 +08:00
}
}