MeowmentDebugTool/Packages/com.bywaystudios.meowmentdebugtool/BUGFIX_REBUILD_LOOP.md
2025-12-22 15:29:55 +08:00

216 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Console模块错误修复说明
## 🐛 已修复的问题
### 1. Rebuild Loop 错误
**问题描述**:
```
Trying to remove/add Background (UnityEngine.UI.Image) from/to rebuild list
while we are already inside a rebuild loop. This is not supported.
```
**原因**:
-`OnLogMessageReceived` 回调中立即调用 `RefreshLogDisplay()` 刷新UI
- 在Unity的Canvas rebuild循环中修改UI元素会触发此错误
- `Canvas.ForceUpdateCanvases()` 在初始化时也会导致rebuild loop
**修复方案**:
#### ConsoleModule.cs
1.**延迟刷新机制**: 添加 `needRefresh` 标志不在回调中立即刷新UI
```csharp
private bool needRefresh = false;
// 在OnLogMessageReceived中
needRefresh = true; // 标记需要刷新
// 在Update中
if (needRefresh)
{
needRefresh = false;
RefreshLogDisplay(); // 延迟到下一帧刷新
}
```
2.**滚动位置延迟设置**: 使用帧计数延迟设置滚动位置
```csharp
private int lastRefreshFrame = -1;
// 只在刷新后的第2帧设置滚动位置
if (lockScroll && Time.frameCount > lastRefreshFrame + 1)
{
logScrollRect.verticalNormalizedPosition = 0f;
}
```
3.**过滤器事件优化**: 过滤器改变时也使用延迟刷新
```csharp
private void OnInfoFilterChanged(bool value)
{
infoFilter = value;
needRefresh = true; // 而不是立即RefreshLogDisplay()
}
```
#### SettingsModule.cs
4.**移除ForceUpdateCanvases**: Canvas会自动在下一帧更新
```csharp
private void ApplyResolution(Vector2 resolution)
{
mainWindow.sizeDelta = resolution;
currentResolutionText.text = $"当前窗口尺寸: {resolution.x} x {resolution.y}";
// 移除了 Canvas.ForceUpdateCanvases();
// Canvas会自动更新不需要强制刷新
}
```
### 2. 中文字体警告
**问题描述**:
```
The character with Unicode value \u5F84 was not found in the [LiberationSans SDF]
font asset or any potential fallbacks.
```
**原因**:
- RuntimeUIGenerator使用的默认字体 `LiberationSans SDF` 不支持中文字符
- TextMeshPro需要专门的中文字体资源
**解决方案** (选择其一):
#### 方案1: 使用中文字体 (推荐)
```csharp
// 在游戏初始化时设置中文字体
UniversalDebugTool.Init();
// 加载支持中文的TMP字体
TMP_FontAsset chineseFont = Resources.Load<TMP_FontAsset>("Fonts/ChineseFont SDF");
UniversalDebugTool.SetSDFFont(chineseFont);
```
#### 方案2: 禁用字体警告
在RuntimeUIGenerator的GetDefaultFont方法中添加过滤
```csharp
private static TMP_FontAsset GetDefaultFont()
{
// 禁用TMP字体警告
TMPro.TMP_Settings.warningsDisabled = true;
// 查找默认字体...
}
```
#### 方案3: 创建中文字体资源
1. 在Unity中Window > TextMeshPro > Font Asset Creator
2. 选择支持中文的字体如Arial Unicode MS、Microsoft YaHei等
3. 设置Character Set为Unicode或Custom Characters
4. 添加常用中文字符
5. 生成字体资源并在代码中加载
## 📋 修改总结
### 文件变更
#### ConsoleModule.cs
- ✅ 添加 `needRefresh` 标志
- ✅ 添加 `lastRefreshFrame` 帧计数
- ✅ 修改 `OnLogMessageReceived` 使用延迟刷新
- ✅ 修改 `Update` 方法处理延迟刷新和滚动
- ✅ 修改所有过滤器事件使用延迟刷新
#### SettingsModule.cs
- ✅ 移除 `Canvas.ForceUpdateCanvases()` 调用
### 性能影响
**更好**: 延迟刷新减少了不必要的UI重建
**更稳定**: 避免了rebuild loop错误
**无副作用**: 延迟一帧刷新对用户体验无影响
## 🧪 测试建议
### 1. 测试Rebuild Loop修复
```csharp
void Start()
{
UniversalDebugTool.Init();
// 快速生成大量日志
for (int i = 0; i < 100; i++)
{
Debug.Log($"测试日志 {i}");
Debug.LogWarning($"警告 {i}");
Debug.LogError($"错误 {i}");
}
// 不应该再有rebuild loop错误
}
```
### 2. 测试滚动功能
```csharp
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log($"新日志 - 帧数: {Time.frameCount}");
// 应该自动滚动到底部(如果锁定滚动已启用)
}
}
```
### 3. 测试过滤器
1. 生成多种类型的日志
2. 点击Console标签页
3. 切换Info/Warning/Error/Fatal过滤器
4. 不应该有rebuild loop错误
### 4. 测试分辨率设置
1. 进入Settings标签页
2. 修改宽度和高度
3. 点击"应用"按钮
4. 不应该有rebuild loop错误
## ⚠️ 注意事项
### 关于中文字体
如果你的游戏需要显示中文,必须:
1. 创建或导入支持中文的TMP字体资源
2. 在初始化后调用 `UniversalDebugTool.SetSDFFont(yourChineseFont)`
3. 或者在RuntimeUIGenerator中修改GetDefaultFont方法返回中文字体
### 最佳实践
```csharp
public class GameInit : MonoBehaviour
{
[SerializeField] private TMP_FontAsset chineseFont;
void Start()
{
// 1. 初始化调试工具
UniversalDebugTool.Init();
// 2. 设置中文字体(如果需要)
if (chineseFont != null)
{
UniversalDebugTool.SetSDFFont(chineseFont);
}
// 3. 其他初始化...
}
}
```
## ✅ 预期结果
修复后,你应该看到:
- ✅ 没有 "Trying to remove/add ... from/to rebuild list" 错误
- ✅ Console正常显示日志
- ✅ 过滤器正常工作
- ✅ 滚动功能正常
- ⚠️ 可能仍有字体警告(如果没有设置中文字体)
字体警告不影响功能,只是文本显示为方块。如果需要中文显示,请按照上述方案添加中文字体。