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 maxCardNumber = 10; [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 cardDotweenDuration = 0.25f; // ======== private ======== // private readonly List hand_card_list = new List(); private readonly List card_list = new List(); 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); REGISTER_EVENT(); } private int cardListNum; private void REGISTER_EVENT() { // 系统发牌事件 CardOS.Instance.EVENT_REGISTER(CardOSData.EVENT_REGISTER_CARD_ENUM.EVENT_LET_OS_DEAL_CARD_FINISH, callback); void callback(int id) { cardListNum--; if (cardListNum > 0) return; // 还有卡牌没处理完 CardOS.Instance.LOCK_RELEASE(CardOSData.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_OS_DEAL_CARD); } } private void Update() { if (Input.GetKeyDown(KeyCode.Space)) { if (CardOS.Instance.LOCK_GET(CardOSData.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_I_DRAG_CARD)) { Debug.LogError($"状态已被锁定: {CardOSData.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_I_DRAG_CARD}"); return; } if (CardOS.Instance.LOCK_GET(CardOSData.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_OS_DROP_CARD)) { Debug.LogError($"状态已被锁定: {CardOSData.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_I_DRAG_CARD}"); return; } if (card_list.Count >= maxCardNumber) return; this.m_self_create_card(); } else if (Input.GetKeyDown(KeyCode.R)) { this.m_self_drop_all_card(); } } private void m_self_drop_all_card() { float duration = cardDotweenDuration - 0.1f; { StartCoroutine(coroutine()); } IEnumerator coroutine() { CardOS.Instance.LOCK_APPLY(CardOSData.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_OS_DROP_CARD); for (var i = card_list.Count; i >= 0; i--) { CardOS.Instance.EVENT_TRIGGER(CardOSData.EVENT_REGISTER_CARD_ENUM.EVENT_LET_ME_DROP_CARD, new CardOSData.STRUCT_EVENT_DROP_CARD { ID = i, POSITION = drop_card_point_world_position, DURATION = duration, }); yield return new WaitForSeconds(duration); } card_list.Clear(); // 清空 CardOS.Instance.LOCK_RELEASE(CardOSData.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_OS_DROP_CARD); } } private void m_self_create_card() { 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_{card_list.Count}"; _card.gameObject.GetComponent().SetID(card_list.Count); card_list.Add(_card); this.m_self_update_card_position(); } private void m_self_update_card_position() { int hand_card_list_count = card_list.Count; if (hand_card_list_count == 0) return; // 卡牌间距 float card_spacing = hand_card_list_count switch { <= 4 => 0.5f / (hand_card_list_count + 1), <= 5 => 0.75f / (hand_card_list_count + 1), _ => 1f / (hand_card_list_count + 1) }; float first_card_position = 0.5f - (hand_card_list_count - 1) * card_spacing / 2; // 获取第一个卡牌的位置 Spline spline = splineContainer.Spline; // 获取曲线 coroutine(); // StartCoroutine(coroutine()); void coroutine() { CardOS.Instance.LOCK_APPLY(CardOSData.LOCK_EXCLUSIVE_CARD_ENUM.LOCK_OS_DEAL_CARD); for (int i = 0; i < hand_card_list_count; i++) { cardListNum = hand_card_list_count; float position = first_card_position + i * card_spacing; 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_ME_DRAW_CARD, new CardOSData.STRUCT_EVENT_DRAW_CARD { ID = i, POSITION = card_world_position, ROTATION = rotation, DURATION = cardDotweenDuration, LAYER_SORT_ORDER = i + 1, SCALE = Vector3.one, }); // yield return new WaitUntil(() => // !CardOS.Instance.LOCK_GET(CardOSData.LOCK_EXCLUSIVE_CARD_ENUM.SORRY_PLEASE_LOCK_I_MOVE_CARD) // ); } } } }