AI补足注释(已经快看不懂了)

实现i18n
优化部分模块的逻辑以优化性能
修复物品展示框打开时按下ESC唤出暂停菜单但没有暂停的bug

Signed-off-by: Eicy <im@crash.work>
This commit is contained in:
2024-10-14 21:37:04 +08:00
parent 3a74806d8c
commit c9d29f2a68
28 changed files with 1244 additions and 476 deletions

View File

@@ -7,27 +7,37 @@ using UnityEngine.UI;
namespace Dialog
{
// 处理对话框的显示与输入效果
public class BoxDialog : MonoBehaviour
{
public float typingSpeed = 0.05f;
public string introduceText;
private string _currentText = "";
private float _timer;
private int _currentIndex;
private bool _start;
public TMP_Text textMeshPro;
public float printTime;
public float maxPrintTime = 10;
public bool isTime2Break;
private string _eventToBeExc;
private string _eventArg;
[SerializeField] private GameObject dialogBox;
[SerializeField] private RawImage head;
[SerializeField] private RawImage face;
[Header("Typing Settings")]
[Tooltip("每个字符之间的打字速度")]
public float typingSpeed = 0.05f; // 打字速度
[Tooltip("对话内容")]
public string introduceText; // 要显示的文本内容
private string _currentText = ""; // 当前显示的文本
private float _timer; // 计时器,用于控制打字速度
private int _currentIndex; // 当前字符的索引
private bool _start; // 控制打字过程的标志
public TMP_Text textMeshPro; // 用于显示文本的TMP组件
public float printTime; // 用于计时对话框的显示时间
public float maxPrintTime = 10; // 最大显示时间
public bool isTime2Break; // 是否达到关闭对话框的时间
private string _eventToBeExc; // 要执行的事件
private string _eventArg; // 事件参数
[SerializeField] private GameObject dialogBox; // 对话框对象
[SerializeField] private RawImage head; // 角色头像
[SerializeField] private RawImage face; // 角色表情
private void Update()
{
// 如果对话未开始,直接返回
if (!_start) return;
// 计时对话框的显示时间
printTime += Time.deltaTime;
if (printTime > maxPrintTime)
{
@@ -35,68 +45,85 @@ namespace Dialog
StartCoroutine(Delay());
}
// 判断是否达到关闭条件
Time2Break();
if (_currentText == introduceText)
{
return;
}
// 如果当前文本已全部显示,直接返回
if (_currentText == introduceText) return;
// 控制打字效果
_timer += Time.deltaTime;
if (!(_timer >= typingSpeed)) return;
_timer = 0f;
if (_timer < typingSpeed) return; // 控制打字速度
_timer = 0f; // 重置计时器
// 显示下一个字符
_currentText += introduceText[_currentIndex];
textMeshPro.text = _currentText;
_currentIndex++;
textMeshPro.text = _currentText; // 更新显示文本
_currentIndex++; // 移动到下一个字符
}
// 沟槽的生命周期
// 控制事件的延迟执行
private IEnumerator Delay()
{
yield return new WaitForSeconds(0.5f);
EventManager.Instance.EventSwitch(_eventToBeExc, _eventArg);
EventManager.Instance.EventSwitch(_eventToBeExc, _eventArg); // 执行事件
}
private void OnEnable()
{
// 订阅对话弹出事件
EventManager.Instance.DialogPop += StartPrinting;
}
private void OnDisable()
{
// 取消订阅对话弹出事件
EventManager.Instance.DialogPop -= StartPrinting;
}
// 判断是否达到关闭对话框的条件
private void Time2Break()
{
if (!isTime2Break) return;
_start = false;
printTime = 0;
isTime2Break = false;
textMeshPro.text = "";
dialogBox.SetActive(false);
_start = false; // 停止打字过程
printTime = 0; // 重置计时
isTime2Break = false; // 重置状态
textMeshPro.text = ""; // 清空文本
dialogBox.SetActive(false); // 隐藏对话框
}
// 开始打印对话内容
private void StartPrinting(DialogPopArgs e)
{
// 检查对话框类型是否为"box"
if (!DialogManager.Instance.GetDialogByIndex(e.Index).Type.Equals("box")) return;
if (printTime != 0) return;
if (printTime != 0) return; // 防止重复打开
// 显示对话框
dialogBox.SetActive(true);
_start = true;
_currentText = "";
introduceText = DialogManager.Instance.GetDialogByIndex(e.Index).Content;
_start = true; // 开始打字
_currentText = ""; // 清空当前文本
introduceText = DialogManager.Instance.GetDialogByIndex(e.Index).Content; // 获取对话内容
// 获取并存储事件信息
_eventToBeExc = DialogManager.Instance.GetDialogByIndex(e.Index).DialogEvent;
_eventArg = DialogManager.Instance.GetDialogByIndex(e.Index).DialogEventArg;
head.texture = Resources.Load<Texture2D>("Character/Head" + "/" +
DialogManager.Instance.GetDialogByIndex(e.Index).Character +
"_Head");
face.texture = Resources.Load<Texture2D>("Character/Face" + "/" +
DialogManager.Instance.GetDialogByIndex(e.Index).Character + "_" +
DialogManager.Instance.GetDialogByIndex(e.Index).Animation +
"_Face");
_currentIndex = 0;
_timer = 0f;
textMeshPro.fontSize = 80;
// 加载角色头像和表情
LoadCharacterGraphics(e.Index);
// 初始化状态
_currentIndex = 0; // 重置索引
_timer = 0f; // 重置计时器
textMeshPro.fontSize = 80; // 设置字体大小
}
// 加载角色的头像和表情
private void LoadCharacterGraphics(int dialogIndex)
{
var dialog = DialogManager.Instance.GetDialogByIndex(dialogIndex);
head.texture = Resources.Load<Texture2D>("Character/Head/" + dialog.Character + "_Head");
face.texture = Resources.Load<Texture2D>("Character/Face/" + dialog.Character + "_" + dialog.Animation + "_Face");
}
}
}
}

View File

@@ -1,21 +1,21 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Localization;
namespace Dialog
{
// 对话类,包含对话的相关信息
public class Dialog
{
public readonly int Index;
public readonly string Content;
public readonly string Type;
public readonly string Animation;
public readonly string Character;
public readonly string DialogEvent;
public readonly string DialogEventArg;
public readonly int Index; // 对话索引
public string Content; // 对话内容(会被本地化处理)
public readonly string Type; // 对话类型
public readonly string Animation; // 动画效果
public readonly string Character; // 角色名称
public readonly string DialogEvent; // 对话事件
public readonly string DialogEventArg; // 对话事件参数
public Dialog(int index, string content, string type, string animation, string character, string dialogEvent,
string dialogEventArg)
public Dialog(int index, string content, string type, string animation, string character, string dialogEvent, string dialogEventArg)
{
Index = index;
Content = content;
@@ -27,10 +27,11 @@ namespace Dialog
}
}
// 物品文本类,包含物品的名称和描述
public class ItemText
{
public readonly string Name;
public readonly string Description;
public string Name; // 物品名称
public string Description; // 物品描述
public ItemText(string name, string description)
{
@@ -38,60 +39,52 @@ namespace Dialog
Description = description;
}
}
// 对话管理器,负责加载和管理对话和物品文本
public class DialogManager : MonoBehaviour
{
private readonly List<Dialog> _dialog = new();
private readonly List<ItemText> _itemTexts = new();
// 存储对话和物品文本的字典
private readonly Dictionary<int, Dialog> _dialogDictionary = new();
private readonly Dictionary<string, ItemText> _itemTextDictionary = new();
private static DialogManager _instance;
public static DialogManager Instance
{
get
{
if (_instance)
return _instance;
_instance = FindFirstObjectByType<DialogManager>() ??
new GameObject("DialogData").AddComponent<DialogManager>();
// 确保只存在一个对话管理器实例
if (_instance != null) return _instance;
_instance = FindFirstObjectByType<DialogManager>() ??
new GameObject("DialogManager").AddComponent<DialogManager>();
return _instance;
}
}
private void Awake()
{
// 初始化对话管理器
if (_instance != null && _instance != this)
{
Destroy(gameObject);
Destroy(gameObject); // 如果已存在,则销毁当前对象
}
else
{
LoadCsv("Dialog/DialogData");
LoadItemTexts("Dialog/ItemText");
_instance = this;
DontDestroyOnLoad(gameObject); // 保持在场景切换中不销毁
LoadData("Dialog/DialogData", DataType.Dialog); // 加载对话数据
LoadData("Dialog/ItemText", DataType.ItemText); // 加载物品文本数据
}
}
private void LoadItemTexts(string resourcePath)
// 数据类型枚举,用于区分加载的数据类型
private enum DataType
{
var texts = Resources.Load<TextAsset>(resourcePath);
if (texts == null)
{
Debug.LogError($"Unable to find CSV file at path: {resourcePath}");
return;
}
var lines = texts.text.Split('\n');
for (var i = 1; i < lines.Length; i++)
{
var values = lines[i].Split(',');
if (values.Length < 2) continue;
var text = new ItemText(
values[0],
values[1]
);
_itemTexts.Add(text);
}
Dialog,
ItemText
}
private void LoadCsv(string resourcePath)
// 加载指定路径的数据
private void LoadData(string resourcePath, DataType dataType)
{
var textAsset = Resources.Load<TextAsset>(resourcePath);
if (textAsset == null)
@@ -100,44 +93,65 @@ namespace Dialog
return;
}
// 按行读取文本
var lines = textAsset.text.Split('\n');
for (var i = 1; i < lines.Length; i++)
{
var values = lines[i].Split(',');
if (values.Length < 7) continue;
var dialog = new Dialog(
int.Parse(values[0]),
values[1],
values[2],
values[3],
values[4],
values[5],
values[6]
);
switch (dataType)
{
case DataType.Dialog:
// 加载对话数据
if (values.Length < 7) continue; // 检查字段数量
var dialog = new Dialog(
int.Parse(values[0].Trim()),
values[1].Trim(),
values[2].Trim(),
values[3].Trim(),
values[4].Trim(),
values[5].Trim(),
values[6].Trim()
);
_dialogDictionary[dialog.Index] = dialog; // 添加到字典
dialog.Content = LocalizationManager.Instance.GetLocalizedValue(dialog.Content); // 本地化对话内容
break;
_dialog.Add(dialog);
case DataType.ItemText:
// 加载物品文本数据
if (values.Length < 2) continue; // 检查字段数量
var itemNameKey = values[0].Trim();
var itemDescriptionKey = values[1].Trim();
var itemText = new ItemText(itemNameKey, itemDescriptionKey);
_itemTextDictionary[itemNameKey] = itemText; // 添加到字典
itemText.Name = LocalizationManager.Instance.GetLocalizedValue(itemText.Name); // 本地化物品名称
itemText.Description = LocalizationManager.Instance.GetLocalizedValue(itemText.Description); // 本地化物品描述
break;
}
}
}
// 根据索引获取对话
public Dialog GetDialogByIndex(int index)
{
foreach (var dialog in _dialog.Where(dialogue => dialogue.Index == index))
if (_dialogDictionary.TryGetValue(index, out var dialog))
{
return dialog;
return dialog; // 返回找到的对话
}
Debug.LogWarning($"Dialog with index {index} not found.");
return null;
return null; // 如果未找到则返回 null
}
public ItemText GetItemText(string nName)
// 根据名称获取物品文本
public ItemText GetItemText(string name)
{
foreach (var text in _itemTexts.Where(text => text.Name == nName))
if (_itemTextDictionary.TryGetValue(name, out var itemText))
{
return text;
return itemText; // 返回找到的物品文本
}
Debug.LogWarning($"Dialog with name {nName} not found.");
return null;
Debug.LogWarning($"ItemText with name {name} not found.");
return null; // 如果未找到则返回 null
}
}
}
}

View File

@@ -6,39 +6,66 @@ using UnityEngine.UI;
namespace Dialog
{
// 物体展示框类,用于显示物品的详细信息(图标、名称、描述)
public class ItemDialog : MonoBehaviour
{
public RawImage itemIcon;
public TMP_Text itemName;
public TMP_Text itemDescription;
public GameObject panel;
private string _itemName;
public RawImage itemIcon; // 物体图标
public TMP_Text itemName; // 物体名称文本
public TMP_Text itemDescription; // 物体描述文本
public GameObject panel; // 物体展示框的UI面板
// 事件订阅
private void OnEnable()
{
EventManager.Instance.ItemDialog+=DialogPop;
EventManager.Instance.ItemDialog += DialogPop;
}
// 取消订阅事件
private void OnDisable()
{
EventManager.Instance.ItemDialog-=DialogPop;
}
private void DialogPop(ItemDialogArgs itemDialogArgs)
{
var itemText = DialogManager.Instance.GetItemText(itemDialogArgs.ItemName);
Debug.Log("ItemDialog");
if (itemText is null) return;
panel.SetActive(true);
itemIcon.texture = Resources.Load<Texture2D>("Item" + "/" + itemText.Name);
itemName.text = itemText.Name;
itemDescription.text = itemText.Description;
Time.timeScale = 0;
EventManager.Instance.ItemDialog -= DialogPop;
}
// 物体展示框弹出,接收物体对话参数
private void DialogPop(ItemDialogArgs itemDialogArgs)
{
// 从DialogManager尝试获取物体文本信息
var itemText = DialogManager.Instance.GetItemText(itemDialogArgs.ItemName);
// 如果没有找到对应的物体文本,直接返回
if (itemText == null) return;
// 显示物体展示框
panel.SetActive(true);
// 加载物体图标并更新UI文本
LoadItemIcon(itemText.Name);
UpdateItemText(itemText);
// 暂停游戏时间
Time.timeScale = 0;
}
// 加载物体图标
private void LoadItemIcon(string itemName)
{
string iconPath = $"Item/{itemName}"; // 更灵活的图标路径
itemIcon.texture = Resources.Load<Texture2D>(iconPath);
}
// 更新物体的名称和描述文本
private void UpdateItemText(ItemText itemText)
{
itemName.text = itemText.Name;
itemDescription.text = itemText.Description;
}
//todo
private void Update()
{
if ((!panel.activeSelf || !Input.GetKeyDown(KeyCode.Escape)) && Time.timeScale == 0 ) return;
// 检测是否关闭物体展示框
if ((!panel.activeSelf || !Input.GetKeyDown(KeyCode.Escape)) && Time.timeScale == 0) return;
// 恢复游戏时间并隐藏展示框
Time.timeScale = 1;
panel.SetActive(false);
}

View File

@@ -6,25 +6,36 @@ using UnityEngine;
namespace Dialog
{
// 处理屏幕对话框的显示与输入效果
public class ScreenDialog : MonoBehaviour
{
public float typingSpeed = 0.05f;
public string introduceText;
private string _currentText = "";
private float _timer;
private int _currentIndex;
private bool _start;
private bool _isBlinking;
public TMP_Text textMeshPro;
public float printTime;
public float maxPrintTime = 10;
public bool isTime2Break;
private string _eventToBeExc;
private string _eventArg;
[Header("Typing Settings")]
[Tooltip("每个字符之间的打字速度")]
public float typingSpeed = 0.05f; // 打字速度
[Tooltip("对话内容")]
public string introduceText; // 要显示的文本内容
private string _currentText = ""; // 当前显示的文本
private float _timer; // 计时器,用于控制打字速度
private int _currentIndex; // 当前字符的索引
private bool _start; // 控制打字过程的标志
private bool _isBlinking; // 控制光标闪烁的标志
public TMP_Text textMeshPro; // 用于显示文本的TMP组件
public float printTime; // 用于计时对话框的显示时间
public float maxPrintTime = 10; // 最大显示时间
public bool isTime2Break; // 是否达到关闭对话框的时间
private string _eventToBeExc; // 要执行的事件
private string _eventArg; // 事件参数
private void Update()
{
// 如果对话未开始,直接返回
if (!_start) return;
// 计时对话框的显示时间
printTime += Time.deltaTime;
if (printTime > maxPrintTime)
{
@@ -32,78 +43,94 @@ namespace Dialog
StartCoroutine(Delay());
}
if (_currentText == introduceText)
{
return;
}
// 如果当前文本已全部显示,直接返回
if (_currentText == introduceText) return;
// 控制打字效果
_timer += Time.deltaTime;
if (!(_timer >= typingSpeed)) return;
_timer = 0f;
if (_timer < typingSpeed) return; // 控制打字速度
_timer = 0f; // 重置计时器
// 显示下一个字符
_currentText += introduceText[_currentIndex];
textMeshPro.text = _currentText;
_currentIndex++;
textMeshPro.text = _currentText; // 更新显示文本
_currentIndex++; // 移动到下一个字符
}
// 沟槽的生命周期
// 控制事件的延迟执行
private IEnumerator Delay()
{
yield return new WaitForSeconds(1f);
EventManager.Instance.EventSwitch(_eventToBeExc, _eventArg);
yield return new WaitForSeconds(1f); // 等待1秒后执行
EventManager.Instance.EventSwitch(_eventToBeExc, _eventArg); // 执行事件
}
private void OnEnable()
{
// 订阅对话弹出事件
EventManager.Instance.DialogPop += StartPrinting;
}
private void OnDisable()
{
// 取消订阅对话弹出事件
EventManager.Instance.DialogPop -= StartPrinting;
}
// 光标闪烁协程
private IEnumerator BlinkCursor()
{
while (true)
{
// 如果达到关闭条件,停止闪烁并重置文本
if (isTime2Break)
{
_start = false;
printTime = 0;
isTime2Break = false;
textMeshPro.fontSize = 48.7f;
textMeshPro.text = "+";
break;
_start = false; // 停止打字过程
printTime = 0; // 重置计时
isTime2Break = false; // 重置状态
textMeshPro.fontSize = 48.7f; // 设置字体大小
textMeshPro.text = "+"; // 显示结束标志
break; // 退出循环
}
// 切换光标状态
if (!_isBlinking)
{
textMeshPro.text += "|";
_isBlinking = true;
textMeshPro.text += "|"; // 添加光标
_isBlinking = true; // 设置闪烁状态
}
else
{
textMeshPro.text = textMeshPro.text[..^1];
_isBlinking = false;
textMeshPro.text = textMeshPro.text[..^1]; // 移除光标
_isBlinking = false; // 设置非闪烁状态
}
yield return new WaitForSeconds(0.3f);
yield return new WaitForSeconds(0.3f); // 等待0.3秒
}
}
// 开始打印对话内容
private void StartPrinting(DialogPopArgs e)
{
// 检查对话框类型是否为"screen"
if (!DialogManager.Instance.GetDialogByIndex(e.Index).Type.Equals("screen")) return;
if (printTime != 0) return;
if (printTime != 0) return; // 防止重复打开
// 开始打字过程
_start = true;
_currentText = "";
introduceText = DialogManager.Instance.GetDialogByIndex(e.Index).Content;
_currentText = ""; // 清空当前文本
introduceText = DialogManager.Instance.GetDialogByIndex(e.Index).Content; // 获取对话内容
// 获取并存储事件信息
_eventToBeExc = DialogManager.Instance.GetDialogByIndex(e.Index).DialogEvent;
_eventArg = DialogManager.Instance.GetDialogByIndex(e.Index).DialogEventArg;
_currentIndex = 0;
_timer = 0f;
textMeshPro.fontSize = 80;
// 初始化状态
_currentIndex = 0; // 重置索引
_timer = 0f; // 重置计时器
textMeshPro.fontSize = 80; // 设置字体大小
// 启动光标闪烁协程
StartCoroutine(BlinkCursor());
}
}
}
}