This commit is contained in:
SoulliesOfficial
2025-07-26 04:20:25 -04:00
parent bae0bfbc20
commit abf81ece7b
196 changed files with 3909 additions and 964 deletions

View File

@@ -53,4 +53,11 @@ public class BasePrefabsCollection : SerializedScriptableObject
[Title("音频相关")]
public GameObject audioEventObject;
public Dictionary<string, Event> noteSounds;
[Title("Debug")] public GameObject judgeRankHint;
public GameObject tapInputMark;
public GameObject touchInputMark;
[FormerlySerializedAs("swipeInputMark")] public GameObject directionalSwipeInputMark;
public GameObject genericSwipeInputMark;
}

View File

@@ -165,9 +165,9 @@ namespace Ichni
//Debug.Log("Touch: " + fingerId + " " + inputPosition);
}
public void SetNewInputUnitSwipe(int fingerId, Vector2 inputPosition, Vector2 delta)
public void SetNewInputUnitSwipe(int fingerId, Vector2 inputPosition, bool isGeneric, Vector2 delta)
{
InputUnitSwipe inputUnitSwipe = new InputUnitSwipe(fingerId, inputPosition, delta);
InputUnitSwipe inputUnitSwipe = new InputUnitSwipe(fingerId, inputPosition, isGeneric, delta);
if(!inputUnitSwipeList.Exists(x => x.fingerId == fingerId))
{
inputUnitSwipeList.Add(inputUnitSwipe);
@@ -203,11 +203,13 @@ namespace Ichni
public class InputUnitSwipe : InputUnit
{
public Vector2 swipeDirection;
public bool isGeneric;
public InputUnitSwipe(int fingerId, Vector2 inputPosition, Vector2 swipeDirection)
public InputUnitSwipe(int fingerId, Vector2 inputPosition, bool isGeneric, Vector2 swipeDirection)
{
this.fingerId = fingerId;
this.inputPosition = inputPosition;
this.isGeneric = isGeneric;
this.swipeDirection = swipeDirection.normalized;
}
}

View File

@@ -55,7 +55,7 @@ namespace Ichni
if (feature != null)
{
pixelateFeature = feature;
Debug.Log("成功找到并缓存 pixelateFeature (通过反射)!");
//Debug.Log("成功找到并缓存 pixelateFeature (通过反射)!");
break;
}
}

View File

@@ -2,6 +2,13 @@ using UnityEngine;
using UnityEngine.InputSystem;
using System;
using System.Collections.Generic;
using DG.Tweening;
using Ichni;
using Lean.Common;
using Lean.Pool;
using Sirenix.OdinInspector;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;
using TouchPhase = UnityEngine.InputSystem.TouchPhase;
@@ -9,14 +16,14 @@ using TouchPhase = UnityEngine.InputSystem.TouchPhase;
/// 为节奏游戏设计的输入管理器,处理多点触控并分发三种主要事件。
/// 【重要】此版本内置了编辑器内的鼠标模拟功能,无需手机即可测试。
/// </summary>
public class RhythmInputManager : MonoBehaviour
public class RhythmInputManager : SerializedMonoBehaviour
{
// =====================================================================
// 公共事件 (Public Events)
// =====================================================================
public static event Action<int, Vector2> OnTap;
public static event Action<int, Vector2> OnTouch;
public static event Action<int, Vector2, Vector2> OnSwipe;
public static event Action<int, Vector2, bool, Vector2> OnSwipe;
// =====================================================================
// 可配置参数 (Configurable Parameters)
@@ -24,7 +31,8 @@ public class RhythmInputManager : MonoBehaviour
[Header("划动设置 (Swipe Settings)")]
[Tooltip("识别为划动的最小移动距离(像素)")]
[SerializeField] private float minSwipeDistance = 50.0f;
[SerializeField] private float minSwipeDistance = 200.0f;
[SerializeField] private float swipeAngleThreshold = 1f;
// =====================================================================
// 内部状态 (Internal State)
@@ -52,14 +60,19 @@ public class RhythmInputManager : MonoBehaviour
//OnTap += (id, pos)=> Debug.Log($"Tap Detected: Touch ID {id}, Position {pos}");
//OnTouch += (id, pos) => Debug.Log($"Touch Detected: Touch ID {id}, Position {pos}");
//OnSwipe += (id, pos, dir) => Debug.Log($"Swipe Detected: Touch ID {id}, Position {pos}, Direction {dir}");
OnTap += GenerateTapMark;
OnTouch += GenerateTouchMark;
OnSwipe += GenerateSwipeMark;
}
private void Update()
{
// 使用预处理指令区分平台
#if UNITY_EDITOR
#if UNITY_EDITOR || UNITY_STANDALONE
// --- 在Unity编辑器中使用鼠标模拟触摸 ---
ProcessMouseInput();
//ProcessMouseInput();
ProcessKeyboardInput();
#else
// --- 在真机设备上,使用真实的触摸输入 ---
ProcessRealTouchInput();
@@ -124,6 +137,48 @@ public class RhythmInputManager : MonoBehaviour
}
#endif
#if UNITY_EDITOR || UNITY_STANDALONE
public static List<KeyControl> availableKeys = new List<KeyControl>()
{
Keyboard.current.dKey,
Keyboard.current.fKey,
Keyboard.current.jKey,
Keyboard.current.kKey,
};
public static List<KeyControl> flickKeys = new List<KeyControl>()
{
Keyboard.current.sKey,
Keyboard.current.lKey,
};
private void ProcessKeyboardInput()
{
for (int index = 0; index < availableKeys.Count; index++)
{
Vector2 inputPosition = new Vector2(index * 400 - 600 + Screen.width * 0.5f, 200f); // 假设每个按键的虚拟位置
if (availableKeys[index].wasPressedThisFrame)
{
OnTap?.Invoke(index, inputPosition);
}
if (availableKeys[index].isPressed)
{
OnTouch?.Invoke(index, inputPosition);
}
}
for (int index = 0; index < flickKeys.Count; index++)
{
Vector2 inputPosition = new Vector2(index * 1600 - 800 + Screen.width * 0.5f, 200f); // 假设每个划动按键的虚拟位置
if (flickKeys[index].wasPressedThisFrame)
{
OnSwipe?.Invoke(index, inputPosition, true, Vector2.zero);
}
}
}
#endif
/// <summary>
/// 【仅在真机上运行】处理真实的触摸屏输入。
/// </summary>
@@ -198,12 +253,86 @@ public class RhythmInputManager : MonoBehaviour
Vector2 direction = swipeVector.normalized;
// 检查是否是新的划动方向
if (Vector2.Dot(direction, state.LastSwipeDirection) < 0.5f)
if (Vector2.Dot(direction, state.LastSwipeDirection) <= swipeAngleThreshold)
{
OnSwipe?.Invoke(state.TouchId, state.StartPosition, direction);
OnSwipe?.Invoke(state.TouchId, state.StartPosition, false, direction);
state.LastSwipeDirection = direction;
state.StartPosition = currentPosition;
state.StartTime = Time.time;
}
}
private void GenerateTapMark(int id, Vector2 pos)
{
RectTransform mark = LeanPool.Spawn(GameManager.instance.basePrefabs.tapInputMark,
GameManager.instance.judgeHintCanvas.transform). GetComponent<RectTransform>();
RectTransform canvasRect = GameManager.instance.judgeHintCanvas.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.zero;
});
ss.Join(mark.GetComponent<Image>().DOFade(0, 0.5f));
ss.Join(mark.DOScale(5, 0.5f));
ss.OnComplete(() => LeanPool.Despawn(mark.gameObject));
ss.SetUpdate(true);
ss.Play();
}
private void GenerateTouchMark(int id, Vector2 pos)
{
RectTransform mark = LeanPool.Spawn(GameManager.instance.basePrefabs.touchInputMark,
GameManager.instance.judgeHintCanvas.transform). GetComponent<RectTransform>();
RectTransform canvasRect = GameManager.instance.judgeHintCanvas.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;
});
ss.Join(mark.GetComponent<Image>().DOFade(0, 0.1f));
ss.OnComplete(() => LeanPool.Despawn(mark.gameObject));
ss.SetUpdate(true);
ss.Play();
}
private void GenerateSwipeMark(int id, Vector2 pos, bool isGeneric, 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 canvasRect = GameManager.instance.judgeHintCanvas.GetComponent<RectTransform>();
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, pos, null, out Vector2 uiPosition))
{
mark.anchoredPosition = uiPosition;
}
mark.localEulerAngles = new Vector3(0, 0, Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg - 90f);
Sequence ss = DOTween.Sequence();
ss.OnStart(() =>
{
mark.GetComponent<Image>().color = Color.white;
mark.localScale = Vector3.zero;
});
ss.Join(mark.GetComponent<Image>().DOFade(0, 0.5f));
ss.Join(mark.DOScale(5, 0.5f));
ss.OnComplete(() => LeanPool.Despawn(mark.gameObject));
ss.SetUpdate(true);
ss.Play();
}
}