262 lines
9.1 KiB
C#
262 lines
9.1 KiB
C#
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<TycoonCard> _onSelectAction;
|
|
|
|
private void Awake()
|
|
{
|
|
_tycoonCard = transform.parent.GetComponent<TycoonCard>();
|
|
_rectTransform = GetComponent<RectTransform>();
|
|
_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<TycoonCard> 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<TycoonSelectCard>().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<RectTransform>().localRotation;
|
|
Quaternion startRotationImg = _cardImage.GetComponent<RectTransform>().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<RectTransform>().localRotation =
|
|
Quaternion.Slerp(startRotation, endRotation, 1.0f - _returnSpeedTime);
|
|
_cardImage.GetComponent<RectTransform>().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<RectTransform>().localRotation = Quaternion.identity;
|
|
_cardImage.GetComponent<RectTransform>().localRotation = Quaternion.identity;
|
|
_endRotationCoroutine = null;
|
|
}
|
|
|
|
|
|
private void RotateCard()
|
|
{
|
|
Vector3 initialScale = _panel.localScale;
|
|
Vector3 targetScale = new Vector3(1.05f, 1.05f, 1.0f); // 타겟 스케일 설정
|
|
|
|
// 마우스 포인터의 화면 좌표(eventData.position)를 이미지의 로컬 좌표(localPoint)로 변환
|
|
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(_rectTransform, Input.mousePosition, _uiCamera,
|
|
out var localPoint))
|
|
{
|
|
// RectTransform의 중심을 기준으로 정규화된 값으로 변환
|
|
Vector2 normalizedPoint = new Vector2(
|
|
(localPoint.x / _rectTransform.rect.width) + 0.5f,
|
|
(localPoint.y / _rectTransform.rect.height) + 0.5f
|
|
);
|
|
|
|
// 좌표를 중심 기준으로 (-0.5, -0.5)에서 (0.5, 0.5)로 변환 (이미지 중앙이 0,0이 되도록)
|
|
Vector2 centeredNormalizedPoint = normalizedPoint - new Vector2(0.5f, 0.5f);
|
|
|
|
// 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);
|
|
|
|
// 회전을 적용 (X축은 위아래 기울기, Y축은 좌우 기울기)
|
|
_panel.GetComponent<RectTransform>().localRotation =
|
|
Quaternion.Euler(rotationX, rotationY, 0f);
|
|
_cardImage.GetComponent<RectTransform>().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);
|
|
}
|
|
}
|
|
} |