From ef260e5d430deaf0ef0dcc44e77a264c5d50c1ea Mon Sep 17 00:00:00 2001 From: Ding Yuntian <1491671119@qq.com> Date: Wed, 12 Nov 2025 20:00:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E6=9C=AC=E7=B3=BB=E7=BB=9F=E9=87=8D?= =?UTF-8?q?=E5=81=9A=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Render/Renderer2Dtest.asset | 22 ++- Assets/Scenes/Persistence.unity | 6 +- .../Scripts/Dialog System/DialogController.cs | 53 +++++- Assets/Scripts/Dialog System/LineRunner.cs | 5 +- Assets/Scripts/Dialog System/LineSyncToken.cs | 42 +++-- .../Framework/AudioKit/AudioManager.cs | 10 +- .../Framework/EventSystemKit/EventSystemEx.cs | 109 ++++++++--- .../EventSystemKit/EventTriggerEx.cs | 17 ++ Assets/Scripts/Framework/Moveable.meta | 3 - .../Scripts/Framework/Moveable/IMoveable.cs | 16 -- .../Framework/Moveable/IMoveable.cs.meta | 11 -- .../Framework/Moveable/MoveableSystem.cs | 74 -------- .../Framework/Moveable/MoveableSystem.cs.meta | 3 - .../Scripts/Framework/OtherKit/MonoCenter.cs | 1 - Assets/Scripts/UI/Cursor/CursorManager.cs | 177 ++++++++---------- .../UI/DialogUI/Bubbles/BubbleGroup.cs | 16 +- Assets/Scripts/UI/UIManager.cs | 37 ++++ ProjectSettings/TagManager.asset | 2 +- 18 files changed, 311 insertions(+), 293 deletions(-) delete mode 100644 Assets/Scripts/Framework/Moveable.meta delete mode 100644 Assets/Scripts/Framework/Moveable/IMoveable.cs delete mode 100644 Assets/Scripts/Framework/Moveable/IMoveable.cs.meta delete mode 100644 Assets/Scripts/Framework/Moveable/MoveableSystem.cs delete mode 100644 Assets/Scripts/Framework/Moveable/MoveableSystem.cs.meta diff --git a/Assets/Render/Renderer2Dtest.asset b/Assets/Render/Renderer2Dtest.asset index fdae0d5da..197d64d62 100644 --- a/Assets/Render/Renderer2Dtest.asset +++ b/Assets/Render/Renderer2Dtest.asset @@ -463,15 +463,19 @@ MonoBehaviour: m_PostInfinity: 2 m_RotationOrder: 4 _filter: - - 0.007228916 - - 0.043749984 - - 0.12409639 - - 0.20444278 - - 0.24096388 - - 0.20444278 - - 0.12409639 - - 0.043749984 - - 0.007228916 + - 0.0048309183 + - 0.016401261 + - 0.04532712 + - 0.08293076 + - 0.12053438 + - 0.14946026 + - 0.1610306 + - 0.14946026 + - 0.12053438 + - 0.08293076 + - 0.04532712 + - 0.016401261 + - 0.0048309183 --- !u!114 &-6086986437317696584 MonoBehaviour: m_ObjectHideFlags: 3 diff --git a/Assets/Scenes/Persistence.unity b/Assets/Scenes/Persistence.unity index d05e4a9e6..e62d39ed9 100644 --- a/Assets/Scenes/Persistence.unity +++ b/Assets/Scenes/Persistence.unity @@ -6410,7 +6410,7 @@ GameObject: - component: {fileID: 367483176} m_Layer: 5 m_Name: Top Bar - m_TagString: Selectable + m_TagString: MainUI m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 @@ -6506,7 +6506,7 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 951630327, guid: ca909870d485bde44b1e652490df203f, type: 3} + m_Sprite: {fileID: 0} m_Type: 1 m_PreserveAspect: 0 m_FillCenter: 1 @@ -9284,7 +9284,7 @@ Transform: m_GameObject: {fileID: 519420028} serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalPosition: {x: -0.009999275, y: 0, z: -10} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] diff --git a/Assets/Scripts/Dialog System/DialogController.cs b/Assets/Scripts/Dialog System/DialogController.cs index 7453a23a0..25e1ec033 100644 --- a/Assets/Scripts/Dialog System/DialogController.cs +++ b/Assets/Scripts/Dialog System/DialogController.cs @@ -13,8 +13,6 @@ namespace AibisDream [SerializeField] private LineAdvanceInput lineAdvanceInput; - public AdvanceMode advanceMode; - private void Start() { _dialogueRunner = GetComponentInChildren(); @@ -33,11 +31,17 @@ namespace AibisDream private void OnEnable() { EnumEventSystem.Global.Register(GameLoopEnum.GameStart, ResetAdvanceMode); + + EnumEventSystem.Global.Register(DialogEventEnum.OptionShow, OnOptionShow); + EnumEventSystem.Global.Register(DialogEventEnum.OptionSelected, OnOptionSelected); } private void OnDisable() { EnumEventSystem.Global.UnRegister(GameLoopEnum.GameStart, ResetAdvanceMode); + + EnumEventSystem.Global.UnRegister(DialogEventEnum.OptionShow, OnOptionShow); + EnumEventSystem.Global.UnRegister(DialogEventEnum.OptionSelected, OnOptionSelected); } private void ResetAdvanceMode() @@ -48,6 +52,9 @@ namespace AibisDream isQuick = false }; + isInOption = false; + lineSyncToken = null; + Time.timeScale = 1f; lineAdvanceInput.ResetAdvanceMode(); } @@ -113,6 +120,8 @@ namespace AibisDream #region 推进方式修改 + public AdvanceMode advanceMode; + public void SwitchAutoMode() { advanceMode.isAuto = !advanceMode.isAuto; @@ -128,8 +137,36 @@ namespace AibisDream } #endregion - } + public LineSyncToken lineSyncToken; + public bool isInOption; + + public LineSyncState GetDialogState() + { + if (lineSyncToken != null && lineSyncToken.state != LineSyncState.Advanced) + { + return lineSyncToken.state; + } + else if (isInOption) + { + return LineSyncState.InOption; + } + else + { + return LineSyncState.Default; + } + } + + private void OnOptionShow() + { + isInOption = true; + } + + private void OnOptionSelected(LineInfo lineInfo) + { + isInOption = false; + } + } public struct AdvanceMode { @@ -140,14 +177,14 @@ namespace AibisDream { get { - if (isAuto) - { - return AdvanceModeEnum.Auto; - } - else if (isQuick) + if (isQuick) { return AdvanceModeEnum.Quick; } + else if (isAuto) + { + return AdvanceModeEnum.Auto; + } else { return AdvanceModeEnum.Default; diff --git a/Assets/Scripts/Dialog System/LineRunner.cs b/Assets/Scripts/Dialog System/LineRunner.cs index 1a104e171..ba6188b64 100644 --- a/Assets/Scripts/Dialog System/LineRunner.cs +++ b/Assets/Scripts/Dialog System/LineRunner.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using AibisDream.Framework; using AibisDream.Utility; using UnityEngine; using Yarn.Unity; @@ -23,6 +21,7 @@ namespace AibisDream { // 自动推进视图 lineSyncEvent = LineSyncToken.CreateAuto(dialogueLine, onDialogueLineFinished); + DialogController.Instance.lineSyncToken = lineSyncEvent; if (_screenViewDict.TryGetValue(DialogViewType.Screen, out var view)) { view.RunLine(lineSyncEvent); @@ -35,6 +34,7 @@ namespace AibisDream else if (dialogueLine.GetCharacterVo().dialogViewType == DialogViewType.Task) { lineSyncEvent = LineSyncToken.CreateImmediate(dialogueLine, onDialogueLineFinished); + DialogController.Instance.lineSyncToken = lineSyncEvent; if (_screenViewDict.TryGetValue(DialogViewType.Task, out var view)) { view.RunLine(lineSyncEvent); @@ -48,6 +48,7 @@ namespace AibisDream { // 手动推进视图 lineSyncEvent = LineSyncToken.CreateDefault(dialogueLine, onDialogueLineFinished); + DialogController.Instance.lineSyncToken = lineSyncEvent; bubbleGroup.RunLine(lineSyncEvent); } diff --git a/Assets/Scripts/Dialog System/LineSyncToken.cs b/Assets/Scripts/Dialog System/LineSyncToken.cs index 64808223d..73cd73c1e 100644 --- a/Assets/Scripts/Dialog System/LineSyncToken.cs +++ b/Assets/Scripts/Dialog System/LineSyncToken.cs @@ -41,7 +41,6 @@ namespace AibisDream { this.lineInfo = LineInfo.Generate(lineInfo); _nextStep = nextStep; - state = LineSyncState.PlayText; _textShown = textShown; } @@ -104,7 +103,7 @@ namespace AibisDream EnumEventSystem.Global.Send(DialogEventEnum.LineShown); await _textShown.OnTextShown(this); } - + public void TextStart() { if (state != LineSyncState.Default) @@ -149,7 +148,7 @@ namespace AibisDream var delayTime = lineText.RemoveRichTextTags().Length * ConstRef.CharacterDelayTime; return CommonUtil.Limit(delayTime, ConstRef.LineMaxDelay, ConstRef.LineMinDelay); } - + public int CalcDelayTime() { return ConstRef.FixedDelay; @@ -165,11 +164,18 @@ namespace AibisDream { public async Task OnTextShown(LineSyncToken token) { - token.state = LineSyncState.AdvanceDelay; - await Task.Delay(token.lineInfo.CalcDelayTime(), token.AdvanceDelayToken.Token); - token.state = LineSyncState.WaitForAdvance; - await Task.Delay(token.lineInfo.CalcAutoDelayTime(), token.AdvanceDelayToken.Token); - token.state = LineSyncState.WaitForAutoAdvance; + try + { + token.state = LineSyncState.AdvanceDelay; + await Task.Delay(token.lineInfo.CalcDelayTime(), token.AdvanceDelayToken.Token); + token.state = LineSyncState.WaitForAdvance; + await Task.Delay(token.lineInfo.CalcAutoDelayTime(), token.AdvanceDelayToken.Token); + token.state = LineSyncState.WaitForAutoAdvance; + } + catch (TaskCanceledException) + { + // 跳过,无事发生 + } } } @@ -177,10 +183,17 @@ namespace AibisDream { public async Task OnTextShown(LineSyncToken token) { - token.state = LineSyncState.AdvanceDelay; - await Task.Delay(token.lineInfo.CalcDelayTime(), token.AdvanceDelayToken.Token); - token.state = LineSyncState.WaitForAutoAdvance; - token.TryAdvance(); + try + { + token.state = LineSyncState.AdvanceDelay; + await Task.Delay(token.lineInfo.CalcDelayTime(), token.AdvanceDelayToken.Token); + token.state = LineSyncState.WaitForAutoAdvance; + token.TryAdvance(); + } + catch (TaskCanceledException) + { + // 跳过,无事发生 + } } } @@ -199,6 +212,9 @@ namespace AibisDream AdvanceDelay, WaitForAdvance, WaitForAutoAdvance, - Advanced + Advanced, + + // 仅限DialogController使用 + InOption } } \ No newline at end of file diff --git a/Assets/Scripts/Framework/AudioKit/AudioManager.cs b/Assets/Scripts/Framework/AudioKit/AudioManager.cs index 8ece6680c..2680f6886 100644 --- a/Assets/Scripts/Framework/AudioKit/AudioManager.cs +++ b/Assets/Scripts/Framework/AudioKit/AudioManager.cs @@ -11,7 +11,7 @@ using STOP_MODE = FMOD.Studio.STOP_MODE; namespace AibisDream.Kit { - public class AudioManager : Singleton, IAudioManager + public class AudioManager : Singleton { private const string AmbStateName = "scene"; @@ -46,7 +46,7 @@ namespace AibisDream.Kit private void RegisterEvent() { // 语音相关 - EnumEventSystem.Global.Register(DialogEventEnum.LineStart, OnLineStart); + EnumEventSystem.Global.Register(DialogEventEnum.LineStart, OnLineStart); EnumEventSystem.Global.Register(DialogEventEnum.LineShown, OnLineShown); // 场景切换相关 EnumEventSystem.Global.Register(EventEnum.SceneLoad, OnSceneLoad); @@ -235,7 +235,7 @@ namespace AibisDream.Kit #endregion - public void OnLineStart(DialogText dialogText) + public void OnLineStart(LineInfo dialogText) { if (_voiceInstance.IsPlaying()) { @@ -243,12 +243,12 @@ namespace AibisDream.Kit _voiceInstance.release(); } - if (string.IsNullOrEmpty(dialogText.actor.voicePath) || !FModEx.IsEventExist(dialogText.actor.VoicePath)) + if (string.IsNullOrEmpty(dialogText.character.voicePath) || !FModEx.IsEventExist(dialogText.character.VoicePath)) { return; } - _voiceInstance = RuntimeManager.CreateInstance(dialogText.actor.VoicePath); + _voiceInstance = RuntimeManager.CreateInstance(dialogText.character.VoicePath); _voiceInstance.start(); } diff --git a/Assets/Scripts/Framework/EventSystemKit/EventSystemEx.cs b/Assets/Scripts/Framework/EventSystemKit/EventSystemEx.cs index c2066436c..d7eefe598 100644 --- a/Assets/Scripts/Framework/EventSystemKit/EventSystemEx.cs +++ b/Assets/Scripts/Framework/EventSystemKit/EventSystemEx.cs @@ -1,72 +1,123 @@ -using AibisDream.Kit; +using System.Collections.Generic; +using AibisDream.Kit; using UnityEngine; namespace AibisDream.Framework { - public class EventSystemEx : SingletonBase + public class EventSystemEx : Singleton { #region 状态 public bool isLocked; #endregion - - public GameObject pointerOverObj; - public GameObject draggingObj; - public GameObject holdingObj; - + + private List pointerOverObjList; + private List draggingObjList; + private List holdingObjList; + #region 事件触发中转 public void OnPointerEnter(IInteraction interaction) { - pointerOverObj = interaction.GetGameObject(); - EnumEventSystem.Global.Send(TriggerEnum.PointerEnter, interaction); + if (!pointerOverObjList.Contains(interaction.GetGameObject())) + { + pointerOverObjList.Add(interaction.GetGameObject()); + } } public void OnPointerExit(IInteraction interaction) { - if (pointerOverObj == interaction.GetGameObject()) - { - EnumEventSystem.Global.Send(TriggerEnum.PointerExit, interaction); - pointerOverObj = null; - } + pointerOverObjList.Remove(interaction.GetGameObject()); } public void OnPointerDown(IInteraction interaction) { - EnumEventSystem.Global.Send(TriggerEnum.PointerDown, interaction); - holdingObj = interaction.GetGameObject(); + if (!holdingObjList.Contains(interaction.GetGameObject())) + { + holdingObjList.Add(interaction.GetGameObject()); + } } public void OnPointerUp(IInteraction interaction) { - if (holdingObj == interaction.GetGameObject()) + holdingObjList.Remove(interaction.GetGameObject()); + } + + public void OnDrag(IInteraction interaction) + { + if (!draggingObjList.Contains(interaction.GetGameObject())) { - EnumEventSystem.Global.Send(TriggerEnum.PointerUp, interaction); - holdingObj = null; + draggingObjList.Add(interaction.GetGameObject()); + } + } + + public void OnEndDrag(IInteraction interaction) + { + draggingObjList.Remove(interaction.GetGameObject()); + } + + public void OnBeginDrag(IInteraction interaction) + { + if (!draggingObjList.Contains(interaction.GetGameObject())) + { + draggingObjList.Add(interaction.GetGameObject()); + } + } + + public TriggerEnum GetPointerState() + { + if (holdingObjList.Count > 0 || draggingObjList.Count > 0) + { + Debug.Log($"Dragging: {draggingObjList.Count}"); + Debug.Log($"Holding: {holdingObjList.Count}"); + return TriggerEnum.Dragging; + } + else if (pointerOverObjList.Count > 0) + { + Debug.Log($"PointerOver: {pointerOverObjList.Count}"); + return TriggerEnum.PointerOver; + } + else + { + return TriggerEnum.None; } } #endregion - + #region 单例必须的代码 - private EventSystemEx() - { - } - public override void OnSingletonInit() { + pointerOverObjList = new List(); + draggingObjList = new List(); + holdingObjList = new List(); + + EnumEventSystem.Global.Register(GameLoopEnum.GameStart, ClearAll); + EnumEventSystem.Global.Register(GameLoopEnum.GameQuit, ClearAll); + } + + private void ClearAll() + { + pointerOverObjList.Clear(); + draggingObjList.Clear(); + holdingObjList.Clear(); + } + + public override void OnSingletonDestroy() + { + EnumEventSystem.Global.UnRegister(GameLoopEnum.GameStart, ClearAll); + EnumEventSystem.Global.UnRegister(GameLoopEnum.GameQuit, ClearAll); } #endregion } - + public enum TriggerEnum { - PointerEnter, - PointerExit, - PointerDown, - PointerUp + None, + Dragging, + PointerOver } } \ No newline at end of file diff --git a/Assets/Scripts/Framework/EventSystemKit/EventTriggerEx.cs b/Assets/Scripts/Framework/EventSystemKit/EventTriggerEx.cs index 93b761c97..c8e9dd7a8 100644 --- a/Assets/Scripts/Framework/EventSystemKit/EventTriggerEx.cs +++ b/Assets/Scripts/Framework/EventSystemKit/EventTriggerEx.cs @@ -102,6 +102,23 @@ namespace AibisDream.Framework base.OnPointerUp(eventData); } } + + public override void OnDrag(PointerEventData eventData) + { + EventSystemEx.Instance.OnDrag(_interaction); + base.OnDrag(eventData); + } + + public override void OnEndDrag(PointerEventData eventData) + { + EventSystemEx.Instance.OnEndDrag(_interaction); + base.OnEndDrag(eventData); + } + + public override void OnBeginDrag(PointerEventData eventData) + { + base.OnBeginDrag(eventData); + } } public interface IInteraction diff --git a/Assets/Scripts/Framework/Moveable.meta b/Assets/Scripts/Framework/Moveable.meta deleted file mode 100644 index 0d6800e14..000000000 --- a/Assets/Scripts/Framework/Moveable.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 9a9cfd121f9a45c0a72e5f056e7ce308 -timeCreated: 1732358305 \ No newline at end of file diff --git a/Assets/Scripts/Framework/Moveable/IMoveable.cs b/Assets/Scripts/Framework/Moveable/IMoveable.cs deleted file mode 100644 index 6dff18dad..000000000 --- a/Assets/Scripts/Framework/Moveable/IMoveable.cs +++ /dev/null @@ -1,16 +0,0 @@ -using UnityEngine; - -namespace AibisDream.Framework -{ - public interface IMoveable - { - bool IsBlock { get; } - - void StartMove(); - - void Move(Vector2 mousePos); - - void StopMove(); - } -} - diff --git a/Assets/Scripts/Framework/Moveable/IMoveable.cs.meta b/Assets/Scripts/Framework/Moveable/IMoveable.cs.meta deleted file mode 100644 index bf7be376a..000000000 --- a/Assets/Scripts/Framework/Moveable/IMoveable.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c5c7b28802d266d499177b7fa8f9f2cd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/Framework/Moveable/MoveableSystem.cs b/Assets/Scripts/Framework/Moveable/MoveableSystem.cs deleted file mode 100644 index 9e26b1931..000000000 --- a/Assets/Scripts/Framework/Moveable/MoveableSystem.cs +++ /dev/null @@ -1,74 +0,0 @@ -using UnityEngine; - -namespace AibisDream.Framework -{ - public class MoveableSystem : IMonoKit - { - private bool _isDragging; - private IMoveable _dragObj; - private Vector3 _offset; - private readonly Camera _camera = Camera.main; - - public void OnUpdate() - { - // 鼠标按下 - if (Input.GetMouseButtonDown(0)) - { - OnMouseClickDown(); - } - - // 鼠标按住 - if (Input.GetMouseButton(0) && _isDragging) - { - OnMouseHolding(); - } - - // 鼠标松开 - if (Input.GetMouseButtonUp(0)) - { - OnMouseClickUp(); - } - } - - private void OnMouseClickDown() - { - // 按下时发出检查射线 - Ray ray = _camera.ScreenPointToRay(Input.mousePosition); - RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction); - - // 检测命中的物体 - if (hit.collider && hit.collider.CompareTag("Moveable")) - { - _dragObj = hit.collider.gameObject.GetComponent(); - if (_dragObj == null) return; - if (_dragObj.IsBlock) return; - - _dragObj.StartMove(); - _offset = hit.collider.transform.position - GetMouseAsWorldPoint(); - - _isDragging = true; - } - } - - private void OnMouseHolding() - { - _dragObj.Move(GetMouseAsWorldPoint() + _offset); - } - - private void OnMouseClickUp() - { - if (!_isDragging) return; - - _dragObj?.StopMove(); - _dragObj = null; - _isDragging = false; - } - - private Vector3 GetMouseAsWorldPoint() - { - Vector3 mousePoint = Input.mousePosition; - mousePoint.z = _camera.nearClipPlane; - return _camera.ScreenToWorldPoint(mousePoint); - } - } -} \ No newline at end of file diff --git a/Assets/Scripts/Framework/Moveable/MoveableSystem.cs.meta b/Assets/Scripts/Framework/Moveable/MoveableSystem.cs.meta deleted file mode 100644 index 0268f4b0c..000000000 --- a/Assets/Scripts/Framework/Moveable/MoveableSystem.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 5d755460ba0142f39c5677d8f948c777 -timeCreated: 1732358554 \ No newline at end of file diff --git a/Assets/Scripts/Framework/OtherKit/MonoCenter.cs b/Assets/Scripts/Framework/OtherKit/MonoCenter.cs index 8721910c4..89b4b3211 100644 --- a/Assets/Scripts/Framework/OtherKit/MonoCenter.cs +++ b/Assets/Scripts/Framework/OtherKit/MonoCenter.cs @@ -23,7 +23,6 @@ namespace AibisDream.Framework { _iocContainer ??= new IOCContainer(); // 在这里添加相应的工具 - Register(new MoveableSystem()); Register(new TransTest()); } diff --git a/Assets/Scripts/UI/Cursor/CursorManager.cs b/Assets/Scripts/UI/Cursor/CursorManager.cs index 615fd4e58..187f4530d 100644 --- a/Assets/Scripts/UI/Cursor/CursorManager.cs +++ b/Assets/Scripts/UI/Cursor/CursorManager.cs @@ -1,9 +1,6 @@ -using System.Collections.Generic; -using System.Linq; -using AibisDream.Framework; +using AibisDream.Framework; using AibisDream.Kit; using UnityEngine; -using UnityEngine.EventSystems; using UnityEngine.UI; namespace AibisDream @@ -16,21 +13,6 @@ namespace AibisDream public Sprite nextTalk, talking, option, interactive, holding, disable; private Image _cursor; - private GraphicRaycaster _raycaster; - - private CursorState _stateCache; - - #region 状态相关 - - private Coroutine _switchCoroutine; - private CursorState _curState = CursorState.Default; - private bool _isTalking; - private bool _isInGame; - - #endregion - - // 卸载时注销事件 - private readonly List _unRegisters = new(); private void Start() { @@ -45,87 +27,9 @@ namespace AibisDream _cursor.sprite = defaultCursor; } - private void OnEnable() - { - RegisterEvent(); - } - - private void OnDisable() - { - // 注销所有事件 - foreach (var eventUnRegister in _unRegisters) - { - eventUnRegister.UnRegister(); - } - - _unRegisters.Clear(); - } - private void InitRefs() { _cursor = transform.Find("Cursor").GetComponent(); - _raycaster = UIManager.Instance.Canvas.GetComponent(); - } - - private void RegisterEvent() - { - // 此处监听所有可能对鼠标状态产生影响的事件 - RegisterGameEvent(); - } - - private void RegisterGameEvent() - { - _unRegisters.Add(EnumEventSystem.Global.Register(GameLoopEnum.GameStart, OnGameStart)); - _unRegisters.Add(EnumEventSystem.Global.Register(GameLoopEnum.GameQuit, OnGameQuit)); - _unRegisters.Add(EnumEventSystem.Global.Register(GameLoopEnum.PauseGame, OnPauseGame)); - _unRegisters.Add(EnumEventSystem.Global.Register(GameLoopEnum.UnPauseGame, OnUnPauseGame)); - } - - private void OnGameStart() - { - _isInGame = true; - } - - private void OnUnPauseGame() - { - _curState = _stateCache; - _stateCache = CursorState.Default; - - _isInGame = true; - } - - private void OnPauseGame() - { - _stateCache = _curState; - _curState = CursorState.Default; - - _isInGame = false; - } - - private void OnGameQuit() - { - _curState = CursorState.Default; - _stateCache = CursorState.Default; - - _isInGame = false; - } - - private bool IsOverSelected() - { - if (!EventSystem.current.IsPointerOverGameObject()) - { - return false; - } - - var eventData = new PointerEventData(EventSystem.current) - { - position = Input.mousePosition - }; - - var results = new List(); - _raycaster.Raycast(eventData, results); - - return results.Count > 0 && results.Any(result => result.gameObject.CompareTag("Selectable")); } private void LateUpdate() @@ -134,15 +38,88 @@ namespace AibisDream // RectTransformUtility.ScreenPointToLocalPointInRectangle(_cursorCanvas, Input.mousePosition, // CameraKit.Instance.uiCamera, out var worldPos); + // 判断当前要用什么样的指针 _cursor.rectTransform.position = Input.mousePosition; - // 在输入状态,要单独处理 + var cursorState = CheckCursorState(); + _cursor.sprite = GetCursorSprite(cursorState); + } + + private CursorStateEnum CheckCursorState() + { + var gameState = GameManager.Instance.state; + + if (!gameState.isInGame || gameState.isInPause) + { + // 非游戏中显示默认指针 + return CursorStateEnum.Default; + } + else if (UIManager.Instance.IsOverRegion("MainUI")) + { + // 游戏中鼠标移至右上角Main Panel时显示默认指针 + return CursorStateEnum.Default; + } + else if (gameState.isInDialog) + { + // 处理对话中的指针 + var dialogState = DialogController.Instance.GetDialogState(); + return HandleDialogState(dialogState); + } + else + { + // 非对话处理指针交互 + var triggerEnum = EventSystemEx.Instance.GetPointerState(); + return HandleDraggingState(triggerEnum); + } + } + + private CursorStateEnum HandleDialogState(LineSyncState dialogState) + { + return dialogState switch + { + LineSyncState.Default => CursorStateEnum.Default, + LineSyncState.PlayText => CursorStateEnum.PlayText, + LineSyncState.AdvanceDelay => CursorStateEnum.PlayText, + LineSyncState.WaitForAdvance => CursorStateEnum.WaitForAdvance, + LineSyncState.WaitForAutoAdvance => CursorStateEnum.WaitForAdvance, + LineSyncState.Advanced => CursorStateEnum.Default, + LineSyncState.InOption => CursorStateEnum.InOption, + _ => CursorStateEnum.Default, + }; + } + + private CursorStateEnum HandleDraggingState(TriggerEnum triggerEnum) + { + return triggerEnum switch + { + TriggerEnum.Dragging => CursorStateEnum.Dragging, + TriggerEnum.PointerOver => CursorStateEnum.PointerOver, + _ => CursorStateEnum.Default, + }; + } + + private Sprite GetCursorSprite(CursorStateEnum cursorState) + { + return cursorState switch + { + CursorStateEnum.Default => defaultCursor, + CursorStateEnum.PlayText => talking, + CursorStateEnum.WaitForAdvance => nextTalk, + CursorStateEnum.InOption => option, + CursorStateEnum.Dragging => holding, + CursorStateEnum.PointerOver => interactive, + _ => defaultCursor, + }; } } - public enum CursorState + public enum CursorStateEnum { Default, - Interactive + PlayText, + WaitForAdvance, + InOption, + Dragging, + PointerOver } } \ No newline at end of file diff --git a/Assets/Scripts/UI/DialogUI/Bubbles/BubbleGroup.cs b/Assets/Scripts/UI/DialogUI/Bubbles/BubbleGroup.cs index d78ef51fc..8808a584f 100644 --- a/Assets/Scripts/UI/DialogUI/Bubbles/BubbleGroup.cs +++ b/Assets/Scripts/UI/DialogUI/Bubbles/BubbleGroup.cs @@ -16,19 +16,10 @@ namespace AibisDream [SerializeField] private TMP_Text widthEstimation; [SerializeField] private CenterBubble centerBubble; - private Dictionary _bubbleDict; + private Dictionary _bubbleDict = new(); private BubbleFactory _bubbleFactory; private CancellationTokenSource _autoHideToken; - #region 一些索引 - - private Action _nextStep; - private IBubble _curBubble; - - private IUnRegister _unRegister; - - #endregion - #region 生命周期 public override void OnSingletonInit() @@ -37,11 +28,6 @@ namespace AibisDream _bubbleFactory = new BubbleFactory(transform); } - public override void OnSingletonDestroy() - { - _unRegister.UnRegister(); - } - public void LoadBubbles(BubbleSlotGroupData groupData) { // 回收旧泡泡 diff --git a/Assets/Scripts/UI/UIManager.cs b/Assets/Scripts/UI/UIManager.cs index 0d518ed8d..7f92b313d 100644 --- a/Assets/Scripts/UI/UIManager.cs +++ b/Assets/Scripts/UI/UIManager.cs @@ -1,8 +1,11 @@ using System; using System.Collections.Generic; +using System.Linq; using AibisDream.Framework; using AibisDream.UI; using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.UI; namespace AibisDream { @@ -19,6 +22,8 @@ namespace AibisDream public Camera UICamera { get; private set; } public RectTransform DialogCanvas { get; private set; } + private GraphicRaycaster _raycaster; + #endregion public override void OnSingletonInit() @@ -60,6 +65,8 @@ namespace AibisDream // 获取Canvas Canvas = transform.Find("UI Canvas").GetComponent(); DialogCanvas = transform.Find("Dialog Canvas").GetComponent(); + // 获取 GraphicRaycaster + _raycaster = Canvas.GetComponent(); // 获取Panel var panels = Canvas.GetComponentsInChildren(true); _panelPool = new Dictionary(); @@ -167,6 +174,36 @@ namespace AibisDream return localPoint; } + + /// + /// 检查鼠标是否在指定标记的 UI 区域上 + /// + /// 区域标识符,需要在 UIRegionMarker 组件中配置 + /// 如果鼠标在指定区域上返回 true,否则返回 false + public bool IsOverRegion(string regionTag) + { + if (string.IsNullOrEmpty(regionTag)) + { + return false; + } + + // 如果鼠标不在 UI 上,直接返回 false + if (!EventSystem.current.IsPointerOverGameObject()) + { + return false; + } + + // 使用 GraphicRaycaster 检测鼠标下的 UI 元素 + var eventData = new PointerEventData(EventSystem.current) + { + position = Input.mousePosition + }; + + var results = new List(); + _raycaster.Raycast(eventData, results); + + return results.Count > 0 && results.Any(result => result.gameObject.CompareTag(regionTag)); + } } public interface IUIManager diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset index f747fc170..975690646 100644 --- a/ProjectSettings/TagManager.asset +++ b/ProjectSettings/TagManager.asset @@ -12,9 +12,9 @@ TagManager: - DialogueObject - MoveableCharacter - Vehicle - - Selectable - UIcamera - ViewCamera + - MainUI layers: - Default - TransparentFX