This commit is contained in:
SoulliesOfficial
2025-09-05 10:14:45 -04:00
parent 4031b29245
commit d4fcca7740
65 changed files with 838 additions and 294 deletions

View File

@@ -9,6 +9,7 @@ using Lean.Pool;
using Sirenix.OdinInspector;
using TMPro;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.EnhancedTouch;
using UnityEngine.UI;
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;
using TouchPhase = UnityEngine.InputSystem.TouchPhase;
@@ -17,7 +18,7 @@ using TouchPhase = UnityEngine.InputSystem.TouchPhase;
/// 为节奏游戏设计的输入管理器,处理多点触控并分发三种主要事件。
/// 【重要】此版本内置了编辑器内的鼠标模拟功能,无需手机即可测试。
/// </summary>
public class GameInputManager : SerializedMonoBehaviour
public class GameInputManager : MonoBehaviour
{
// =====================================================================
// 可配置参数 (Configurable Parameters)
@@ -41,7 +42,7 @@ public class GameInputManager : SerializedMonoBehaviour
public Vector2 StartPosition;
public float StartTime;
public Vector2 LastSwipeDirection = Vector2.zero;
public bool IsTapCandidate = true;
public bool isFirstSwipe = true;
}
private readonly Dictionary<int, TouchState> _activeTouches = new Dictionary<int, TouchState>();
@@ -55,7 +56,7 @@ public class GameInputManager : SerializedMonoBehaviour
private void Awake()
{
#if UNITY_EDITOR || UNITY_STANDALONE
#if UNITY_STANDALONE
DOTween.SetTweensCapacity(200, 200);
gameInput = new GameInput();
gameInput.Game.Enable();
@@ -65,6 +66,8 @@ public class GameInputManager : SerializedMonoBehaviour
Debug.Log("已加载自定义按键绑定");
}
RegisterActionsInputs();
#else
Debug.Log("已启用真实触摸输入");
#endif
}
@@ -76,10 +79,19 @@ public class GameInputManager : SerializedMonoBehaviour
}
// 使用预处理指令区分平台
#if UNITY_EDITOR || UNITY_STANDALONE
#if UNITY_STANDALONE
HandleHolding();
#else
ProcessRealTouchInput();
#endif
}
private void OnDisable()
{
#if UNITY_STANDALONE
#else
#endif
}
@@ -103,21 +115,24 @@ public class GameInputManager : SerializedMonoBehaviour
GameManager.instance.noteJudgeManager.SetNewInputUnitTouch(id, position);
}
private void OnSwipe(int id, Vector2 position, bool isGeneric, Vector2 direction)
private void OnSwipe(int id, Vector2 position, bool isGeneric, bool isFirst, Vector2 direction)
{
if (SettingsManager.instance.gameSettings.debugMode)
{
GenerateSwipeMark(id, position, isGeneric, direction);
GenerateSwipeMark(id, position, isGeneric, isFirst, direction);
if(isFirst) Debug.Log($"划动开始 - ID: {id}, 位置: {position}, 方向: {direction}");
else Debug.Log($"划动更新 - ID: {id}, 位置: {position}, 方向: {direction}");
}
GameManager.instance.noteJudgeManager.SetNewInputUnitSwipe(id, position, isGeneric, direction);
GameManager.instance.noteJudgeManager.SetNewInputUnitSwipe(id, position, isGeneric, isFirst, direction);
}
// =====================================================================
// 核心处理逻辑 (Core Processing Logic)
// =====================================================================
#if UNITY_EDITOR || UNITY_STANDALONE
#if UNITY_STANDALONE
/// <summary>
/// 【仅在编辑器中运行】处理鼠标输入并模拟触摸事件。
/// </summary>
@@ -171,7 +186,7 @@ public class GameInputManager : SerializedMonoBehaviour
}
#endif
#if UNITY_EDITOR || UNITY_STANDALONE
#if UNITY_STANDALONE
public bool holdingTouch0;
public bool holdingTouch1;
@@ -269,22 +284,6 @@ public class GameInputManager : SerializedMonoBehaviour
holdingSwipe0 = false;
}
};
/*gameInput.Game.Swipe1.performed += ctx =>
{
if (ctx.performed)
{
holdingSwipe1 = true;
}
};
gameInput.Game.Swipe1.canceled += ctx =>
{
if (ctx.canceled)
{
holdingSwipe1 = false;
}
};*/
}
private void HandleHolding()
@@ -318,12 +317,6 @@ public class GameInputManager : SerializedMonoBehaviour
Vector2 inputPosition = new Vector2(Screen.width * 0.5f, 200f);
OnSwipe(0, inputPosition, true, Vector2.zero);
}
/*if (holdingSwipe1)
{
Vector2 inputPosition = new Vector2(600 + Screen.width * 0.5f, 200f);
OnSwipe(3, inputPosition, true, Vector2.zero);
}*/
}
#endif
@@ -357,6 +350,8 @@ public class GameInputManager : SerializedMonoBehaviour
TouchId = touchId,
StartPosition = position,
StartTime = Time.time,
LastSwipeDirection = Vector2.zero,
isFirstSwipe = true
};
_activeTouches[touchId] = newState;
OnTap(touchId, position);
@@ -367,7 +362,8 @@ public class GameInputManager : SerializedMonoBehaviour
if (_activeTouches.TryGetValue(touchId, out TouchState movedState))
{
OnTouch(touchId, position);
DetectSwipe(movedState, position);
DetectSwipe(movedState, _activeTouches[touchId].isFirstSwipe, position);
//_activeTouches[touchId].isFirstSwipe = false;
}
break;
@@ -382,6 +378,10 @@ public class GameInputManager : SerializedMonoBehaviour
if (_activeTouches.ContainsKey(touchId))
{
_activeTouches.Remove(touchId);
if (SettingsManager.instance.gameSettings.debugMode)
{
GenerateEndMark(position);
}
}
break;
@@ -389,6 +389,10 @@ public class GameInputManager : SerializedMonoBehaviour
if (_activeTouches.ContainsKey(touchId))
{
_activeTouches.Remove(touchId);
if (SettingsManager.instance.gameSettings.debugMode)
{
GenerateCanceledMark(position);
}
}
break;
}
@@ -397,7 +401,7 @@ public class GameInputManager : SerializedMonoBehaviour
/// <summary>
/// 检测划动逻辑 (无需修改)
/// </summary>
private void DetectSwipe(TouchState state, Vector2 currentPosition)
private void DetectSwipe(TouchState state, bool isFirst, Vector2 currentPosition)
{
Vector2 swipeVector = currentPosition - state.StartPosition;
if (swipeVector.magnitude < minSwipeDistance) return;
@@ -407,7 +411,7 @@ public class GameInputManager : SerializedMonoBehaviour
// 检查是否是新的划动方向
if (Vector2.Dot(direction, state.LastSwipeDirection) <= swipeAngleThreshold)
{
OnSwipe(state.TouchId, state.StartPosition, false, direction);
OnSwipe(state.TouchId, state.StartPosition, false, isFirst, direction);
state.LastSwipeDirection = direction;
state.StartPosition = currentPosition;
state.StartTime = Time.time;
@@ -461,13 +465,13 @@ public class GameInputManager : SerializedMonoBehaviour
ss.Play();
}
private void GenerateSwipeMark(int id, Vector2 pos, bool isGeneric, Vector2 direction)
private void GenerateSwipeMark(int id, Vector2 pos, bool isGeneric, bool isFirst, Vector2 direction)
{
GameObject markPrefab = isGeneric
? GameManager.instance.basePrefabs.genericSwipeInputMark
: GameManager.instance.basePrefabs.directionalSwipeInputMark;
RectTransform mark = LeanPool.Spawn(markPrefab, GameManager.instance.judgeHintCanvas.transform). GetComponent<RectTransform>();
RectTransform mark = LeanPool.Spawn(markPrefab, GameManager.instance.judgeHintCanvas.transform).GetComponent<RectTransform>();
RectTransform canvasRect = GameManager.instance.judgeHintCanvas.GetComponent<RectTransform>();
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, pos, null, out Vector2 uiPosition))
@@ -479,7 +483,7 @@ public class GameInputManager : SerializedMonoBehaviour
Sequence ss = DOTween.Sequence();
ss.OnStart(() =>
{
mark.GetComponent<Image>().color = Color.white;
mark.GetComponent<Image>().color = isFirst ? Color.red : Color.white;
mark.localScale = Vector3.zero;
});
ss.Join(mark.GetComponent<Image>().DOFade(0, 0.25f));
@@ -488,4 +492,50 @@ public class GameInputManager : SerializedMonoBehaviour
ss.SetUpdate(true);
ss.Play();
}
private void GenerateEndMark(Vector2 pos)
{
RectTransform canvasRect = GameManager.instance.judgeHintCanvas.GetComponent<RectTransform>();
RectTransform mark = LeanPool.Spawn(GameManager.instance.basePrefabs.inputEndMark, canvasRect).GetComponent<RectTransform>();
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, pos, null, out Vector2 uiPosition))
{
mark.anchoredPosition = uiPosition;
}
Sequence ss = DOTween.Sequence();
ss.OnStart(() =>
{
mark.GetComponent<Image>().color = Color.white;
mark.localScale = Vector3.one * 5f;
});
ss.Join(mark.GetComponent<Image>().DOFade(0, 0.25f));
ss.Join(mark.DOScale(0, 0.25f));
ss.OnComplete(() => LeanPool.Despawn(mark.gameObject));
ss.SetUpdate(true);
ss.Play();
}
private void GenerateCanceledMark(Vector2 pos)
{
RectTransform canvasRect = GameManager.instance.judgeHintCanvas.GetComponent<RectTransform>();
RectTransform mark = LeanPool.Spawn(GameManager.instance.basePrefabs.inputCanceledMark, canvasRect).GetComponent<RectTransform>();
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, pos, null, out Vector2 uiPosition))
{
mark.anchoredPosition = uiPosition;
}
Sequence ss = DOTween.Sequence();
ss.OnStart(() =>
{
mark.GetComponent<Image>().color = Color.white;
mark.localScale = Vector3.one * 5f;
});
ss.Join(mark.GetComponent<Image>().DOFade(0, 0.25f));
ss.Join(mark.DOScale(0, 0.25f));
ss.OnComplete(() => LeanPool.Despawn(mark.gameObject));
ss.SetUpdate(true);
ss.Play();
}
}