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

463 lines
18 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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<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的地面贴图路径");
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<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节点");
}
else
{
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}");
}
}
}
}
// 检查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<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}");
}
}
}
}
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<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,
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<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组件");
// 获取地面贴图路径
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<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 = "未找到地面材质";
}
}
// 查找Ground_2节点
var ground2Transform = artTransform.Find("Ground_2");
if (ground2Transform != null)
{
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材质";
}
}
return (groundTexturePath, ground2TexturePath);
}
catch (Exception ex)
{
return ($"获取Ground贴图路径时出错: {ex.Message}", $"获取Ground_2贴图路径时出错: {ex.Message}");
}
}
private void ExportToCSV(List<LevelTextureInfo> 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; }
}
}