using UnityEngine; using UnityEngine.EventSystems; /// /// Touch/click region that drives one gameplay track (0-4) through InputManager, /// exactly as if the bound keyboard key were pressed/released. Attach to a UI /// element (Image with Raycast Target on) laid over a lane; set trackIndex in the /// inspector. Uses EventSystem pointer callbacks so it supports multi-touch (each /// finger routes its own down/up to the region it started on) and works on Android /// touch as well as desktop mouse. /// /// Judgment/scoring is unchanged: this only injects the same press/release the /// keyboard path produces. On a track already held by keyboard, PressTrack/ /// ReleaseTrack are idempotent so there is no double-trigger. /// [RequireComponent(typeof(RectTransform))] public class TrackTouchRegion : MonoBehaviour, IPointerDownHandler, IPointerUpHandler { [Tooltip("Track this region controls: 0=red 1=green 2=yellow 3=purple 4=blue")] [Range(0, 4)] public int trackIndex = 0; // The pointerId that pressed this region, so we only release on the matching // pointer's up event (relevant for multi-touch where several fingers are down). private int activePointerId = int.MinValue; private bool pressed = false; public void OnPointerDown(PointerEventData eventData) { if (pressed) return; // already driven by another finger; ignore extras var im = InputManager.Instance; if (im == null) return; activePointerId = eventData.pointerId; pressed = true; im.PressTrack(trackIndex); } public void OnPointerUp(PointerEventData eventData) { if (!pressed || eventData.pointerId != activePointerId) return; var im = InputManager.Instance; pressed = false; activePointerId = int.MinValue; if (im != null) im.ReleaseTrack(trackIndex); } private void OnDisable() { // If the region is hidden/destroyed mid-hold, make sure the track is released // so a note is not left stuck in the held state. if (pressed) { pressed = false; activePointerId = int.MinValue; var im = InputManager.Instance; if (im != null) im.ReleaseTrack(trackIndex); } } }