using UnityEngine; using UnityEngine.UI; using TMPro; using System.Collections.Generic; using UnityEngine.EventSystems; // Важно для отслеживания кликов public class MusicPlayer : MonoBehaviour, IPointerDownHandler { // Определение должно быть внутри класса [System.Serializable] public class Track { public string title; public string artist; public AudioClip clip; } [Header("Data")] public List playlist; private int currentTrackIndex = 0; private bool isPlayerClicked = false; [Header("UI References")] public GameObject playerPanel; // Сама панель плеера, которую будем скрывать public TextMeshProUGUI trackTitleText; public TextMeshProUGUI artistText; public Slider progressSlider; public Slider volumeSlider; public TextMeshProUGUI playPauseText; [Header("Audio")] public AudioSource audioSource; private bool isDragging = false; void Start() { LoadTrack(0); SetVolume(); } void Update() { // Если плеер активен и нажата кнопка мыши if (playerPanel.activeSelf && Input.GetMouseButtonDown(0)) { // Если за этот кадр клик НЕ был по плееру (isPlayerClicked == false) // И мы не кликаем по UI-элементам (чтобы кнопки плеера работали) if (!isPlayerClicked && !IsPointerOverPlayer()) { ClosePlayer(); } isPlayerClicked = false; // Сбрасываем для следующего кадра } if (audioSource.isPlaying && !isDragging && progressSlider != null) { progressSlider.value = audioSource.time / audioSource.clip.length; if (audioSource.time >= (audioSource.clip.length - 0.1f)) { NextTrack(); } } } // Фиксируем, что клик был ВНУТРИ плеера public void OnPointerDown(PointerEventData eventData) { isPlayerClicked = true; } // Проверка: находится ли мышь над объектом плеера private bool IsPointerOverPlayer() { PointerEventData eventData = new PointerEventData(EventSystem.current); eventData.position = Input.mousePosition; List results = new List(); EventSystem.current.RaycastAll(eventData, results); foreach (var res in results) { // Если в иерархии родителей есть наш плеер — значит клик "внутри" if (res.gameObject.transform.IsChildOf(this.transform)) return true; } return false; } public void TogglePlayer() { bool isActive = playerPanel.activeSelf; playerPanel.SetActive(!isActive); // Если открываем — выводим на передний план (через AppLayer если есть) if (!isActive) transform.SetAsLastSibling(); } public void ClosePlayer() { playerPanel.SetActive(false); } // --- ЛОГИКА ПЛЕЕРА (остается прежней) --- public void TogglePlayPause() { if (audioSource.isPlaying) audioSource.Pause(); else audioSource.UnPause(); UpdatePlayPauseUI(); } public void LoadTrack(int index) { if (playlist.Count == 0) return; currentTrackIndex = index; audioSource.clip = playlist[index].clip; trackTitleText.text = playlist[index].title; artistText.text = playlist[index].artist; audioSource.Play(); UpdatePlayPauseUI(); } public void NextTrack() { LoadTrack((currentTrackIndex + 1) % playlist.Count); } public void PreviousTrack() { LoadTrack(currentTrackIndex == 0 ? playlist.Count - 1 : currentTrackIndex - 1); } public void SetVolume() { audioSource.volume = volumeSlider.value; } public void OnSliderDragStart() { isDragging = true; } public void OnSliderDragEnd() { isDragging = false; audioSource.time = progressSlider.value * audioSource.clip.length; } void UpdatePlayPauseUI() { if (playPauseText) playPauseText.text = !audioSource.isPlaying ? "Пауза" : "Воспроизведение"; } }