using UnityEngine; using UnityEngine.EventSystems; using Unheimlich.Features.DetectiveBoard.Data; namespace Unheimlich.Features.DetectiveBoard.UI { /// /// Wraps a PostItNode to behave as a card in the bottom-screen fan hand. /// Handles hover pop animation and delegates click to ClueHandUI for board placement. /// Add this component alongside PostItNode on the same GameObject. /// [RequireComponent(typeof(PostItNode))] public class ClueHandCard : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler { [Header("Hover Settings")] [SerializeField] private float _hoverRiseAmount = 60f; [SerializeField] private float _hoverAnimSpeed = 8f; private PostItNode _node; private ClueHandUI _handUI; // Fan resting state assigned by ClueHandUI private Vector2 _restAnchoredPosition; private float _restRotation; // Runtime animation state private Vector2 _currentAnchoredPosition; private float _currentRotation; private bool _isHovered; private bool _isPlaced; public ClueData ClueData => _node != null ? _node.ClueData : null; public PostItNode Node => _node; public bool IsPlaced => _isPlaced; private void Awake() { if (_node == null) _node = GetComponent(); } /// /// Binds this card to its parent hand manager. /// public void Initialize(PostItNode node, ClueHandUI handUI) { _node = node; _handUI = handUI; } /// /// Assigns the resting fan slot (position + rotation) for this card. /// public void SetFanSlot(Vector2 anchoredPosition, float rotationZ) { _restAnchoredPosition = anchoredPosition; _restRotation = rotationZ; _currentAnchoredPosition = anchoredPosition; _currentRotation = rotationZ; RectTransform rt = _node.RectTransform; rt.anchoredPosition = anchoredPosition; rt.localRotation = Quaternion.Euler(0f, 0f, rotationZ); } private void Update() { if (_isPlaced) return; RectTransform rt = _node.RectTransform; Vector2 targetPos = _isHovered ? _restAnchoredPosition + Vector2.up * _hoverRiseAmount : _restAnchoredPosition; float targetRot = _isHovered ? 0f : _restRotation; _currentAnchoredPosition = Vector2.Lerp(_currentAnchoredPosition, targetPos, Time.deltaTime * _hoverAnimSpeed); _currentRotation = Mathf.LerpAngle(_currentRotation, targetRot, Time.deltaTime * _hoverAnimSpeed); rt.anchoredPosition = _currentAnchoredPosition; rt.localRotation = Quaternion.Euler(0f, 0f, _currentRotation); } public void OnPointerEnter(PointerEventData eventData) { if (_isPlaced) return; _isHovered = true; _handUI?.OnCardHovered(this); } public void OnPointerExit(PointerEventData eventData) { if (_isPlaced) return; _isHovered = false; _handUI?.OnCardUnhovered(this); } public void OnPointerClick(PointerEventData eventData) { if (_isPlaced || eventData.button != PointerEventData.InputButton.Left) return; _isHovered = false; _handUI?.OnCardSelected(this); } /// /// Hides this card from the hand after placement on the board. /// public void MarkAsPlaced() { _isPlaced = true; gameObject.SetActive(false); } } }