文本系统重做完成
This commit is contained in:
@@ -13,8 +13,6 @@ namespace AibisDream
|
||||
|
||||
[SerializeField] private LineAdvanceInput lineAdvanceInput;
|
||||
|
||||
public AdvanceMode advanceMode;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_dialogueRunner = GetComponentInChildren<DialogueRunner>();
|
||||
@@ -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, LineInfo>(DialogEventEnum.OptionSelected, OnOptionSelected);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
EnumEventSystem.Global.UnRegister(GameLoopEnum.GameStart, ResetAdvanceMode);
|
||||
|
||||
EnumEventSystem.Global.UnRegister(DialogEventEnum.OptionShow, OnOptionShow);
|
||||
EnumEventSystem.Global.UnRegister<DialogEventEnum, LineInfo>(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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ using STOP_MODE = FMOD.Studio.STOP_MODE;
|
||||
|
||||
namespace AibisDream.Kit
|
||||
{
|
||||
public class AudioManager : Singleton<AudioManager>, IAudioManager
|
||||
public class AudioManager : Singleton<AudioManager>
|
||||
{
|
||||
private const string AmbStateName = "scene";
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace AibisDream.Kit
|
||||
private void RegisterEvent()
|
||||
{
|
||||
// 语音相关
|
||||
EnumEventSystem.Global.Register<DialogEventEnum, DialogText>(DialogEventEnum.LineStart, OnLineStart);
|
||||
EnumEventSystem.Global.Register<DialogEventEnum, LineInfo>(DialogEventEnum.LineStart, OnLineStart);
|
||||
EnumEventSystem.Global.Register(DialogEventEnum.LineShown, OnLineShown);
|
||||
// 场景切换相关
|
||||
EnumEventSystem.Global.Register<EventEnum, string>(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();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,72 +1,123 @@
|
||||
using AibisDream.Kit;
|
||||
using System.Collections.Generic;
|
||||
using AibisDream.Kit;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AibisDream.Framework
|
||||
{
|
||||
public class EventSystemEx : SingletonBase<EventSystemEx>
|
||||
public class EventSystemEx : Singleton<EventSystemEx>
|
||||
{
|
||||
#region 状态
|
||||
|
||||
public bool isLocked;
|
||||
|
||||
#endregion
|
||||
|
||||
public GameObject pointerOverObj;
|
||||
public GameObject draggingObj;
|
||||
public GameObject holdingObj;
|
||||
|
||||
|
||||
private List<GameObject> pointerOverObjList;
|
||||
private List<GameObject> draggingObjList;
|
||||
private List<GameObject> 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<GameObject>();
|
||||
draggingObjList = new List<GameObject>();
|
||||
holdingObjList = new List<GameObject>();
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a9cfd121f9a45c0a72e5f056e7ce308
|
||||
timeCreated: 1732358305
|
||||
@@ -1,16 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AibisDream.Framework
|
||||
{
|
||||
public interface IMoveable
|
||||
{
|
||||
bool IsBlock { get; }
|
||||
|
||||
void StartMove();
|
||||
|
||||
void Move(Vector2 mousePos);
|
||||
|
||||
void StopMove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5c7b28802d266d499177b7fa8f9f2cd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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<IMoveable>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d755460ba0142f39c5677d8f948c777
|
||||
timeCreated: 1732358554
|
||||
@@ -23,7 +23,6 @@ namespace AibisDream.Framework
|
||||
{
|
||||
_iocContainer ??= new IOCContainer();
|
||||
// 在这里添加相应的工具
|
||||
Register(new MoveableSystem());
|
||||
Register(new TransTest());
|
||||
}
|
||||
|
||||
|
||||
@@ -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<IUnRegister> _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<Image>();
|
||||
_raycaster = UIManager.Instance.Canvas.GetComponent<GraphicRaycaster>();
|
||||
}
|
||||
|
||||
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<RaycastResult>();
|
||||
_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
|
||||
}
|
||||
}
|
||||
@@ -16,19 +16,10 @@ namespace AibisDream
|
||||
[SerializeField] private TMP_Text widthEstimation;
|
||||
[SerializeField] private CenterBubble centerBubble;
|
||||
|
||||
private Dictionary<ActorRole, Bubble[]> _bubbleDict;
|
||||
private Dictionary<ActorRole, Bubble[]> _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)
|
||||
{
|
||||
// 回收旧泡泡
|
||||
|
||||
@@ -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<RectTransform>();
|
||||
DialogCanvas = transform.Find("Dialog Canvas").GetComponent<RectTransform>();
|
||||
// 获取 GraphicRaycaster
|
||||
_raycaster = Canvas.GetComponent<GraphicRaycaster>();
|
||||
// 获取Panel
|
||||
var panels = Canvas.GetComponentsInChildren<IUIPanel>(true);
|
||||
_panelPool = new Dictionary<Type, IUIPanel>();
|
||||
@@ -167,6 +174,36 @@ namespace AibisDream
|
||||
|
||||
return localPoint;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查鼠标是否在指定标记的 UI 区域上
|
||||
/// </summary>
|
||||
/// <param name="regionTag">区域标识符,需要在 UIRegionMarker 组件中配置</param>
|
||||
/// <returns>如果鼠标在指定区域上返回 true,否则返回 false</returns>
|
||||
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<RaycastResult>();
|
||||
_raycaster.Raycast(eventData, results);
|
||||
|
||||
return results.Count > 0 && results.Any(result => result.gameObject.CompareTag(regionTag));
|
||||
}
|
||||
}
|
||||
|
||||
public interface IUIManager
|
||||
|
||||
Reference in New Issue
Block a user