using System; using System.Collections; using System.Collections.Generic; using DG.Tweening; using TMPro.EditorUtilities; using UnityEngine; using UnityEngine.Android; 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); CombatScenarioEventOS.Instance.EVENT_TRIGGER(EventData.EVENT_REGISTER_CARD_ENUM.EVENT_LET_OS_SHUFFLE_CARD, new EventStruct.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_SELF_TURN_START(); // 开始乙方回合 REGISTER_EVENT_SELF_TURN_END(); // 系统结束回合 } private void REGISTER_EVENT_ENEMY_TURN_START() // 系统敌方回合开始 { StartCoroutine(coroutine()); IEnumerator coroutine() { for (var i = 0; i < 3; i++) { yield return new WaitForSeconds(1); } REGISTER_EVENT_ENEMY_TURN_END(); } } private void REGISTER_EVENT_ENEMY_TURN_END() { // 敌方阶段结束, // 转为我方阶段 CombatScenarioEventOS.Instance.EVENT_TRIGGER(EventData.EVENT_REGISTER_CARD_ENUM.EVENT_LET_OS_SHUFFLE_CARD, new EventStruct.STRUCT_EVENT_SHUFFLE_CARD { DECK_CARD_COUNT = defaultDeckNumber, HAND_CARD_COUNT = defaultCardNumber, DURATION = cardShuffleDuration, }); } private void REGISTER_EVENT_SELF_TURN_START() // 系统开始乙方回合 { // TODO: 增加洗牌消息监听 CombatScenarioEventOS.Instance.EVENT_REGISTER( EventData.EVENT_REGISTER_CARD_ENUM.EVENT_LET_OS_SHUFFLE_CARD, callback); return; void callback(EventStruct.STRUCT_EVENT_SHUFFLE_CARD args) { int handCardCount = args.HAND_CARD_COUNT; int deckCardCount = args.DECK_CARD_COUNT; float duration = args.DURATION; CombatScenarioEventOS.Instance.LOCK_APPLY(EventLock.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); } CombatScenarioEventOS.Instance.LOCK_RELEASE(EventLock.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_OS_SHUFFLE_CARD); // 系统发牌解锁 } } } private void REGISTER_EVENT_SELF_TURN_END() // 系统结束乙方回合 { CombatScenarioEventOS.Instance.EVENT_REGISTER(EventData.EVENT_REGISTER_CARD_ENUM.EVENT_LET_OS_END_TURN, callback); return; void callback(bool placeholder) { if (CombatScenarioEventOS.Instance.LOCK_GET(EventLock.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_OS_SHUFFLE_CARD)) return; // 系统是否正在洗牌 if (!CombatScenarioEventOS.Instance.LOCK_APPLY(EventLock.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_OS_DROP_CARD)) return; // 系统弃牌加锁失败 StartCoroutine(coroutine()); return; IEnumerator coroutine() { if (handCardList.Count > 0) { // for (var i = handCardList.Count; i >= 0; i--) for (var i = 0; i < handCardList.Count; i++) { CombatScenarioEventOS.Instance.EVENT_TRIGGER(EventData.EVENT_REGISTER_CARD_ENUM.EVENT_LET_CARD_DROP_SELF, new EventStruct.STRUCT_EVENT_DROP_CARD { ID = i, POSITION = drop_card_point_world_position, DURATION = cardDropDuration, }); yield return new WaitForSeconds(cardDropDuration); } } handCardList.Clear(); // 清空 CombatScenarioEventOS.Instance.LOCK_RELEASE(EventLock.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_OS_DROP_CARD); REGISTER_EVENT_ENEMY_TURN_START(); } } } 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); CombatScenarioEventOS.Instance.EVENT_TRIGGER(EventData.EVENT_REGISTER_CARD_ENUM.EVENT_LET_CARD_DRAW_CARD, new EventStruct.STRUCT_EVENT_DRAW_CARD { ID = i, POSITION = card_world_position, ROTATION = rotation, DURATION = duration, LAYER_SORT_ORDER = i + 1, SCALE = Vector3.one, }); } } } }