338 lines
12 KiB
C#
338 lines
12 KiB
C#
namespace HK.Editor
|
||
{
|
||
using UnityEngine;
|
||
using UnityEditor;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System;
|
||
// 移除了System.Windows.Forms引用
|
||
|
||
public class DevLoggerWindow : EditorWindow
|
||
{
|
||
// 日志分类选项
|
||
public enum LogCategory
|
||
{
|
||
功能开发,
|
||
BUG修复,
|
||
优化改进,
|
||
文档编写,
|
||
测试验证,
|
||
会议讨论,
|
||
自定义
|
||
}
|
||
|
||
// 日志数据类
|
||
[Serializable]
|
||
public class DevLogEntry
|
||
{
|
||
public string timestamp; // 时间戳
|
||
public string content; // 开发内容
|
||
public bool isCompleted; // 是否完成
|
||
public string date; // 日期(用于分组)
|
||
public string category; // 分类标签
|
||
}
|
||
|
||
// 日志列表
|
||
private List<DevLogEntry> logEntries = new List<DevLogEntry>();
|
||
|
||
// 窗口状态
|
||
private string newLogContent = "";
|
||
private bool newLogCompleted = false;
|
||
private LogCategory selectedCategory = LogCategory.功能开发;
|
||
private string customCategory = "";
|
||
private Vector2 scrollPosition;
|
||
private string savePath;
|
||
private string copyFeedback = ""; // 复制成功提示
|
||
private float feedbackTimer = 0; // 提示信息计时器
|
||
|
||
// 菜单栏打开窗口
|
||
[MenuItem("Tool/开发日志")]
|
||
public static void ShowWindow()
|
||
{
|
||
GetWindow<DevLoggerWindow>("开发日志", true);
|
||
GetWindow<DevLoggerWindow>().minSize = new Vector2(600, 400);
|
||
}
|
||
|
||
private void OnEnable()
|
||
{
|
||
// 初始化保存路径(项目根目录/DevLogs.json)
|
||
savePath = Path.Combine(Application.dataPath, "../DevLogs.json");
|
||
LoadLogs();
|
||
}
|
||
|
||
private void Update()
|
||
{
|
||
// 处理复制成功提示的显示时间
|
||
if (feedbackTimer > 0)
|
||
{
|
||
feedbackTimer -= Time.deltaTime;
|
||
if (feedbackTimer <= 0)
|
||
{
|
||
copyFeedback = "";
|
||
Repaint();
|
||
}
|
||
}
|
||
}
|
||
|
||
private void OnGUI()
|
||
{
|
||
// 显示复制成功提示
|
||
if (!string.IsNullOrEmpty(copyFeedback))
|
||
{
|
||
GUIStyle feedbackStyle = new GUIStyle(EditorStyles.helpBox);
|
||
feedbackStyle.normal.textColor = Color.green;
|
||
EditorGUILayout.LabelField(copyFeedback, feedbackStyle);
|
||
}
|
||
|
||
GUILayout.Label("添加新日志", EditorStyles.boldLabel);
|
||
|
||
// 分类选择
|
||
EditorGUILayout.BeginHorizontal();
|
||
GUILayout.Label("日志分类:", GUILayout.Width(80));
|
||
selectedCategory = (LogCategory)EditorGUILayout.EnumPopup(selectedCategory);
|
||
|
||
// 自定义分类输入框
|
||
if (selectedCategory == LogCategory.自定义)
|
||
{
|
||
customCategory = EditorGUILayout.TextField(customCategory);
|
||
}
|
||
|
||
EditorGUILayout.EndHorizontal();
|
||
|
||
// 输入新日志内容
|
||
newLogContent = EditorGUILayout.TextArea(newLogContent, GUILayout.Height(80));
|
||
|
||
// 完成状态选择
|
||
newLogCompleted = EditorGUILayout.Toggle("是否完成", newLogCompleted);
|
||
|
||
// 添加按钮
|
||
if (GUILayout.Button("添加日志"))
|
||
{
|
||
if (!string.IsNullOrEmpty(newLogContent.Trim()))
|
||
{
|
||
// 验证自定义分类
|
||
if (selectedCategory == LogCategory.自定义 && string.IsNullOrEmpty(customCategory.Trim()))
|
||
{
|
||
EditorUtility.DisplayDialog("提示", "请输入自定义分类名称", "确定");
|
||
return;
|
||
}
|
||
|
||
AddNewLogEntry();
|
||
newLogContent = ""; // 清空输入框
|
||
newLogCompleted = false;
|
||
}
|
||
else
|
||
{
|
||
EditorUtility.DisplayDialog("提示", "日志内容不能为空", "确定");
|
||
}
|
||
}
|
||
|
||
GUILayout.Space(20);
|
||
GUILayout.Label("历史日志", EditorStyles.boldLabel);
|
||
|
||
// 显示日志列表
|
||
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
|
||
|
||
// 按日期分组显示
|
||
string currentDate = "";
|
||
for (int i = logEntries.Count - 1; i >= 0; i--)
|
||
{
|
||
var entry = logEntries[i];
|
||
|
||
// 显示日期分组标题
|
||
if (entry.date != currentDate)
|
||
{
|
||
currentDate = entry.date;
|
||
GUILayout.Space(10);
|
||
GUILayout.Label(currentDate, EditorStyles.centeredGreyMiniLabel);
|
||
GUILayout.Space(5);
|
||
}
|
||
|
||
// 日志条目样式
|
||
EditorGUILayout.BeginHorizontal();
|
||
|
||
// 分类标签
|
||
GUIStyle categoryStyle = new GUIStyle(EditorStyles.miniButton)
|
||
{
|
||
fontSize = 10,
|
||
fixedWidth = 80,
|
||
alignment = TextAnchor.MiddleCenter
|
||
};
|
||
SetCategoryStyleColors(categoryStyle, entry.category);
|
||
GUILayout.Label(entry.category, categoryStyle);
|
||
|
||
// 完成状态标记
|
||
string statusLabel = entry.isCompleted ? "✓ 已完成" : "○ 进行中";
|
||
GUIStyle statusStyle = entry.isCompleted
|
||
? new GUIStyle(EditorStyles.label) { normal = { textColor = Color.green } }
|
||
: new GUIStyle(EditorStyles.label) { normal = { textColor = Color.yellow } };
|
||
|
||
EditorGUILayout.LabelField(statusLabel, statusStyle, GUILayout.Width(80));
|
||
|
||
// 日志内容
|
||
EditorGUILayout.LabelField(entry.content, GUILayout.ExpandWidth(true));
|
||
|
||
// 时间戳
|
||
EditorGUILayout.LabelField(entry.timestamp, EditorStyles.miniLabel, GUILayout.Width(80));
|
||
|
||
// 复制按钮
|
||
if (GUILayout.Button("复制", EditorStyles.miniButtonLeft, GUILayout.Width(50)))
|
||
{
|
||
CopyLogToClipboard(entry);
|
||
}
|
||
|
||
// 删除按钮
|
||
if (GUILayout.Button("删除", EditorStyles.miniButtonRight, GUILayout.Width(50)))
|
||
{
|
||
if (EditorUtility.DisplayDialog("确认", "确定要删除这条日志吗?", "是", "否"))
|
||
{
|
||
logEntries.RemoveAt(i);
|
||
SaveLogs();
|
||
}
|
||
}
|
||
|
||
EditorGUILayout.EndHorizontal();
|
||
GUILayout.Space(2);
|
||
}
|
||
|
||
EditorGUILayout.EndScrollView();
|
||
}
|
||
|
||
// 将日志内容复制到剪贴板(使用Unity内置方法)
|
||
private void CopyLogToClipboard(DevLogEntry entry)
|
||
{
|
||
try
|
||
{
|
||
// 格式化复制内容,包含完整信息
|
||
string formattedLog = $"{entry.date} {entry.timestamp} [{entry.category}] {entry.content} ({(entry.isCompleted ? "已完成" : "进行中")})";
|
||
|
||
// 使用Unity编辑器的剪贴板功能
|
||
EditorGUIUtility.systemCopyBuffer = formattedLog;
|
||
|
||
// 显示复制成功提示
|
||
copyFeedback = "日志内容已复制到剪贴板!";
|
||
feedbackTimer = 2f; // 显示2秒
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError("复制日志失败: " + e.Message);
|
||
copyFeedback = "复制失败: " + e.Message;
|
||
feedbackTimer = 3f;
|
||
}
|
||
}
|
||
|
||
// 设置分类标签的样式颜色
|
||
private void SetCategoryStyleColors(GUIStyle style, string category)
|
||
{
|
||
switch (category)
|
||
{
|
||
case "功能开发":
|
||
style.normal.textColor = Color.white;
|
||
style.normal.background = MakeTex(2, 2, new Color(0.2f, 0.4f, 0.8f, 0.8f));
|
||
break;
|
||
case "BUG修复":
|
||
style.normal.textColor = Color.white;
|
||
style.normal.background = MakeTex(2, 2, new Color(0.8f, 0.3f, 0.3f, 0.8f));
|
||
break;
|
||
case "优化改进":
|
||
style.normal.textColor = Color.white;
|
||
style.normal.background = MakeTex(2, 2, new Color(0.3f, 0.7f, 0.3f, 0.8f));
|
||
break;
|
||
case "文档编写":
|
||
style.normal.textColor = Color.white;
|
||
style.normal.background = MakeTex(2, 2, new Color(0.7f, 0.7f, 0.3f, 0.8f));
|
||
break;
|
||
case "测试验证":
|
||
style.normal.textColor = Color.white;
|
||
style.normal.background = MakeTex(2, 2, new Color(0.6f, 0.3f, 0.8f, 0.8f));
|
||
break;
|
||
case "会议讨论":
|
||
style.normal.textColor = Color.white;
|
||
style.normal.background = MakeTex(2, 2, new Color(0.8f, 0.5f, 0.2f, 0.8f));
|
||
break;
|
||
default: // 自定义分类
|
||
style.normal.textColor = Color.white;
|
||
style.normal.background = MakeTex(2, 2, new Color(0.6f, 0.6f, 0.6f, 0.8f));
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 创建简单的纹理用于GUI样式
|
||
private Texture2D MakeTex(int width, int height, Color col)
|
||
{
|
||
Color[] pix = new Color[width * height];
|
||
for (int i = 0; i < pix.Length; i++)
|
||
pix[i] = col;
|
||
Texture2D result = new Texture2D(width, height);
|
||
result.SetPixels(pix);
|
||
result.Apply();
|
||
return result;
|
||
}
|
||
|
||
// 添加新日志条目
|
||
private void AddNewLogEntry()
|
||
{
|
||
string category = selectedCategory.ToString();
|
||
if (selectedCategory == LogCategory.自定义)
|
||
{
|
||
category = customCategory.Trim();
|
||
}
|
||
|
||
var newEntry = new DevLogEntry
|
||
{
|
||
timestamp = DateTime.Now.ToString("HH:mm:ss"),
|
||
date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||
content = newLogContent,
|
||
isCompleted = newLogCompleted,
|
||
category = category
|
||
};
|
||
|
||
logEntries.Add(newEntry);
|
||
SaveLogs();
|
||
}
|
||
|
||
// 保存日志到文件
|
||
private void SaveLogs()
|
||
{
|
||
try
|
||
{
|
||
string json = JsonUtility.ToJson(new LogWrapper { entries = logEntries }, true);
|
||
File.WriteAllText(savePath, json);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError("保存日志失败: " + e.Message);
|
||
}
|
||
}
|
||
|
||
// 从文件加载日志
|
||
private void LoadLogs()
|
||
{
|
||
try
|
||
{
|
||
if (File.Exists(savePath))
|
||
{
|
||
string json = File.ReadAllText(savePath);
|
||
LogWrapper wrapper = JsonUtility.FromJson<LogWrapper>(json);
|
||
if (wrapper != null && wrapper.entries != null)
|
||
{
|
||
logEntries = wrapper.entries;
|
||
}
|
||
}
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError("加载日志失败: " + e.Message);
|
||
logEntries = new List<DevLogEntry>();
|
||
}
|
||
}
|
||
|
||
// 用于JSON序列化的包装类
|
||
[Serializable]
|
||
private class LogWrapper
|
||
{
|
||
public List<DevLogEntry> entries;
|
||
}
|
||
}
|
||
}
|
||
|