using UnityEngine; using DG.Tweening; using CodeJay.Enum; using UnityEngine.EventSystems; using System.Collections; using UnityEngine.UI; using Unity.Profiling; using System.Collections.Generic; [System.Serializable] public class CardSlot : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerExitHandler { private class MoveSequenceInfo { private Sequence sequence = null; private bool isDiscardDirect = false; public Sequence Sequence { get { return sequence; } } public bool IsDiscardDirect { get { return isDiscardDirect; } } public MoveSequenceInfo(Sequence sequence, bool isDiscardDirect = false) { this.sequence = sequence; this.isDiscardDirect = isDiscardDirect; } } public const float TWEEN_DURATION = 0.25f; public const float TWEEN_DURATION_DISCARD = 0.5f; public const float TWEEN_DURATION_INTERACTION = 0.1f; public const float TWEEN_FROM_CENTER_TO_FLOOR = 0.75f; private static readonly Vector2 START_POSITION = new Vector2(1000, -1000); private static readonly Vector2 START_SIZE = new Vector2(132.21f, 199.485f); [SerializeField] private UnityEngine.UI.Image CardImage; [SerializeField] private Canvas _canvas; [SerializeField] private GraphicRaycaster _rayCaster; private PlayerGuideImage GuideImage; private IEnumerator _eDiscardDirect = null; private bool ShouldDestroy = false; public ECardType CardType { get; private set; } = ECardType.Max; public ECardLocationType LocationType { get; private set; } public ECardMonthType MonthType { get => CardType < ECardType.Back ? CodeJay.CodeJayUtility.Converter.CardTypeToMonthType(CardType) : ECardMonthType.Max; } public ECardScoreType ScoreType { get => CodeJay.CodeJayUtility.Converter.CardTypeToScoreType(CardType); } public EGuideType GuideType { get => GuideImage.guideType; set => GuideImage.SetData(value); } public bool GuideTypeImageEnabled { get => GuideImage.Enabled; set => GuideImage.Enabled = value; } public bool RaycastTarget { get => _rayCaster.enabled; set => _rayCaster.enabled = value; } private Queue _sequenceOrder = new Queue(); private void Awake() { if (CardImage == null) CardImage = this.GetComponent(); if (GuideImage == null) GuideImage = this.GetComponentInChildren(); if (GameManager.Instance != null) { GameManager.Event.RegistEvent(EEventType.OnGameEnd, this.OnGameEnd); } } private void OnDestroy() { if (GameManager.Instance != null) { GameManager.Event.RemoveEvent(EEventType.OnGameEnd, this.OnGameEnd); } } public void DestroyCardSlot() { ShouldDestroy = true; Destroy(this); } private void OnDisable() { if (DOTween.IsTweening(CardImage.rectTransform)) CardImage.rectTransform.DOKill(); } private void OnGameEnd() { if (DOTween.IsTweening(CardImage.rectTransform)) CardImage.rectTransform.DOKill(); StopAllCoroutines(); LocationType = ECardLocationType.Max; if (_eDiscardDirect != null) { StopCoroutine(_eDiscardDirect); _canvas.sortingOrder = 0; _canvas.overrideSorting = false; } GuideImage.SetData(EGuideType.None); } public void Initialize(RectTransform rt = null) { if (CardImage == null) CardImage = this.GetComponent(); if (GuideImage == null) GuideImage = this.GetComponentInChildren(); if (rt != null) { this.transform.SetParent(rt); } if (DOTween.IsTweening(CardImage.rectTransform)) CardImage.rectTransform.DOKill(); CardImage.enabled = false; CardImage.sprite = GameManager.Resource.GetSprite(ECardType.Back); CardImage.rectTransform.anchoredPosition = START_POSITION; CardImage.rectTransform.sizeDelta = START_SIZE; this.transform.localScale = Vector3.one; LocationType = ECardLocationType.Max; if (_eDiscardDirect != null) { StopCoroutine(_eDiscardDirect); _canvas.sortingOrder = 0; _canvas.overrideSorting = false; } GuideImage.SetData(EGuideType.None); _sequenceOrder.Clear(); } public void SetData(ECardType cardType) { CardType = cardType; CardImage.sprite = GameManager.Resource.GetSprite(CardType); } public void GuideImageEnabled(bool b) { if (b) { GuideImage.Enabled = LocationType == ECardLocationType.Player_Hand; } else GuideImage.Enabled = false; } public void Move(ECardLocationType fromLocation, ECardLocationType toLocation, RectTransform rectTransform, Ease ease = Ease.OutExpo, bool isDistribute = false) { if (toLocation == ECardLocationType.Max) this.gameObject.SetActive(false); else { this.moveTween(fromLocation, toLocation, rectTransform, ease, isDistribute); } } private void moveTween(ECardLocationType fromLocation, ECardLocationType toLocation, RectTransform rt, Ease ease, bool isDistribute) { LocationType = toLocation; if (rt == null) { this.SetImageByLocation(ECardLocationType.Max); throw new System.Exception($"Invalid Call. Methodname: {nameof(moveTween)}. rt is Null."); } else { Vector2 size = new Vector2(rt.rect.width, rt.rect.height); Vector2 pos = CardImage.rectTransform.position; CardImage.rectTransform.SetParent(rt, true); Sequence mySequence = null; MoveSequenceInfo info = null; if (isDistribute == false && fromLocation == ECardLocationType.Center && toLocation == ECardLocationType.Floor) { CardImage.rectTransform.localRotation = Quaternion.identity; CardImage.rectTransform.sizeDelta = size; mySequence = DOTween.Sequence().SetRecyclable(true).Pause(); mySequence.Append(CardImage.rectTransform.DOScale(Vector3.one * 3f, TWEEN_DURATION / GamePanel.GameSpeed).SetEase(Ease.OutQuint).From(new Vector3(0, 1, 1))) // LocalScale�� 1.25���� 1�� ���� �� AnchoredPosition �̵� .Append(CardImage.rectTransform.DOScale(1f, (TWEEN_DURATION / GamePanel.GameSpeed) / 2).SetEase(Ease.OutQuint)) .Join(CardImage.rectTransform.DOAnchorPos(Vector2.zero, (TWEEN_DURATION / GamePanel.GameSpeed) / 2).SetEase(Ease.OutQuint)); info = new MoveSequenceInfo(mySequence, true); /*if (_eDiscardDirect != null) StopCoroutine(_eDiscardDirect); _eDiscardDirect = this.coroOverrideSorting((TWEEN_DURATION * 1.5f) / GamePanel.GameSpeed); StartCoroutine(_eDiscardDirect);*/ } else if ((fromLocation == ECardLocationType.Player_Hand || fromLocation == ECardLocationType.AI_Hand) && toLocation == ECardLocationType.Floor) { CardImage.rectTransform.localRotation = Quaternion.identity; CardImage.rectTransform.sizeDelta = size; mySequence = DOTween.Sequence().SetRecyclable(true).Pause(); mySequence.Append(CardImage.rectTransform.DOScale(Vector3.one * 3f, TWEEN_DURATION / GamePanel.GameSpeed).SetEase(Ease.OutQuint).From(Vector3.one)) .Join(CardImage.rectTransform.DOAnchorPos(Vector2.zero, TWEEN_DURATION / GamePanel.GameSpeed).SetEase(Ease.OutQuint)) // LocalScale�� 1.25���� 1�� ���� �� AnchoredPosition �̵� .Append(CardImage.rectTransform.DOScale(1f, (TWEEN_DURATION / 2) / GamePanel.GameSpeed).SetEase(Ease.OutQuint).SetDelay((TWEEN_DURATION / 2) / GamePanel.GameSpeed)); info = new MoveSequenceInfo(mySequence, true); /*if (_eDiscardDirect != null) StopCoroutine(_eDiscardDirect); _eDiscardDirect = this.coroOverrideSorting((TWEEN_DURATION * 1.5f) / GamePanel.GameSpeed); StartCoroutine(_eDiscardDirect);*/ } else if (toLocation == ECardLocationType.Center) { mySequence = DOTween.Sequence().SetRecyclable(true).Pause(); mySequence.Append(CardImage.rectTransform.DOSizeDelta(size, (TWEEN_DURATION / GamePanel.GameSpeed)).SetEase(ease)) .Join(CardImage.rectTransform.DOScale(1, (TWEEN_DURATION / GamePanel.GameSpeed)).SetEase(ease)) .Join(CardImage.rectTransform.DOAnchorPos(Vector2.zero, (TWEEN_DURATION / GamePanel.GameSpeed)).SetEase(ease)) .Join(CardImage.rectTransform.DOLocalRotate(Vector3.forward * (Random.Range(-5f, 5f)), (TWEEN_DURATION / GamePanel.GameSpeed), RotateMode.FastBeyond360).SetEase(ease)); info = new MoveSequenceInfo(mySequence); } else { if (toLocation == ECardLocationType.Max) { throw new System.Exception($"Invalid Call. Methodname: {nameof(moveTween)}.\ntoLocation Type is Default."); } else { CardImage.rectTransform.localRotation = Quaternion.identity; mySequence = DOTween.Sequence().SetRecyclable(true).Pause(); mySequence.Append(CardImage.rectTransform.DOSizeDelta(size, (TWEEN_DURATION / GamePanel.GameSpeed)).SetEase(ease)) .Join(CardImage.rectTransform.DOScale(1, (TWEEN_DURATION / GamePanel.GameSpeed)).SetEase(ease)) .Join(CardImage.rectTransform.DOAnchorPos(Vector2.zero, (TWEEN_DURATION / GamePanel.GameSpeed)).SetEase(ease)); info = new MoveSequenceInfo(mySequence); } } if (info != null && info.Sequence != null) { //info.Sequence.Play(); info.Sequence.OnComplete(() => { if (_sequenceOrder.Count > 0) { _sequenceOrder.Dequeue(); if (_sequenceOrder.Count > 0) { _sequenceOrder.Peek().Sequence.Play(); if(_sequenceOrder.Peek().IsDiscardDirect) { if (_eDiscardDirect != null) StopCoroutine(_eDiscardDirect); _eDiscardDirect = this.coroOverrideSorting((TWEEN_DURATION * 1.5f) / GamePanel.GameSpeed); StartCoroutine(_eDiscardDirect); } } } }); _sequenceOrder.Enqueue(info); if (_sequenceOrder.Count == 1) { _sequenceOrder.Peek().Sequence.Play(); if (_sequenceOrder.Peek().IsDiscardDirect) { if (_eDiscardDirect != null) StopCoroutine(_eDiscardDirect); _eDiscardDirect = this.coroOverrideSorting((TWEEN_DURATION * 1.5f) / GamePanel.GameSpeed); StartCoroutine(_eDiscardDirect); } } } } this.SetImageByLocation(toLocation); } private IEnumerator coroRotateInCenter() { float cnt = TWEEN_DURATION; while (cnt > 0f) { cnt -= Time.deltaTime * GamePanel.GameSpeed; yield return null; } } private void SetImageByLocation(ECardLocationType location) { switch (location) { case ECardLocationType.Player_Hand: case ECardLocationType.Player_Score: case ECardLocationType.AI_Score: case ECardLocationType.Floor: CardImage.enabled = true; CardImage.sprite = GameManager.Resource.GetSprite(CardType); break; case ECardLocationType.AI_Hand: case ECardLocationType.Center: CardImage.enabled = true; CardImage.sprite = GameManager.Resource.GetSprite(ECardType.Back); break; default: CardImage.enabled = false; break; } } private IEnumerator coroOverrideSorting(float delay) { _canvas.overrideSorting = true; _canvas.sortingOrder = 1; yield return new WaitForSeconds(delay); _canvas.sortingOrder = 0; _eDiscardDirect = null; _canvas.overrideSorting = false; } #region Interaction Methods public void OnPointerDown(PointerEventData eventData) { if (CardType != ECardType.Max && LocationType == ECardLocationType.Player_Hand && GameManager.UI.IsAnyPopupOpened() == false) this.transform.DOScale(1.35f, (TWEEN_DURATION_INTERACTION / GamePanel.GameSpeed)).SetEase(Ease.OutExpo); } public void OnPointerClick(PointerEventData eventData) { if (CardType != ECardType.Max && LocationType == ECardLocationType.Player_Hand && GameManager.UI.IsAnyPopupOpened() == false) { if (GamePanel.Instance.DiscardisNull()) GamePanel.Instance.Discard(this); } } public void OnPointerExit(PointerEventData eventData) { if (LocationType == ECardLocationType.Player_Hand) this.transform.DOScale(1, (TWEEN_DURATION_INTERACTION / GamePanel.GameSpeed)).SetEase(Ease.OutExpo); } #endregion }