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

File diff suppressed because one or more lines are too long

View File

@@ -1,3 +1,3 @@
index,content,type,animation,character,event,arg
0,我会一直视奸你..,screen,typeing,,OnDialogPop,1
1,永远..永远…,box,Idle,Test,,
0,dialog.typing.0,screen,typeing,,OnDialogPop,1
1,dialog.box.1,box,Idle,Test,,
1 index content type animation character event arg
2 0 我会一直视奸你.. dialog.typing.0 screen typeing OnDialogPop 1
3 1 永远..永远… dialog.box.1 box Idle Test

View File

@@ -1,2 +1,2 @@
name,description
Cube,只是一个方块。
item.name.cube,item.description.cube
1 name description
2 Cube item.name.cube 只是一个方块。 item.description.cube

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6d11d94775f774f4fb82bfa947139e90
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,4 @@
item.name.cube=方块
item.description.cube=只是一个方块。
dialog.typing.0=我会一直视奸你..
dialog.box.1=永远..永远…

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 75a836a9d560014499f611d03e575526
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -475,6 +475,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
index: 1
itemNameKey:
--- !u!1 &143509929
GameObject:
m_ObjectHideFlags: 0
@@ -812,6 +813,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
index: 0
itemNameKey: item.name.cube
--- !u!54 &183733062
Rigidbody:
m_ObjectHideFlags: 0
@@ -839,6 +841,52 @@ Rigidbody:
m_Interpolate: 0
m_Constraints: 0
m_CollisionDetection: 0
--- !u!1 &365932366
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 365932367}
- component: {fileID: 365932368}
m_Layer: 0
m_Name: LanguageManager
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &365932367
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 365932366}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 9.623426, y: 1.8037834, z: -4.2049627}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &365932368
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 365932366}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 37147edcf20d8924c83c6224d801d5c8, type: 3}
m_Name:
m_EditorClassIdentifier:
languageMap: []
defaultLanguage: 1
--- !u!1 &601447515
GameObject:
m_ObjectHideFlags: 0
@@ -3477,3 +3525,4 @@ SceneRoots:
- {fileID: 2138876384}
- {fileID: 127902485}
- {fileID: 1306517523}
- {fileID: 365932367}

View File

@@ -2,27 +2,35 @@
namespace Camera
{
// 控制摄像机的类
public class CameraController : MonoBehaviour
{
public float mouseSensitivity = 100.0f;
public Transform playerBody;
[Header("Camera Settings")]
public float mouseSensitivity = 100.0f; // 鼠标灵敏度
public Transform playerBody; // 玩家身体的 Transform 组件
private float _xRotation;
private float _xRotation; // 摄像机的上下旋转角度
private void Start()
{
// 锁定鼠标光标到屏幕中心
Cursor.lockState = CursorLockMode.Locked;
}
private void Update()
{
// 获取鼠标的水平和垂直移动值
var mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
var mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
// 更新垂直旋转值并限制在 -90 到 90 度之间
_xRotation -= mouseY;
_xRotation = Mathf.Clamp(_xRotation, -90f, 90f);
// 应用旋转到摄像机
transform.localRotation = Quaternion.Euler(_xRotation, 0f, 0f);
// 旋转玩家身体
playerBody.Rotate(Vector3.up * mouseX);
}
}

View File

@@ -4,21 +4,27 @@ using UnityEngine;
namespace Camera
{
// 处理摄像机与可交互物体的交互
public class CameraInterAct : MonoBehaviour
{
[SerializeField] private int maxInterActDistance = 10;
[SerializeField] private GameObject target;
[Header("Interaction Settings")]
[SerializeField] private int maxInterActDistance = 10; // 最大交互距离
private void Update()
{
Physics.Raycast(transform.position, transform.forward, out var raycastHit, maxInterActDistance);
if (raycastHit.collider && Input.GetKeyDown(KeySettingManager.Instance.GetKey("InterAct")))
// 执行射线检测
if (!Physics.Raycast(transform.position, transform.forward, out var raycastHit,
maxInterActDistance)) return;
// 检测到碰撞体并按下交互键
if (Input.GetKeyDown(KeySettingManager.Instance.GetKey("InterAct")))
{
EventManager.Instance.OnCameraInterAct(raycastHit.collider.gameObject);
}
}
private void OnDrawGizmos()
{
// 在场景视图中绘制射线,便于调试
Gizmos.color = Color.green;
Gizmos.DrawLine(transform.position, transform.position + transform.forward * maxInterActDistance);
}

View File

@@ -4,38 +4,52 @@ using UnityEngine.Rendering.PostProcessing;
namespace Camera
{
// 处理相机的后期处理效果
public class CameraPostProcessing : MonoBehaviour
{
private UnityEngine.Camera _camera;
private PostProcessVolume _processVolume;
private UnityEngine.Camera _camera; // 参考相机组件
private PostProcessVolume _processVolume; // 后期处理体积
private void Awake()
{
// 获取相机和后期处理组件
_camera = GetComponent<UnityEngine.Camera>();
_processVolume = GetComponent<PostProcessVolume>();
}
private void OnEnable()
{
EventManager.Instance.PlayerRunning += PostProcess;
EventManager.Instance.PlayerRunStop += ProcessingStop;
// 订阅事件
EventManager.Instance.PlayerRunning += PostProcess; // 玩家开始跑步时激活后期处理效果
EventManager.Instance.PlayerRunStop += ProcessingStop; // 玩家停止跑步时禁用后期处理效果
}
private void OnDisable()
{
// 取消订阅事件
EventManager.Instance.PlayerRunning -= PostProcess;
EventManager.Instance.PlayerRunStop -= ProcessingStop;
}
// 启动后期处理效果
private void PostProcess()
{
// 插值设置相机视野
_camera.fieldOfView = Mathf.Lerp(_camera.fieldOfView, 90f, Time.deltaTime * 10f);
_processVolume.profile.GetSetting<ChromaticAberration>().intensity.value = Mathf.Lerp(
_processVolume.profile.GetSetting<ChromaticAberration>().intensity.value, 1f, Time.deltaTime * 10f);
// 插值设置色差强度
var chromaticAberration = _processVolume.profile.GetSetting<ChromaticAberration>();
chromaticAberration.intensity.value = Mathf.Lerp(chromaticAberration.intensity.value, 1f, Time.deltaTime * 10f);
}
// 停止后期处理效果
private void ProcessingStop()
{
_processVolume.profile.GetSetting<ChromaticAberration>().intensity.value = Mathf.Lerp(
_processVolume.profile.GetSetting<ChromaticAberration>().intensity.value, 0f, Time.deltaTime * 10f);
// 插值设置色差强度归零
var chromaticAberration = _processVolume.profile.GetSetting<ChromaticAberration>();
chromaticAberration.intensity.value = Mathf.Lerp(chromaticAberration.intensity.value, 0f, Time.deltaTime * 10f);
// 插值设置相机视野回到默认值
_camera.fieldOfView = Mathf.Lerp(_camera.fieldOfView, 60f, Time.deltaTime * 10f);
}
}

View File

@@ -3,78 +3,99 @@ using UnityEngine;
namespace Camera
{
// 处理相机的震动效果
public class CameraShake : MonoBehaviour
{
public Transform cameraTransform;
public float amplitude = 0.05f;
public float frequency = 10.0f;
[Header("Camera Settings")]
[Tooltip("相机抖动的Transform。")]
public Transform cameraTransform; // 相机的变换组件
private Vector3 _originalPos;
private bool _isRunning;
private bool _isWalking;
[Header("抖动参数")]
[Tooltip("抖动效果的振幅。")]
public float amplitude = 0.05f; // 震动幅度
[Tooltip("抖动效果的频率。")]
public float frequency = 10.0f; // 震动频率
private Vector3 _originalPos; // 相机的初始位置
private bool _isRunning; // 玩家是否在奔跑
private bool _isWalking; // 玩家是否在行走
private void Start()
{
// 存储相机的初始位置
_originalPos = cameraTransform.localPosition;
}
private void OnEnable()
{
EventManager.Instance.PlayerRunning += OnPlayerRunning;
EventManager.Instance.PlayerRunStop += StopRunning;
EventManager.Instance.PlayerWalking += OnPlayerWalking;
EventManager.Instance.PlayerWalkStop += StopWalking;
// 订阅事件
EventManager.Instance.PlayerRunning += OnPlayerRunning; // 玩家开始奔跑事件
EventManager.Instance.PlayerRunStop += StopRunning; // 玩家停止奔跑事件
EventManager.Instance.PlayerWalking += OnPlayerWalking; // 玩家开始行走事件
EventManager.Instance.PlayerWalkStop += StopWalking; // 玩家停止行走事件
}
private void OnDisable()
{
// 取消订阅事件
EventManager.Instance.PlayerRunning -= OnPlayerRunning;
EventManager.Instance.PlayerRunStop -= StopRunning;
EventManager.Instance.PlayerWalking -= OnPlayerWalking;
EventManager.Instance.PlayerWalkStop -= StopWalking;
}
// 玩家开始奔跑时调用
private void OnPlayerRunning()
{
_isRunning = true;
_isRunning = true; // 设置奔跑状态
}
// 玩家开始行走时调用
private void OnPlayerWalking()
{
_isWalking = true;
_isWalking = true; // 设置行走状态
}
// 停止奔跑时调用
private void StopRunning()
{
_isRunning = false;
_isRunning = false; // 重置奔跑状态
}
// 停止行走时调用
private void StopWalking()
{
_isWalking = false;
_isWalking = false; // 重置行走状态
}
private void Update()
{
// 处理相机震动效果
if (_isRunning)
{
var xShake = Mathf.Sin(Time.time * frequency) * amplitude;
var yShake = Mathf.Cos(Time.time * frequency * 2) * amplitude * 0.5f;
cameraTransform.localPosition = _originalPos + new Vector3(xShake, yShake, 0);
// 计算奔跑状态下的震动
ApplyShake(frequency, amplitude);
}
else if (_isWalking)
{
// 计算行走状态下的震动
ApplyShake(frequency / 2, amplitude);
}
else
{
if (_isWalking)
{
var xShake = Mathf.Sin(Time.time * frequency / 2) * amplitude;
var yShake = Mathf.Cos(Time.time * frequency / 2 * 2) * amplitude * 0.5f;
cameraTransform.localPosition = _originalPos + new Vector3(xShake, yShake, 0);
}
else
cameraTransform.localPosition = _originalPos;
// 恢复相机到初始位置
cameraTransform.localPosition = _originalPos;
}
}
// 应用相机震动效果
private void ApplyShake(float shakeFrequency, float shakeAmplitude)
{
var xShake = Mathf.Sin(Time.time * shakeFrequency) * shakeAmplitude; // X轴震动
var yShake = Mathf.Cos(Time.time * shakeFrequency * 2) * shakeAmplitude * 0.5f; // Y轴震动
// 更新相机位置
cameraTransform.localPosition = _originalPos + new Vector3(xShake, yShake, 0);
}
}
}
}

View File

@@ -1,44 +1,54 @@
using UnityEngine;
using UnityEngine.Serialization;
namespace Camera
{
// 处理屏幕的纵横比,以确保游戏在不同分辨率下的正确显示
public class ScreenAspect : MonoBehaviour
{
//目标比例默认16:9
public float TargetAspect = 16f / 9f;
private UnityEngine.Camera _mainCamera;
[FormerlySerializedAs("TargetAspect")]
[Header("Target Aspect Ratio")]
[Tooltip("目标纵横比默认设置为16:9")]
public float targetAspect = 16f / 9f; // 默认目标比例
private UnityEngine.Camera _mainCamera; // 主相机引用
private void Awake()
{
// 获取主相机
_mainCamera = UnityEngine.Camera.main;
// 计算当前窗口的纵横比
var windowAspect = Screen.width / (float)Screen.height;
var scaleHeight = windowAspect / TargetAspect;
// 计算缩放高度
var scaleHeight = windowAspect / targetAspect;
// 根据缩放比例调整相机的视口
if (scaleHeight < 1f)
{
var rect = _mainCamera.rect;
rect.width = 1f;
rect.height = scaleHeight;
rect.x = 0;
rect.y = (1f - scaleHeight) / 2f;
_mainCamera.rect = rect;
// 纵向拉伸的情况
SetCameraRect(1f, scaleHeight, 0, (1f - scaleHeight) / 2f);
}
else
{
// 横向拉伸的情况
var scaleWidth = 1f / scaleHeight;
var rect = _mainCamera.rect;
rect.width = scaleWidth;
rect.height = 1f;
rect.x = (1f - scaleWidth) / 2f;
rect.y = 0;
_mainCamera.rect = rect;
SetCameraRect(scaleWidth, 1f, (1f - scaleWidth) / 2f, 0);
}
}
// 设置相机视口的矩形
private void SetCameraRect(float width, float height, float x, float y)
{
var rect = _mainCamera.rect; // 获取相机的当前视口矩形
rect.width = width; // 设置视口宽度
rect.height = height; // 设置视口高度
rect.x = x; // 设置视口X位置
rect.y = y; // 设置视口Y位置
_mainCamera.rect = rect; // 应用新的视口矩形
}
}
}

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());
}
}
}
}

View File

@@ -0,0 +1,4 @@
namespace Event.EventHandler
{
public delegate void TextChangeHandler();
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 008aadcb613c420cbf9bfff4465322f8
timeCreated: 1728908078

View File

@@ -4,16 +4,20 @@ using UnityEngine;
namespace Event
{
// 事件管理器类,负责事件的注册和触发
public class EventManager : MonoBehaviour
{
private static EventManager _instance;
// 单例模式实例获取
public static EventManager Instance
{
get
{
if (_instance)
return _instance;
// 创建新的 GameObject 和 EventManager 组件
_instance = FindFirstObjectByType<EventManager>() ??
new GameObject("EventManager").AddComponent<EventManager>();
return _instance;
@@ -22,6 +26,7 @@ namespace Event
private void Awake()
{
// 确保只存在一个 EventManager 实例
if (_instance != null && _instance != this)
{
Destroy(gameObject);
@@ -32,19 +37,19 @@ namespace Event
}
}
// 定义事件
public event CameraInterActHandler CameraInterAct;
public event DialogPopHandler DialogPop;
public event PlayerRunStartHandler PlayerRunStart;
public event PlayerRunningHandler PlayerRunning;
public event PlayerRunStopHandler PlayerRunStop;
public event PlayerWalkStartHandler PlayerWalkStart;
public event PlayerWalkStopHandler PlayerWalkStop;
public event PlayerWalkingHandler PlayerWalking;
public event ItemDialogHandler ItemDialog;
public event TextChangeHandler TextChange;
// 事件开关,根据事件名称调用相应的方法
public void EventSwitch(string eventName, string args)
{
switch (eventName)
@@ -52,54 +57,70 @@ namespace Event
case "OnDialogPop":
OnDialogPop(int.Parse(args));
break;
// 可以在此处添加更多事件
default:
break;
}
}
// 触发相机交互事件
public void OnCameraInterAct(GameObject item)
{
CameraInterAct?.Invoke(new CameraInterActArgs(item));
}
// 触发对话框弹出事件
public void OnDialogPop(int index)
{
DialogPop?.Invoke(new DialogPopArgs(index));
}
// 触发玩家开始走路事件
public void OnPlayerWalkStart()
{
PlayerWalkStart?.Invoke();
}
// 触发玩家停止走路事件
public void OnPlayerWalkStop()
{
PlayerWalkStop?.Invoke();
}
// 触发玩家行走事件
public void OnPlayerWalking()
{
PlayerWalking?.Invoke();
}
// 触发玩家开始奔跑事件
public void OnPlayerRunStart()
{
PlayerRunStart?.Invoke();
}
public void OnItemDialog(string nName)
{
ItemDialog?.Invoke(new ItemDialogArgs(nName));
}
// 触发玩家正在奔跑事件
public void OnPlayerRunning()
{
PlayerRunning?.Invoke();
}
// 触发玩家停止奔跑事件
public void OnPlayerRunStop()
{
PlayerRunStop?.Invoke();
}
// 触发文本变化事件
public void OnTextChange()
{
TextChange?.Invoke();
}
// 触发物品对话事件
public void OnItemDialog(string name)
{
ItemDialog?.Invoke(new ItemDialogArgs(name));
}
}
}
}

View File

@@ -6,8 +6,10 @@ namespace Items.Abstract
{
public abstract class ItemBase : MonoBehaviour
{
public int index;
public int index; // 对话索引
public string itemNameKey; //物体本地化key
#region
private void OnEnable()
{
EventManager.Instance.CameraInterAct += ReceiveEvent;
@@ -17,13 +19,16 @@ namespace Items.Abstract
{
EventManager.Instance.CameraInterAct -= ReceiveEvent;
}
#endregion
// 收到相机交互事件
protected virtual void ReceiveEvent(CameraInterActArgs item)
{
if (item.Item != gameObject) return;
ActivateItem();
}
//物体逻辑
protected virtual void ActivateItem()
{
//Debug.Log("Item is activated");

View File

@@ -4,13 +4,19 @@ using Items.Interface;
namespace Items
{
// 测试物品类,继承自 ItemBase 并实现 IItem 接口
public class TestItem : ItemBase, IItem
{
// 重写物品激活方法
protected override void ActivateItem()
{
// 调用基类的激活方法
base.ActivateItem();
//EventManager.Instance.OnDialogPop(index);
EventManager.Instance.OnItemDialog(gameObject.name);
// 触发物品对话事件,使用物品名称作为参数
EventManager.Instance.OnItemDialog(itemNameKey);
EventManager.Instance.OnDialogPop(index);
// 销毁当前物体
Destroy(gameObject);
}
}

View File

@@ -6,46 +6,50 @@ using Newtonsoft.Json;
namespace Keyboard
{
// 管理键位设置,包括加载、保存和获取按键
public class KeySettingManager : MonoBehaviour
{
public List<KeyMapping> keyMappings = new();
public string filePath;
public List<KeyMapping> keyMappings = new(); // 存储键位映射
public string filePath; // 键位设置文件路径
private static KeySettingManager _instance;
private static KeySettingManager _instance; // 单例实例
// 单例属性
public static KeySettingManager Instance
{
get
{
if (_instance)
return _instance;
_instance = FindFirstObjectByType<KeySettingManager>() ??
if (_instance) return _instance; // 如果实例已存在,返回实例
// 否则,查找场景中的实例或创建新实例
_instance = FindFirstObjectByType<KeySettingManager>() ??
new GameObject("KeySettingManager").AddComponent<KeySettingManager>();
return _instance;
}
}
public Vector2 Direction { get; private set; }
public Vector2 Direction { get; private set; } // 存储方向
private void Awake()
{
// 确保只有一个实例存在
if (_instance != null && _instance != this)
{
Destroy(gameObject);
Destroy(gameObject); // 销毁重复的实例
}
else
{
_instance = this;
_instance = this; // 设置单例实例
}
DontDestroyOnLoad(gameObject);
filePath = Application.persistentDataPath + "/" + "KeySetting.json";
LoadKeySettings();
DontDestroyOnLoad(gameObject); // 确保在场景切换时不被销毁
filePath = Application.persistentDataPath + "/" + "KeySetting.json"; // 设置文件路径
LoadKeySettings(); // 加载键位设置
}
//加载键位设置
// 加载键位设置
private void LoadKeySettings()
{
// 如果文件存在,读取并反序列化
if (File.Exists(filePath))
{
var json = File.ReadAllText(filePath);
@@ -53,85 +57,58 @@ namespace Keyboard
}
else
{
//如果文件不存在,创建默认键位设置
keyMappings.Add(new KeyMapping("InterAct", KeyCode.E));
keyMappings.Add(new KeyMapping("Left", KeyCode.A));
keyMappings.Add(new KeyMapping("Right", KeyCode.D));
keyMappings.Add(new KeyMapping("Up", KeyCode.W));
keyMappings.Add(new KeyMapping("Down", KeyCode.S));
keyMappings.Add(new KeyMapping("Run", KeyCode.LeftShift));
SaveKeySettings();
// 如果文件不存在,创建默认键位设置
CreateDefaultKeyMappings();
SaveKeySettings(); // 保存默认设置
}
}
//保存键位设置
// 创建默认键位设置
private void CreateDefaultKeyMappings()
{
keyMappings.Add(new KeyMapping("InterAct", KeyCode.E));
keyMappings.Add(new KeyMapping("Left", KeyCode.A));
keyMappings.Add(new KeyMapping("Right", KeyCode.D));
keyMappings.Add(new KeyMapping("Up", KeyCode.W));
keyMappings.Add(new KeyMapping("Down", KeyCode.S));
keyMappings.Add(new KeyMapping("Run", KeyCode.LeftShift));
}
// 保存键位设置
private void SaveKeySettings()
{
var json = JsonConvert.SerializeObject(keyMappings, Formatting.Indented);
File.WriteAllText(filePath, json);
File.WriteAllText(filePath, json); // 写入JSON文件
}
//获取键
// 获取指定动作的按
public KeyCode GetKey(string actionName)
{
return (from mapping in keyMappings where mapping.actionName == actionName select mapping.keyCode)
.FirstOrDefault();
return keyMappings.FirstOrDefault(mapping => mapping.actionName == actionName).keyCode; // 返回对应的按键
}
//设置键
// 设置指定动作的按
public void SetKey(string actionName, KeyCode newKeyCode)
{
foreach (var mapping in keyMappings.Where(mapping => mapping.actionName == actionName))
var mapping = keyMappings.FirstOrDefault(m => m.actionName == actionName);
if (mapping != null)
{
mapping.keyCode = newKeyCode;
break;
mapping.keyCode = newKeyCode; // 更新键位
SaveKeySettings(); // 保存更改
}
SaveKeySettings();
}
//更新Direction
// 更新方向
private void Update()
{
if (Input.GetKey(GetKey("Left")))
{
Direction = new Vector2(-1, Direction.y);
}
// 重置方向为零
Direction = Vector2.zero;
if (Input.GetKey(GetKey("Right")))
{
Direction = new Vector2(1, Direction.y);
}
if (Input.GetKey(GetKey("Up")))
{
Direction = new Vector2(Direction.x, 1);
}
if (Input.GetKey(GetKey("Down")))
{
Direction = new Vector2(Direction.x, -1);
}
if (Input.GetKey(GetKey("Left")) && Input.GetKey(GetKey("Right")))
{
Direction = new Vector2(0, Direction.y);
}
if (!Input.GetKey(GetKey("Left")) && !Input.GetKey(GetKey("Right")))
{
Direction = new Vector2(0, Direction.y);
}
if (Input.GetKey(GetKey("Up")) && Input.GetKey(GetKey("Down")))
{
Direction = new Vector2(Direction.x, 0);
}
if (!Input.GetKey(GetKey("Up")) && !Input.GetKey(GetKey("Down")))
{
Direction = new Vector2(Direction.x, 0);
}
// 根据按键更新方向
if (Input.GetKey(GetKey("Left"))) Direction += Vector2.left;
if (Input.GetKey(GetKey("Right"))) Direction += Vector2.right;
if (Input.GetKey(GetKey("Up"))) Direction += Vector2.up;
if (Input.GetKey(GetKey("Down"))) Direction += Vector2.down;
}
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 760e8757e837f0449bdbe3161a63d3b0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,80 @@
using System.Collections.Generic;
using UnityEngine;
namespace Localization
{
// 语言枚举
public enum Language
{
en_us,
zh_cn
}
// 本地化管理器类,用于加载和获取本地化文本
public class LocalizationManager : MonoBehaviour
{
// 单例实例
public static LocalizationManager Instance { get; private set; }
// 默认语言设置
public Language defaultLanguage = Language.zh_cn;
// 存储本地化文本的字典
private readonly Dictionary<string, string> _localizedText = new();
// Awake 方法,初始化单例并加载默认语言
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject); // 如果实例已存在,销毁当前对象
}
else
{
Instance = this;
DontDestroyOnLoad(gameObject); // 保持在场景切换中不销毁
LoadLanguage(defaultLanguage); // 加载默认语言
}
}
// 加载指定语言的文本文件
public void LoadLanguage(Language language)
{
_localizedText.Clear(); // 清空现有文本
// 从资源中加载语言文件
var textAsset = Resources.Load<TextAsset>($"Language/{language}");
if (textAsset == null)
{
Debug.LogError($"Unable to find language file for: {language}");
return;
}
// 按行读取文本并填充字典
var lines = textAsset.text.Split('\n');
foreach (var line in lines)
{
var keyValue = line.Split('=');
if (keyValue.Length == 2)
{
// 去除多余空格并添加到字典中
_localizedText[keyValue[0].Trim()] = keyValue[1].Trim();
}
}
}
// 根据键获取本地化的值
public string GetLocalizedValue(string key)
{
// 尝试从字典中获取对应的值
if (_localizedText.TryGetValue(key, out var value))
{
return value;
}
// 如果找不到对应的值,打印警告并返回原 key
Debug.LogWarning($"Localization key '{key}' not found.");
return key;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 37147edcf20d8924c83c6224d801d5c8

View File

@@ -5,70 +5,95 @@ using UnityEngine.Rendering.PostProcessing;
namespace Player
{
// 玩家运动管理类
public class PlayerMotion : MonoBehaviour
{
[SerializeField] private Rigidbody rb;
[SerializeField] private Animator animator;
[SerializeField] private float maxVelocity;
[SerializeField] private PostProcessVolume postProcessVolume;
[SerializeField] private UnityEngine.Camera postProcessCamera;
private Vector3 _velocity;
private bool _isRunning;
private bool _isWalking;
[SerializeField] private Rigidbody rb; // 角色的 Rigidbody 组件
[SerializeField] private Animator animator; // 角色的 Animator 组件
[SerializeField] private float maxVelocity; // 最大速度
[SerializeField] private PostProcessVolume postProcessVolume; // 后处理卷
[SerializeField] private UnityEngine.Camera postProcessCamera; // 后处理相机
private Vector3 _velocity; // 当前速度
private bool _isRunning; // 是否正在奔跑
private bool _isWalking; // 是否正在行走
private void Update()
{
Run();
Run(); // 在每帧更新角色的运动
}
// 处理角色的运动逻辑
private void Run()
{
// 根据输入方向计算速度
_velocity = KeySettingManager.Instance.Direction.x * transform.right +
KeySettingManager.Instance.Direction.y * transform.forward;
// 添加力以移动角色
rb.AddForce(_velocity.normalized * (Time.deltaTime * 50), ForceMode.Impulse);
// 如果没有输入方向,则限制角色的速度
if (_velocity == Vector3.zero)
{
var temp = rb.linearVelocity;
temp = Vector3.ClampMagnitude(temp, 2);
temp.y = rb.linearVelocity.y;
rb.linearVelocity = temp;
var temp = rb.linearVelocity; // 获取当前线性速度
temp = Vector3.ClampMagnitude(temp, 2); // 限制最大速度为 2
temp.y = rb.linearVelocity.y; // 保留 Y 轴速度
rb.linearVelocity = temp; // 更新角色的速度
}
// 处理奔跑状态
if (Input.GetKey(KeySettingManager.Instance.GetKey("Run")) &&
KeySettingManager.Instance.Direction != Vector2.zero)
{
if (!_isRunning)
{
_isRunning = true;
_isWalking = false;
EventManager.Instance.OnPlayerWalkStop();
EventManager.Instance.OnPlayerRunStart();
}
EventManager.Instance.OnPlayerRunning();
rb.linearVelocity = Vector3.ClampMagnitude(rb.linearVelocity, maxVelocity + 2);
HandleRunningState();
}
if (!Input.GetKey(KeySettingManager.Instance.GetKey("Run")) &&
KeySettingManager.Instance.Direction != Vector2.zero)
// 处理行走状态
else if (KeySettingManager.Instance.Direction != Vector2.zero)
{
if (!_isWalking)
{
_isRunning = false;
_isWalking = true;
EventManager.Instance.OnPlayerRunStop();
EventManager.Instance.OnPlayerWalkStart();
}
EventManager.Instance.OnPlayerWalking();
rb.linearVelocity = Vector3.ClampMagnitude(rb.linearVelocity, maxVelocity);
HandleWalkingState();
}
if (KeySettingManager.Instance.Direction == Vector2.zero)
// 如果没有输入方向,停止所有运动状态
else if (KeySettingManager.Instance.Direction == Vector2.zero)
{
EventManager.Instance.OnPlayerRunStop();
EventManager.Instance.OnPlayerWalkStop();
StopMovement();
}
}
// 处理奔跑状态逻辑
private void HandleRunningState()
{
if (!_isRunning)
{
_isRunning = true;
_isWalking = false;
EventManager.Instance.OnPlayerWalkStop();
EventManager.Instance.OnPlayerRunStart();
}
EventManager.Instance.OnPlayerRunning();
rb.linearVelocity = Vector3.ClampMagnitude(rb.linearVelocity, maxVelocity + 2); // 限制速度
}
// 处理行走状态逻辑
private void HandleWalkingState()
{
if (!_isWalking)
{
_isRunning = false;
_isWalking = true;
EventManager.Instance.OnPlayerRunStop();
EventManager.Instance.OnPlayerWalkStart();
}
EventManager.Instance.OnPlayerWalking();
rb.linearVelocity = Vector3.ClampMagnitude(rb.linearVelocity, maxVelocity); // 限制速度
}
// 停止运动状态
private void StopMovement()
{
EventManager.Instance.OnPlayerRunStop();
EventManager.Instance.OnPlayerWalkStop();
}
}
}
}

View File

@@ -2,24 +2,34 @@
namespace UI
{
// 控制暂停按钮的类
public class PauseButton : MonoBehaviour
{
[SerializeField] private GameObject pauseMenu;
[SerializeField] private GameObject pauseMenu; // 暂停菜单的游戏对象
private void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
// 检测是否按下 Escape 键并且游戏未暂停
if (Input.GetKeyDown(KeyCode.Escape) && Time.timeScale != 0)
{
Pause();
Cursor.lockState = CursorLockMode.None;
Pause(); // 调用暂停方法
UnlockCursor(); // 解锁鼠标光标
}
}
// 暂停游戏的方法
public void Pause()
{
pauseMenu.SetActive(true);
Time.timeScale = 0;
gameObject.SetActive(false);
pauseMenu.SetActive(true); // 显示暂停菜单
Time.timeScale = 0; // 将时间缩放设置为 0暂停游戏
gameObject.SetActive(false); // 隐藏暂停按钮
}
// 解锁鼠标光标的方法
private void UnlockCursor()
{
Cursor.lockState = CursorLockMode.None; // 设置光标状态为解锁
Cursor.visible = true; // 确保光标可见
}
}
}

View File

@@ -2,40 +2,46 @@
namespace UI
{
// 控制暂停面板的类
public class PausePanel : MonoBehaviour
{
[SerializeField] private GameObject pauseButton;
[SerializeField] private GameObject pauseButton; // 暂停按钮的游戏对象
private void Start()
{
Time.timeScale = 1;
gameObject.SetActive(false);
Time.timeScale = 1; // 确保游戏开始时时间流动
gameObject.SetActive(false); // 初始时隐藏暂停面板
}
private void Update()
{
// 检测是否按下 Escape 键以继续游戏
if (Input.GetKeyDown(KeyCode.Escape))
{
Continue();
Continue(); // 调用继续游戏的方法
}
}
// 继续游戏的方法
public void Continue()
{
pauseButton.SetActive(true);
Time.timeScale = 1;
Cursor.lockState = CursorLockMode.Locked;
gameObject.SetActive(false);
pauseButton.SetActive(true); // 显示暂停按钮
Time.timeScale = 1; // 恢复游戏时间
Cursor.lockState = CursorLockMode.Locked; // 锁定鼠标光标
gameObject.SetActive(false); // 隐藏暂停面板
}
// 退出游戏的方法
public void Exit()
{
Application.Quit();
Application.Quit(); // 退出应用程序
}
// 返回主菜单的方法(可扩展)
public void MainMenu()
{
Time.timeScale = 1;
Time.timeScale = 1; // 确保时间流动恢复
// todo 这里可以添加加载主菜单的逻辑
}
}
}