using System; using System.Collections; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; /* * 마우스와 카드의 상호작용 * 마우스가 올라왔을 때와 움직일때, 클릭하는 곳의 범위를 지정하고 해당 범위에 맞춰서 카드의 움직임과 효과를 담당한다. */ /* *To do *회전하는 객체 가져오기 * 그림은 덜 회전하도록 하기 (절반 이상) * 카드 회전(돌아가는거), 획득, 등장은 따로 빼놓고 Card 스크립트에 분리시켜놓기 */ namespace BlueWater.Uis { public class TycoonCardArea : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler, IPointerMoveHandler { private Coroutine _currentRotationCoroutine; private float _maxRotationAngle; private float _returnSpeed; private TycoonCard _tycoonCard; //부모 private float _returnSpeedTime = 0.0f; // 복원속도를 더할 메서드 private bool _isPointerInside; // 이미지 안에 마우스가 있는지 여부를 추적 private Coroutine _startRotationCoroutine; private Coroutine _endRotationCoroutine; private Image _cardImage; private RectTransform _rectTransform; private Transform _panel; private Camera _uiCamera; //Area 활성화 유무 private bool _enable = false; private Action _onSelectAction; private void Awake() { _tycoonCard = transform.parent.GetComponent(); _rectTransform = GetComponent(); _panel = _tycoonCard.Panel; _cardImage = _tycoonCard.CardImage; _maxRotationAngle = _tycoonCard.maxRotationAngle; _returnSpeed = _tycoonCard.returnSpeed; } private void Start() { _uiCamera = TycoonCameraManager.Instance.UiCamera; } public void SetEnable(bool val) { _enable = val; } public void SetselectAction(Action action) { _onSelectAction = action; } // 마우스가 이미지 위에 올라갔을 때 호출 public void OnPointerEnter(PointerEventData eventData) { if (_endRotationCoroutine != null) { StopCoroutine(_endRotationCoroutine); _endRotationCoroutine = null; } if (_startRotationCoroutine != null) { StopCoroutine(_startRotationCoroutine); _startRotationCoroutine = null; } if (_enable) { if (_currentRotationCoroutine != null) { StopCoroutine(_currentRotationCoroutine); _currentRotationCoroutine = null; } _startRotationCoroutine = StartCoroutine(StartToRotation()); } } // 마우스가 이미지에서 벗어났을 때 호출 public void OnPointerExit(PointerEventData eventData) { if (_enable) { if (_endRotationCoroutine != null) { StopCoroutine(_endRotationCoroutine); _endRotationCoroutine = null; } if (_startRotationCoroutine != null) { StopCoroutine(_startRotationCoroutine); _startRotationCoroutine = null; } } if (_enable) { _isPointerInside = false; _endRotationCoroutine = StartCoroutine(ReturnToZeroRotation()); } } // 마우스 클릭 시 호출 public void OnPointerClick(PointerEventData eventData) { if (_enable) { //_tycoonCard.transform.parent.parent.GetComponent().SelectedCard(_tycoonCard); if (_onSelectAction != null) { _onSelectAction?.Invoke(_tycoonCard); //OnPointerExit(null); } //해당 밑줄은 따로 메소드를 만들어주자... 여기서 호출하는게 아니라 SelectCardUi에서 호출받는 방식으로... //this.SetEnable(false); //_isPointerInside = false; } } public void OnPointerMove(PointerEventData eventData) { if (_isPointerInside) { RotateCard(); } } public void SuccessClick() { if (!_enable) return; OnPointerExit(null); SetEnable(false); _isPointerInside = false; } // ReSharper disable Unity.PerformanceAnalysis private IEnumerator StartToRotation() { if (_endRotationCoroutine != null) { StopCoroutine(_endRotationCoroutine); _endRotationCoroutine = null; } while (_returnSpeedTime < 1.0f) { _returnSpeedTime += Time.unscaledDeltaTime * _returnSpeed; RotateCard(); yield return null; } _isPointerInside = true; _returnSpeedTime = 1.0f; } // ReSharper disable Unity.PerformanceAnalysis private IEnumerator ReturnToZeroRotation() { if (_startRotationCoroutine != null) { StopCoroutine(_startRotationCoroutine); _startRotationCoroutine = null; } Quaternion startRotation = _panel.GetComponent().localRotation; Quaternion startRotationImg = _cardImage.GetComponent().localRotation; Quaternion endRotation = Quaternion.identity; Vector3 initialScale = _panel.localScale; Vector3 targetScale = new Vector3(0.95f, 0.95f, 0.95f); while (_returnSpeedTime > 0.0f) { _panel.GetComponent().localRotation = Quaternion.Slerp(startRotation, endRotation, 1.0f - _returnSpeedTime); _cardImage.GetComponent().localRotation = Quaternion.Slerp(startRotationImg, endRotation, 1.0f - _returnSpeedTime); _returnSpeedTime -= Time.unscaledDeltaTime * _returnSpeed; float t = (1.0f - _returnSpeedTime); t = 1 - Mathf.Pow(2, -10 * t); _panel.localScale = Vector3.Lerp(initialScale, targetScale, t); yield return null; } _returnSpeedTime = 0.0f; _panel.GetComponent().localRotation = Quaternion.identity; _cardImage.GetComponent().localRotation = Quaternion.identity; _endRotationCoroutine = null; } private void RotateCard() { Vector3 initialScale = _panel.localScale; Vector3 targetScale = new Vector3(1.05f, 1.05f, 1.0f); // 타겟 스케일 설정 /* // RectTransform의 화면 좌표를 가져오기 위한 변수 RectTransform rectTransform = GetComponent(); if (RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, Input.mousePosition, null, out var localPoint)) { // RectTransform의 크기를 기준으로 좌표를 정규화 Vector2 normalizedPoint = new Vector2( localPoint.x / rectTransform.rect.width, localPoint.y / rectTransform.rect.height ); // 좌표를 중심 기준으로 (-0.5, -0.5)에서 (0.5, 0.5)로 변환 Vector2 centeredNormalizedPoint = normalizedPoint * 2f; // Debug.Log($"Normalized Point: {centeredNormalizedPoint}"); // X와 Y축의 회전 각도를 마우스 위치에 따라 계산 (최대 회전 각도를 15도로 제한) float rotationX = Mathf.Clamp(-centeredNormalizedPoint.y * _maxRotationAngle * 2 * _returnSpeedTime, -_maxRotationAngle, _maxRotationAngle); float rotationY = Mathf.Clamp(centeredNormalizedPoint.x * _maxRotationAngle * 2 * _returnSpeedTime, -_maxRotationAngle, _maxRotationAngle); Debug.Log($"Normalized Point: {rotationX} x {rotationY}"); // 회전을 적용 (X축은 위아래 기울기, Y축은 좌우 기울기) _panel.GetComponent().localRotation = Quaternion.Euler(rotationX, rotationY, 0f); _cardImage.GetComponent().localRotation = Quaternion.Euler(-rotationX, 0f, 0f); } */ // 스케일 보간 (Lerp) float t = Mathf.Clamp01(_returnSpeedTime); float easedT = 1 - Mathf.Pow(2, -10 * t); // 스케일을 Lerp 함수를 사용하여 보간 _panel.localScale = Vector3.Lerp(initialScale, targetScale, easedT); } } }