2024-09-12 04:17:34 +00:00
|
|
|
using System;
|
2024-09-09 09:50:37 +00:00
|
|
|
using System.Collections;
|
2024-09-12 04:17:34 +00:00
|
|
|
using BlueWater;
|
2024-09-09 09:50:37 +00:00
|
|
|
using BlueWater.Tycoons;
|
2024-09-12 04:17:34 +00:00
|
|
|
using SingularityGroup.HotReload;
|
|
|
|
using Sirenix.OdinInspector;
|
2024-09-09 09:50:37 +00:00
|
|
|
using UnityEngine;
|
2024-09-12 04:17:34 +00:00
|
|
|
using TMPro;
|
|
|
|
using UnityEngine.EventSystems;
|
|
|
|
using UnityEngine.UI;
|
|
|
|
using Object = UnityEngine.Object; // TextMeshPro 네임스페이스 추가
|
2024-09-09 09:50:37 +00:00
|
|
|
|
2024-09-12 04:17:34 +00:00
|
|
|
|
|
|
|
public enum Acceleration
|
|
|
|
{
|
|
|
|
|
|
|
|
None = default,
|
|
|
|
EaseExpoIn,
|
|
|
|
EaseExpoOut,
|
|
|
|
EaseBounceIn,
|
|
|
|
EaseBounceOut,
|
|
|
|
|
|
|
|
// EaseBounceOut = None
|
|
|
|
//아직 정해지지 않은건 None표시
|
|
|
|
}
|
|
|
|
|
2024-09-12 07:38:16 +00:00
|
|
|
public class TycoonCard : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler ,IPointerMoveHandler
|
2024-09-09 09:50:37 +00:00
|
|
|
{
|
2024-09-12 04:17:34 +00:00
|
|
|
|
|
|
|
[field: Title("카드 속성")]
|
|
|
|
|
|
|
|
private CardData _cardData_IDX;
|
|
|
|
[field: SerializeField, CLabel("IDX"), ReadOnly]
|
|
|
|
private string _cardData = "AddAllLiquid";
|
|
|
|
|
|
|
|
[field: SerializeField, CLabel("카드 이름")]
|
|
|
|
private string CardName;
|
|
|
|
//[field: SerializeField, CLabel("카드 이미지")]
|
|
|
|
//private Image CardImage;
|
|
|
|
[field: SerializeField, CLabel("카드 텍스트")]
|
|
|
|
private string CardText;
|
|
|
|
|
|
|
|
private Coroutine currentRotationCoroutine;
|
|
|
|
[field: Title("카드 회전")]
|
|
|
|
[field: SerializeField, CLabel("카드 회전 속도")]
|
|
|
|
private float RotationDurationCard = 1.0f;
|
|
|
|
[field: SerializeField, CLabel("회전 가속 종류")]
|
|
|
|
public Acceleration AccelerationCard;
|
|
|
|
|
2024-09-12 07:38:16 +00:00
|
|
|
[field: Title("부가효과 : 카드 기울기")]
|
|
|
|
[field: SerializeField, CLabel("최대 기울기(각도)")]
|
|
|
|
private float maxRotationAngle = 15f;
|
|
|
|
[field: SerializeField, CLabel("기울기 복원 속도")]
|
|
|
|
private float returnSpeed = 1.0f;
|
|
|
|
private bool isPointerInside; // 이미지 안에 마우스가 있는지 여부를 추적
|
|
|
|
private Coroutine moveRotationCoroutine;
|
|
|
|
private Coroutine endRotationCoroutine;
|
|
|
|
|
|
|
|
private Image image;
|
|
|
|
|
|
|
|
private RectTransform rectTransform;
|
|
|
|
|
|
|
|
void Start()
|
|
|
|
{
|
|
|
|
rectTransform = GetComponent<RectTransform>();
|
|
|
|
_cardData_IDX = TycoonManager.Instance.GetCardDataByIdx(_cardData);
|
|
|
|
|
|
|
|
Transform nameTransform = transform.Find("Name");
|
|
|
|
Transform infoTransform = transform.Find("Infomation");
|
|
|
|
|
|
|
|
TextMeshProUGUI nametextComponent = nameTransform.GetComponent<TextMeshProUGUI>();
|
|
|
|
nametextComponent.text = _cardData_IDX.Img;
|
|
|
|
|
|
|
|
TextMeshProUGUI infotextComponent = infoTransform.GetComponent<TextMeshProUGUI>();
|
|
|
|
infotextComponent.text = _cardData_IDX.ScriptText;
|
|
|
|
|
|
|
|
image = transform.Find("Image").GetComponent<Image>();
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-09-12 04:17:34 +00:00
|
|
|
|
|
|
|
[Button("회전")]
|
|
|
|
public void Rotation_Start()
|
2024-09-09 09:50:37 +00:00
|
|
|
{
|
2024-09-12 04:17:34 +00:00
|
|
|
RectTransform rectTransform = this.GetComponent<RectTransform>();
|
|
|
|
rectTransform.localRotation = Quaternion.Euler(0,-180,0);
|
|
|
|
|
|
|
|
if (currentRotationCoroutine != null)
|
|
|
|
{
|
|
|
|
StopCoroutine(currentRotationCoroutine);
|
|
|
|
currentRotationCoroutine = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
currentRotationCoroutine = StartCoroutine(RotateOverTime());
|
|
|
|
|
2024-09-12 07:36:24 +00:00
|
|
|
var cardData = TycoonManager.Instance.CardDataSo.GetDataByIdx(_cardData);
|
2024-09-12 04:17:34 +00:00
|
|
|
|
|
|
|
// Resources.Load()
|
2024-09-09 09:50:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-09-12 04:17:34 +00:00
|
|
|
void Start()
|
|
|
|
{
|
2024-09-12 07:36:24 +00:00
|
|
|
_cardData_IDX = TycoonManager.Instance.CardDataSo.GetDataByIdx(_cardData);
|
2024-09-12 04:17:34 +00:00
|
|
|
|
|
|
|
Transform nameTransform = transform.Find("Name");
|
|
|
|
Transform infoTransform = transform.Find("Infomation");
|
|
|
|
|
|
|
|
TextMeshProUGUI nametextComponent = nameTransform.GetComponent<TextMeshProUGUI>();
|
|
|
|
nametextComponent.text = _cardData_IDX.Img;
|
|
|
|
|
|
|
|
TextMeshProUGUI infotextComponent = infoTransform.GetComponent<TextMeshProUGUI>();
|
|
|
|
infotextComponent.text = _cardData_IDX.ScriptText;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 마우스가 이미지 위에 올라갔을 때 호출
|
|
|
|
public void OnPointerEnter(PointerEventData eventData)
|
|
|
|
{
|
2024-09-12 07:38:16 +00:00
|
|
|
if (endRotationCoroutine != null)
|
|
|
|
{
|
|
|
|
StopCoroutine(endRotationCoroutine);
|
|
|
|
endRotationCoroutine = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
isPointerInside = true;
|
2024-09-12 04:17:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 마우스가 이미지에서 벗어났을 때 호출
|
|
|
|
public void OnPointerExit(PointerEventData eventData)
|
|
|
|
{
|
2024-09-12 07:38:16 +00:00
|
|
|
image.color = new Color(1.0f,1.0f,1.0f,1.0f);
|
|
|
|
|
|
|
|
if (endRotationCoroutine != null)
|
|
|
|
{
|
|
|
|
StopCoroutine(endRotationCoroutine);
|
|
|
|
endRotationCoroutine = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (moveRotationCoroutine != null)
|
|
|
|
{
|
|
|
|
StopCoroutine(moveRotationCoroutine);
|
|
|
|
moveRotationCoroutine = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
endRotationCoroutine = StartCoroutine(ReturnToZeroRotation());
|
|
|
|
|
|
|
|
isPointerInside = false;
|
2024-09-12 04:17:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 마우스 클릭 시 호출
|
|
|
|
public void OnPointerClick(PointerEventData eventData)
|
|
|
|
{
|
|
|
|
Debug.Log("ClickMouse");
|
2024-09-12 07:38:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void OnPointerMove(PointerEventData eventData)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (endRotationCoroutine != null)
|
|
|
|
{
|
|
|
|
StopCoroutine(endRotationCoroutine);
|
|
|
|
endRotationCoroutine = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (moveRotationCoroutine != null)
|
|
|
|
{
|
|
|
|
StopCoroutine(moveRotationCoroutine);
|
|
|
|
moveRotationCoroutine = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
moveRotationCoroutine = StartCoroutine(SmoothMoveToMouse(eventData));
|
2024-09-12 04:17:34 +00:00
|
|
|
}
|
|
|
|
|
2024-09-12 07:38:16 +00:00
|
|
|
// 마우스의 움직임을 천천히 따라가도록 하는 코루틴
|
|
|
|
private IEnumerator SmoothMoveToMouse(PointerEventData eventData)
|
|
|
|
{
|
|
|
|
while (isPointerInside)
|
|
|
|
{
|
|
|
|
Vector2 localPoint;
|
|
|
|
|
|
|
|
// 마우스 포인터의 화면 좌표(eventData.position)를 이미지의 로컬 좌표(localPoint)로 변환
|
|
|
|
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, out localPoint))
|
|
|
|
{
|
|
|
|
// 이미지 내에서의 좌표를 정규화된 값으로 변환 (0,0)이 이미지의 왼쪽 아래, (1,1)이 오른쪽 위
|
|
|
|
Vector2 normalizedPoint = new Vector2(
|
|
|
|
(localPoint.x - rectTransform.rect.xMin) / rectTransform.rect.width,
|
|
|
|
(localPoint.y - rectTransform.rect.yMin) / rectTransform.rect.height
|
|
|
|
);
|
|
|
|
|
|
|
|
// 좌표를 중심 기준으로 (-0.5, -0.5)에서 (0.5, 0.5)로 변환 (이미지 중앙이 0,0이 되도록)
|
|
|
|
Vector2 centeredNormalizedPoint = normalizedPoint - new Vector2(0.5f, 0.5f);
|
|
|
|
|
|
|
|
// X와 Y축의 회전 각도를 마우스 위치에 따라 계산 (최대 회전 각도를 15도로 제한)
|
|
|
|
float targetRotationX = Mathf.Clamp(centeredNormalizedPoint.y * maxRotationAngle * 2, -maxRotationAngle, maxRotationAngle);
|
|
|
|
float targetRotationY = Mathf.Clamp(-centeredNormalizedPoint.x * maxRotationAngle * 2, -maxRotationAngle, maxRotationAngle);
|
|
|
|
|
|
|
|
// 현재 회전 값
|
|
|
|
Vector3 currentRotation = rectTransform.localRotation.eulerAngles;
|
|
|
|
|
|
|
|
// 목표 회전 값으로 부드럽게 이동 (Slerp)
|
|
|
|
float rotationX = Mathf.LerpAngle(currentRotation.x, targetRotationX, Time.deltaTime * 1.0f);
|
|
|
|
float rotationY = Mathf.LerpAngle(currentRotation.y, targetRotationY, Time.deltaTime * 1.0f);
|
|
|
|
|
|
|
|
// 회전을 적용 (X축은 위아래 기울기, Y축은 좌우 기울기)
|
|
|
|
rectTransform.localRotation = Quaternion.Euler(rotationX, rotationY, 0f);
|
|
|
|
|
|
|
|
// 천천히 이동하므로 매 프레임마다 기다림
|
|
|
|
yield return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private IEnumerator ReturnToZeroRotation()
|
|
|
|
{
|
|
|
|
Quaternion startRotation = rectTransform.localRotation;
|
|
|
|
Quaternion endRotation = Quaternion.identity;
|
|
|
|
float timeElapsed = 0f;
|
|
|
|
|
|
|
|
while (timeElapsed < 1f)
|
|
|
|
{
|
|
|
|
// 점진적으로 원래 회전 상태로 돌아가기
|
|
|
|
rectTransform.localRotation = Quaternion.Slerp(startRotation, endRotation, timeElapsed);
|
|
|
|
timeElapsed += Time.deltaTime * returnSpeed;
|
|
|
|
yield return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 최종적으로 완전한 초기 회전 상태로 설정
|
|
|
|
rectTransform.localRotation = Quaternion.identity;
|
|
|
|
endRotationCoroutine = null;
|
|
|
|
}
|
2024-09-12 04:17:34 +00:00
|
|
|
|
|
|
|
private IEnumerator RotateOverTime()
|
2024-09-09 09:50:37 +00:00
|
|
|
{
|
|
|
|
RectTransform rectTransform = this.GetComponent<RectTransform>();
|
|
|
|
Transform backObject = rectTransform.Find("Back");
|
2024-09-12 04:17:34 +00:00
|
|
|
backObject.gameObject.SetActive(true);
|
2024-09-09 09:50:37 +00:00
|
|
|
Quaternion startRotation = rectTransform.localRotation;
|
2024-09-12 04:17:34 +00:00
|
|
|
Quaternion targetRotation = Quaternion.Euler(0, 0, 0);
|
2024-09-09 09:50:37 +00:00
|
|
|
|
|
|
|
float elapsedTime = 0f;
|
|
|
|
|
2024-09-12 04:17:34 +00:00
|
|
|
while (elapsedTime < RotationDurationCard)
|
2024-09-09 09:50:37 +00:00
|
|
|
{
|
|
|
|
elapsedTime += Time.deltaTime;
|
|
|
|
|
2024-09-12 04:17:34 +00:00
|
|
|
float t = elapsedTime / RotationDurationCard;
|
|
|
|
float easedT = t;
|
|
|
|
|
|
|
|
if (AccelerationCard == Acceleration.EaseExpoIn) easedT = Mathf.Pow(2, 10 * (t - 1)) ;
|
|
|
|
else if (AccelerationCard == Acceleration.EaseExpoOut) easedT = 1 - Mathf.Pow(2, -10 * t);
|
|
|
|
else if (AccelerationCard == Acceleration.EaseBounceIn) easedT = 1 - BounceOut(1 - t);
|
|
|
|
else if (AccelerationCard == Acceleration.EaseBounceOut) easedT = BounceOut(t);
|
2024-09-09 09:50:37 +00:00
|
|
|
|
|
|
|
rectTransform.localRotation = Quaternion.Lerp(startRotation, targetRotation, easedT);
|
|
|
|
|
|
|
|
float currentYRotation = rectTransform.localRotation.eulerAngles.y;
|
2024-09-12 04:17:34 +00:00
|
|
|
|
2024-09-09 09:50:37 +00:00
|
|
|
if (currentYRotation <= 90.0f && backObject.gameObject.activeSelf)
|
|
|
|
{
|
|
|
|
backObject.gameObject.SetActive(false);
|
|
|
|
}
|
2024-09-12 04:17:34 +00:00
|
|
|
|
2024-09-09 09:50:37 +00:00
|
|
|
yield return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
rectTransform.localRotation = targetRotation;
|
|
|
|
}
|
2024-09-12 04:17:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//가속도를 위한 함수...▼
|
|
|
|
float BounceOut(float t)
|
|
|
|
{
|
|
|
|
if (t < (1 / 2.75f))
|
|
|
|
{
|
|
|
|
return 7.5625f * t * t;
|
|
|
|
}
|
|
|
|
else if (t < (2 / 2.75f))
|
|
|
|
{
|
|
|
|
t -= (1.5f / 2.75f);
|
|
|
|
return 7.5625f * t * t + 0.75f;
|
|
|
|
}
|
|
|
|
else if (t < (2.5f / 2.75f))
|
|
|
|
{
|
|
|
|
t -= (2.25f / 2.75f);
|
|
|
|
return 7.5625f * t * t + 0.9375f;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
t -= (2.625f / 2.75f);
|
|
|
|
return 7.5625f * t * t + 0.984375f;
|
|
|
|
}
|
|
|
|
}
|
2024-09-09 09:50:37 +00:00
|
|
|
}
|