好多新内容
This commit is contained in:
@@ -68,6 +68,11 @@ public class TrackTouchInput : MonoBehaviour
|
||||
|
||||
private void Update()
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
// Windows 平台:禁用轨道点击/触摸轮询,只依赖按键输入。
|
||||
// 编辑器(Win)也一并禁用,便于在 PC 上以键盘方式测试真实 Windows 行为。
|
||||
return;
|
||||
#else
|
||||
var im = InputManager.Instance;
|
||||
if (im == null) return;
|
||||
|
||||
@@ -80,6 +85,7 @@ public class TrackTouchInput : MonoBehaviour
|
||||
{
|
||||
ProcessMouse(im, cam);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>处理所有并发触点,返回本帧触点数量。</summary>
|
||||
@@ -198,6 +204,7 @@ public class TrackTouchInput : MonoBehaviour
|
||||
/// </summary>
|
||||
private int ResolveTrack(Camera cam, Vector2 screenPos)
|
||||
{
|
||||
EnsureOverlapFilter();
|
||||
Vector2 point;
|
||||
|
||||
if (forceOrthographicMode || cam.orthographic)
|
||||
@@ -222,12 +229,58 @@ public class TrackTouchInput : MonoBehaviour
|
||||
point = new Vector2(world.x, world.y);
|
||||
}
|
||||
|
||||
Collider2D hit = Physics2D.OverlapPoint(point, hitLayers);
|
||||
if (hit == null) return -1;
|
||||
// 用 OverlapPointAll 遍历所有命中的碰撞体,挑出带 TrackTouchZone 的那个。
|
||||
// 关键修复:判定线附近同一屏幕点常密集着 note 的 Collider2D 与 judgeline 触发器,
|
||||
// 单值版 OverlapPoint 只返回其中一个,若不是 tap zone 就丢判定(=点了轨道却没反应)。
|
||||
// 遍历全部命中即可穿透这些遮挡,可靠找到轨道点击区。
|
||||
int count = Physics2D.OverlapPoint(point, _overlapFilter, _overlapResults);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Collider2D hit = _overlapResults[i];
|
||||
if (hit == null) continue;
|
||||
TrackTouchZone zone = hit.GetComponent<TrackTouchZone>();
|
||||
if (zone == null) zone = hit.GetComponentInParent<TrackTouchZone>();
|
||||
if (zone != null) return zone.trackIndex;
|
||||
}
|
||||
|
||||
TrackTouchZone zone = hit.GetComponent<TrackTouchZone>();
|
||||
if (zone == null) zone = hit.GetComponentInParent<TrackTouchZone>();
|
||||
return zone != null ? zone.trackIndex : -1;
|
||||
// 兜底:没有精确命中任何 zone(点落在轨道间缝隙或紧邻边缘)。
|
||||
// 取横向最近的 zone,只要触点在其 Collider 的纵向范围内即算命中——
|
||||
// 等效于把相邻轨道点击区在横向补满、消除缝隙,且不误触远离轨道区的点击。
|
||||
return ResolveNearestZone(point);
|
||||
}
|
||||
|
||||
// 横向最近轨道兜底:在所有 zone 中找触点纵向落在其包围盒内、且横向距离最近的一个。
|
||||
private int ResolveNearestZone(Vector2 point)
|
||||
{
|
||||
var zones = TrackTouchZone.All;
|
||||
int best = -1;
|
||||
float bestDist = float.MaxValue;
|
||||
for (int i = 0; i < zones.Count; i++)
|
||||
{
|
||||
TrackTouchZone z = zones[i];
|
||||
if (z == null || z.Collider == null) continue;
|
||||
Bounds b = z.Collider.bounds;
|
||||
// 纵向必须落在该点击区范围内(留一点容差),避免点屏幕别处也触发轨道。
|
||||
if (point.y < b.min.y - 0.1f || point.y > b.max.y + 0.1f) continue;
|
||||
float dx = Mathf.Abs(point.x - b.center.x);
|
||||
if (dx < bestDist) { bestDist = dx; best = z.trackIndex; }
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
// OverlapPoint 的复用缓冲与过滤器(避免每次触摸分配 GC)。
|
||||
private static readonly Collider2D[] _overlapResults = new Collider2D[16];
|
||||
private ContactFilter2D _overlapFilter;
|
||||
private bool _filterReady;
|
||||
|
||||
private void EnsureOverlapFilter()
|
||||
{
|
||||
if (_filterReady) return;
|
||||
_overlapFilter = new ContactFilter2D();
|
||||
_overlapFilter.useLayerMask = true;
|
||||
_overlapFilter.SetLayerMask(hitLayers);
|
||||
_overlapFilter.useTriggers = true; // tap zone 可能是触发器,需包含
|
||||
_filterReady = true;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
|
||||
Reference in New Issue
Block a user