Unity钢琴游戏UI按钮点击检测与录制回放问题求助
Hey there! Let's break down and solve each of your Unity piano game issues step by step:
There are two straightforward ways to handle UI Button clicks in Unity:
Method 1: Editor Binding (No Code Setup Required)
- Select your Button in the Hierarchy panel.
- In the Inspector, locate the
On Click ()section under the Button component. - Click the
+button to add a new event entry. - Drag the GameObject holding your piano logic script into the empty object slot.
- From the dropdown menu, select the method you want to trigger (like
ToggleRecording()orPlayNote()).
Method 2: Dynamic Binding via Code
Great for dynamic UI elements or if you prefer code-driven setup:
using UnityEngine.UI; public Button recordButton; // Assign this in the Inspector private void Start() { // Bind the button click to your custom method recordButton.onClick.AddListener(ToggleRecording); } private void ToggleRecording() { // We'll fill this in for the next issue! }
Instead of relying on keyboard input to start/stop recording, we'll use the button click to toggle a recording state. Here's how to adjust your code:
First, add variables to track recording state and store notes:
private bool isRecording = false; private List<Note> recordedNotes = new List<Note>(); private float recordingStartTime; // Helper class to store note timing and key data [System.Serializable] private class Note { public int noteIndex; // Which piano key was pressed public float timeSinceStart; // Time elapsed since recording began when the note was hit }
Now update the ToggleRecording method to handle start/stop logic:
private void ToggleRecording() { isRecording = !isRecording; if (isRecording) { // Reset recording data when starting a new session recordedNotes.Clear(); recordingStartTime = Time.time; Debug.Log("Recording started!"); } else { Debug.Log("Recording stopped!"); } }
Modify your note-trigger logic to record only when active:
// Call this method whenever a piano key is pressed (via keyboard or UI) public void OnPianoKeyPressed(int noteIndex) { // Play the note immediately (works regardless of recording state) PlayNote(noteIndex); // Record the note if we're in recording mode if (isRecording) { float timeElapsed = Time.time - recordingStartTime; recordedNotes.Add(new Note { noteIndex = noteIndex, timeSinceStart = timeElapsed }); } }
First, make sure your core note playback method is standalone (so it works in any state):
public void PlayNote(int noteIndex) { // Your existing note playback logic here: // Example: Play audio, trigger key visual feedback // AudioSource keyAudio = pianoKeyObjects[noteIndex].GetComponent<AudioSource>(); // if (keyAudio != null) keyAudio.Play(); }
For playback, use a coroutine to respect the timing of recorded notes:
public void PlaybackRecording() { if (recordedNotes.Count == 0) { Debug.Log("No recorded notes to play back!"); return; } StartCoroutine(PlaybackCoroutine()); } private IEnumerator PlaybackCoroutine() { float playbackStartTime = Time.time; foreach (Note note in recordedNotes) { // Wait until the correct time has passed since playback started float waitTime = note.timeSinceStart - (Time.time - playbackStartTime); if (waitTime > 0) { yield return new WaitForSeconds(waitTime); } // Play the note using your standalone method PlayNote(note.noteIndex); } }
Finally, add a "Playback" UI Button and bind its click event to PlaybackRecording() using either the editor or code method from issue 1!
内容的提问来源于stack exchange,提问作者deep

