using System; using System.Collections; using System.Collections.Generic; using DG.Tweening; using TMPro.EditorUtilities; using UnityEngine; using UnityEngine.Splines; public class CardManager : MonoBehaviour { // ======== serializeField ======== [SerializeField] private int defaultDeckNumber = 21; // 默认牌组数量 [SerializeField] private int defaultCardNumber = 5; // 默认手牌数量 // [SerializeField] private int maxCardNumber = 9; // 最大卡牌数量 [SerializeField] private List cardPrefabs; [SerializeField] private SplineContainer splineContainer; [SerializeField] private RectTransform dealCardPlace; [SerializeField] private RectTransform dropCardPlace; [SerializeField] private Camera mainCamera; [SerializeField] private Transform cardContainer; [SerializeField] private float cardShuffleDuration = 0.25f; [SerializeField] private float cardDropDuration = 0.2f; // ======== private ======== // private readonly List hand_card_list = new List(); private readonly List handCardList = new(); private Vector3 deal_card_point_world_position; private Vector3 drop_card_point_world_position; private void Start() { RectTransformUtility.ScreenPointToWorldPointInRectangle( rect: dealCardPlace, screenPoint: dealCardPlace.position, cam: mainCamera, out deal_card_point_world_position); RectTransformUtility.ScreenPointToWorldPointInRectangle( rect: dropCardPlace, screenPoint: dropCardPlace.position, cam: mainCamera, out drop_card_point_world_position); CardOS.Instance.EVENT_TRIGGER(CardOSData.EVENT_REGISTER_CARD_ENUM.EVENT_LET_OS_SHUFFLE_CARD, new CardOSData.STRUCT_EVENT_SHUFFLE_CARD { DECK_CARD_COUNT = defaultDeckNumber, HAND_CARD_COUNT = defaultCardNumber, DURATION = cardShuffleDuration, }); } private void Awake() { REGISTER_EVENT(); } private void REGISTER_EVENT() { REGISTER_EVENT_SHUFFLE_CARD(); // 系统洗牌 REGISTER_EVENT_FOLD_CARD(); // 系统弃牌 } private void REGISTER_EVENT_SHUFFLE_CARD() { CardOS.Instance.EVENT_REGISTER( CardOSData.EVENT_REGISTER_CARD_ENUM.EVENT_LET_OS_SHUFFLE_CARD, callback); return; void callback(CardOSData.STRUCT_EVENT_SHUFFLE_CARD args) { int handCardCount = args.HAND_CARD_COUNT; int deckCardCount = args.DECK_CARD_COUNT; float duration = args.DURATION; CardOS.Instance.LOCK_APPLY(CardOSData.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_OS_SHUFFLE_CARD); // 系统洗牌加锁 StartCoroutine(coroutine()); return; IEnumerator coroutine() { for (var i = 0; i < handCardCount; i++) { create_a_card(duration); yield return new WaitForSeconds(duration); } CardOS.Instance.LOCK_RELEASE(CardOSData.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_OS_SHUFFLE_CARD); // 系统洗牌解锁 } } } private void REGISTER_EVENT_FOLD_CARD() { CardOS.Instance.EVENT_REGISTER(CardOSData.EVENT_REGISTER_CARD_ENUM.EVENT_LET_OS_FOLD_CARD, callback); return; void callback(bool placeholder) { if (CardOS.Instance.LOCK_GET(CardOSData.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_OS_SHUFFLE_CARD)) return; StartCoroutine(coroutine()); return; IEnumerator coroutine() { CardOS.Instance.LOCK_APPLY(CardOSData.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_OS_DROP_CARD); for (var i = handCardList.Count; i >= 0; i--) { CardOS.Instance.EVENT_TRIGGER(CardOSData.EVENT_REGISTER_CARD_ENUM.EVENT_LET_CARD_DROP_SELF, new CardOSData.STRUCT_EVENT_DROP_CARD { ID = i, POSITION = drop_card_point_world_position, DURATION = cardDropDuration, }); yield return new WaitForSeconds(cardDropDuration); } handCardList.Clear(); // 清空 CardOS.Instance.LOCK_RELEASE(CardOSData.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_OS_DROP_CARD); } } } private void create_a_card(float duration) { GameObject _card = Instantiate( cardPrefabs[UnityEngine.Random.Range(0, cardPrefabs.Count)], position: deal_card_point_world_position, rotation: Quaternion.identity, parent: cardContainer); _card.gameObject.name = $"Card_{handCardList.Count}"; Card cardComponent = _card.GetComponent(); cardComponent.SetID(handCardList.Count); handCardList.Add(cardComponent); draw_a_card(duration); } private void draw_a_card(float duration) { int handCardListCount = handCardList.Count; if (handCardListCount == 0) return; float cardSpacing = handCardListCount switch // 动态调整卡牌间距 { <= 4 => 0.5f / (handCardListCount + 1), <= 5 => 0.75f / (handCardListCount + 1), _ => 1f / (handCardListCount + 1) }; float firstCardPosition = 0.5f - (handCardListCount - 1) * cardSpacing / 2; // 获取第一个卡牌的位置 Spline spline = splineContainer.Spline; // 获取曲线 draw_card(); return; void draw_card() { for (int i = 0; i < handCardListCount; i++) { float position = firstCardPosition + i * cardSpacing; Vector3 card_world_position = spline.EvaluatePosition(position); // 获取曲线指定位置的坐标 card_world_position += cardContainer.position; Vector3 forward = spline.EvaluateTangent(position); // 获取曲线指定的切线方向 Vector3 up = spline.EvaluateUpVector(position); // 获取曲线指定的UP向量 Vector3 upwards = Vector3.Cross(up, forward).normalized; // 切线和向上的夹角计算方向 Quaternion rotation = Quaternion.LookRotation(up, upwards); CardOS.Instance.EVENT_TRIGGER(CardOSData.EVENT_REGISTER_CARD_ENUM.EVENT_LET_CARD_DRAW_CARD, new CardOSData.STRUCT_EVENT_DRAW_CARD { ID = i, POSITION = card_world_position, ROTATION = rotation, DURATION = duration, LAYER_SORT_ORDER = i + 1, SCALE = Vector3.one, }); } } } }