AI补足注释(已经快看不懂了)
实现i18n 优化部分模块的逻辑以优化性能 修复物品展示框打开时按下ESC唤出暂停菜单但没有暂停的bug Signed-off-by: Eicy <im@crash.work>
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -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,2 +1,2 @@
|
||||
name,description
|
||||
Cube,只是一个方块。
|
||||
item.name.cube,item.description.cube
|
||||
|
||||
|
8
Assets/Resources/Language.meta
Normal file
8
Assets/Resources/Language.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d11d94775f774f4fb82bfa947139e90
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
4
Assets/Resources/Language/zh_cn.txt
Normal file
4
Assets/Resources/Language/zh_cn.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
item.name.cube=方块
|
||||
item.description.cube=只是一个方块。
|
||||
dialog.typing.0=我会一直视奸你..
|
||||
dialog.box.1=永远..永远…
|
||||
7
Assets/Resources/Language/zh_cn.txt.meta
Normal file
7
Assets/Resources/Language/zh_cn.txt.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75a836a9d560014499f611d03e575526
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; // 应用新的视口矩形
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4
Assets/Scripts/Event/EventHandler/TextChangeHandler.cs
Normal file
4
Assets/Scripts/Event/EventHandler/TextChangeHandler.cs
Normal file
@@ -0,0 +1,4 @@
|
||||
namespace Event.EventHandler
|
||||
{
|
||||
public delegate void TextChangeHandler();
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 008aadcb613c420cbf9bfff4465322f8
|
||||
timeCreated: 1728908078
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
8
Assets/Scripts/Localization.meta
Normal file
8
Assets/Scripts/Localization.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 760e8757e837f0449bdbe3161a63d3b0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
80
Assets/Scripts/Localization/LocalizationManager.cs
Normal file
80
Assets/Scripts/Localization/LocalizationManager.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Localization/LocalizationManager.cs.meta
Normal file
2
Assets/Scripts/Localization/LocalizationManager.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 37147edcf20d8924c83c6224d801d5c8
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; // 确保光标可见
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 这里可以添加加载主菜单的逻辑
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user