using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace RR.Common.UI { /// /// Меняет цвет TMP-текста внутри кнопки при фокусе и наведении. /// public class ButtonTextFocusColor : MonoBehaviour, ISelectHandler, IDeselectHandler, IPointerEnterHandler, IPointerExitHandler { [SerializeField] private TextMeshProUGUI targetText; [SerializeField] private Color normalColor = new(0f, 0.29411766f, 0.1882353f, 1f); [SerializeField] private Color focusedColor = Color.white; private Selectable _selectable; private bool _isPointerInside; private bool _lastFocusedState; private bool _hasAppliedState; private void Awake() { ResolveReferences(); RefreshVisualState(force: true); } private void OnEnable() { ResolveReferences(); RefreshVisualState(force: true); } private void OnDisable() { _isPointerInside = false; _lastFocusedState = false; _hasAppliedState = false; ApplyTextColor(normalColor); } private void LateUpdate() { RefreshVisualState(); } public void OnSelect(BaseEventData eventData) { RefreshVisualState(force: true); } public void OnDeselect(BaseEventData eventData) { RefreshVisualState(force: true); } public void OnPointerEnter(PointerEventData eventData) { _isPointerInside = true; RefreshVisualState(force: true); } public void OnPointerExit(PointerEventData eventData) { _isPointerInside = false; RefreshVisualState(force: true); } private void RefreshVisualState(bool force = false) { ResolveReferences(); bool isFocused = IsFocusedNow(); if (!force && _hasAppliedState && _lastFocusedState == isFocused) { return; } _lastFocusedState = isFocused; _hasAppliedState = true; ApplyTextColor(isFocused ? focusedColor : normalColor); } private bool IsFocusedNow() { if (!isActiveAndEnabled) { return false; } if (_selectable != null && (!_selectable.IsActive() || !_selectable.IsInteractable())) { return false; } bool isSelected = EventSystem.current != null && EventSystem.current.currentSelectedGameObject == gameObject; return isSelected || _isPointerInside; } private void ApplyTextColor(Color color) { if (targetText == null) { return; } targetText.color = color; } private void ResolveReferences() { if (_selectable == null) { _selectable = GetComponent(); } if (targetText == null) { targetText = GetComponentInChildren(true); } } #if UNITY_EDITOR private void Reset() { ResolveReferences(); } private void OnValidate() { ResolveReferences(); if (!Application.isPlaying) { RefreshVisualState(force: true); } } #endif } }