using System.Collections; using System.Collections.Generic; using DG.Tweening; using MYp0ZVTT2QSDK; using NPOI.SS.Formula.Functions; using UnityEngine; public class CreatCard : MonoBehaviour { private Dictionary materialDict; public Camera main_camera; // private List Card_gameobject_list = new List(); // Start is called before the first frame update private int _sortingOrder = 0; private int hand_card_num = -1; Vector3 hand_card_pos = new Vector3(2.3f, -6, 0); Vector3 dark_hand_card_pos = new Vector3(0.3f, -6, 0); void Awake() { float size = (float)System.Math.Round(4.5f / ((float)Screen.width / Screen.height), 4); string type = SystemInfo.deviceModel.ToLower().Trim(); // Debug.Log($"type==========={type}"); if (type.Substring(0, 3) == "ipa") {//iPad机型 size = 49.9f; } main_camera.orthographicSize = size; } void Start() { card_item = Resources.Load("card/card_item"); Material[] materials = Resources.LoadAll("Card/poker_material"); // 初始化字典 materialDict = new Dictionary(); foreach (Material mat in materials) { if (!materialDict.ContainsKey(mat.name)) { materialDict.Add(mat.name, mat); // Debug.Log("Loaded material: " + mat.name); } } // 使用示例:通过名字获取材质球 // if (materialDict.TryGetValue("poker_back", out Material backMat)) // { // // 给某个 MeshRenderer 应用材质 // GetComponent().material = backMat; // } CreatCardFunction(); CheckCanClick(); } void CreatCardFunction() { for (int i = 0; i < cards.Count; i++) { GameObject temp = Instantiate(card_item, cards[i].initial_position, Quaternion.Euler(cards[i].initial_rotation), gameObject.transform); temp.name = i.ToString(); Debug.Log(cards[i].suit); Debug.Log(cards[i].number); string color_ = null; if (cards[i].suit == 0 || cards[i].suit == 1) { color_ = "black"; } else { color_ = "red"; } if (materialDict.TryGetValue("num_" + color_ + "_small_" + cards[i].number, out Material backMat)) { // 给某个 MeshRenderer 应用材质 temp.transform.Find("small").GetComponent().material = backMat; } if (materialDict.TryGetValue("num_" + color_ + "_big_" + cards[i].number, out Material backMat1)) { // 给某个 MeshRenderer 应用材质 temp.transform.Find("big").GetComponent().material = backMat1; } if (materialDict.TryGetValue("suit_" + cards[i].suit, out Material backMat2)) { // 给某个 MeshRenderer 应用材质 temp.transform.Find("suit").GetComponent().material = backMat2; } cards[i]._gameObject = temp; if (cards[i].is_dark_hand) { dark_hand_cards_list.Add(cards[i]); } if (cards[i].is_hand) { cards[i]._gameObject.transform.eulerAngles = new Vector3(0, 180, 0); cards[i]._gameObject.transform.position = hand_card_pos; hand_card_num = cards[i].number; } } // 就地排序(从大到小) dark_hand_cards_list.Sort((a, b) => b.initial_position.z.CompareTo(a.initial_position.z)); int index = 0; for (int i = dark_hand_cards_list.Count - 1; i >= 0; i--) { dark_hand_cards_list[i]._gameObject.transform.eulerAngles = Vector3.zero; dark_hand_cards_list[i]._gameObject.transform.position = new Vector3(dark_hand_card_pos.x + index * (-0.1f), dark_hand_card_pos.y, dark_hand_cards_list[i]._gameObject.transform.position.z); index++; } } void CheckCanClick(bool showAnima = false) { // List allRenderers = new List(); // for (int i = 0; i < Card_gameobject_list.Count; i++) // { // Renderer render = Card_gameobject_list[i].GetComponentInChildren(); // allRenderers.Add(render); // } // for (int i = 0; i < Card_gameobject_list.Count; i++) // { // if (IsCovered(allRenderers[i], allRenderers, main_camera)) // { // Debug.Log(Card_gameobject_list[i].name); // Card_gameobject_list[i].transform.rotation = Quaternion.Euler(new Vector3(0, 0, Card_gameobject_list[i].transform.rotation.z)); // } // } for (int i = 0; i < cards.Count; i++) { bool is_cover = false; if (cards[i].is_hand || cards[i].is_dark_hand) continue; for (int j = 0; j < cards.Count; j++) { if (cards[j].is_hand || cards[j].is_dark_hand) continue; if (cards[i] == cards[j]) continue; if (cards[j]._gameObject.transform.position.z > cards[i]._gameObject.transform.position.z) { continue; } if (IsIntersect(cards[j], cards[i]))//被盖住了 { is_cover = true; break; } } if (!is_cover)//正面 { if (cards[i].isBack) { if (!showAnima) cards[i]._gameObject.transform.Rotate(0f, 180f, 0f, Space.Self); else { cards[i]._gameObject.transform .DOLocalRotate(new Vector3(0, 180, 0), 0.5f, RotateMode.LocalAxisAdd); } cards[i].isBack = false; } } else//背面 { } } } void HitCard(string card_name) { int index = int.Parse(card_name); // cards[index]._gameObject if (dark_hand_cards_list.Count > 0 && cards[index] == dark_hand_cards_list[dark_hand_cards_list.Count - 1]) { Debug.Log("????????????????????????????????"); Transform t = cards[index]._gameObject.transform; t.DOLocalMove(hand_card_pos, 0.3f); t.DOLocalRotate(new Vector3(0, -180, 0), 0.3f, RotateMode.LocalAxisAdd); t.DOScale(1.1f, 0.15f).SetEase(Ease.OutBack).OnComplete(() => { t.DOScale(1f, 0.15f).SetEase(Ease.InQuad); }); // .DOLocalRotate(new Vector3(0, 180, 0), 0.5f, RotateMode.LocalAxisAdd); cards[index].is_hand = true; hand_card_num = cards[index].number; Renderer[] _render_ = cards[index]._gameObject.transform.GetComponentsInChildren(); for (int i = 0; i < _render_.Length; i++) { // _render_[i].material.renderQueue = renderQueue; _render_[i].sortingOrder = _sortingOrder; _sortingOrder++; } dark_hand_cards_list.RemoveAt(dark_hand_cards_list.Count - 1); } else { if (cards[index].isBack) { return; } if (!numberCanClick(cards[index].number)) { return; } cards[index]._gameObject.transform.DOLocalMove(hand_card_pos, 0.3f); cards[index]._gameObject.transform.DOLocalRotate(new Vector3(0, 180, 0), 0.3f); cards[index].is_hand = true; Renderer[] _render_ = cards[index]._gameObject.transform.GetComponentsInChildren(); for (int i = 0; i < _render_.Length; i++) { // _render_[i].material.renderQueue = renderQueue; _render_[i].sortingOrder = _sortingOrder; _sortingOrder++; } DOVirtual.DelayedCall(0.5f, () => { CheckCanClick(true); }); } } bool numberCanClick(int _number) { Debug.Log("dianjide" + _number); Debug.Log("xianzaide" + hand_card_num); if (hand_card_num < 0) { hand_card_num = _number; return true; } if (hand_card_num == 13 && (_number == 1 || _number == 12)) { hand_card_num = _number; return true; } if (hand_card_num == 1 && (_number == 13 || _number == 2)) { hand_card_num = _number; return true; } if ((hand_card_num == (_number - 1)) || (hand_card_num == (_number + 1))) { hand_card_num = _number; return true; } return false; } public static bool IsIntersect(CardInfo a, CardInfo b) { float w = 1.12f, h = 1.64f; Vector2[] rectA = GetCorners(a.initial_position, w, h, a.initial_rotation.z); Vector2[] rectB = GetCorners(b.initial_position, w, h, b.initial_rotation.z); // 在 Scene 里画出来 DrawRect(rectA, Color.red); DrawRect(rectB, Color.green); List axes = new List(); for (int i = 0; i < 4; i++) { Vector2 edgeA = rectA[(i + 1) % 4] - rectA[i]; axes.Add(edgeA.normalized); } for (int i = 0; i < 4; i++) { Vector2 edgeB = rectB[(i + 1) % 4] - rectB[i]; axes.Add(edgeB.normalized); } foreach (var axis in axes) { (float minA, float maxA) = Project(rectA, axis); (float minB, float maxB) = Project(rectB, axis); // Debug.Log($"Axis {axis}: A[{minA},{maxA}] B[{minB},{maxB}]"); // 加容差避免边界误判 if (maxA < minB - 1e-6 || maxB < minA - 1e-6) return false; } return true; } private static Vector2[] GetCorners(Vector2 center, float w, float h, float angleDeg) { float angle = angleDeg * Mathf.Deg2Rad; // 度转弧度 Vector2[] corners = new Vector2[4]; Vector2[] offsets = { new Vector2(-w/2, -h/2), new Vector2(w/2, -h/2), new Vector2(w/2, h/2), new Vector2(-w/2, h/2) }; for (int i = 0; i < 4; i++) { float x = Mathf.Cos(angle) * offsets[i].x - Mathf.Sin(angle) * offsets[i].y; float y = Mathf.Sin(angle) * offsets[i].x + Mathf.Cos(angle) * offsets[i].y; corners[i] = center + new Vector2(x, y); } return corners; } private static (float min, float max) Project(Vector2[] corners, Vector2 axis) { float min = float.MaxValue, max = float.MinValue; foreach (var p in corners) { float proj = Vector2.Dot(p, axis); min = Mathf.Min(min, proj); max = Mathf.Max(max, proj); } return (min, max); } private static void DrawRect(Vector2[] corners, Color color) { for (int i = 0; i < 4; i++) { Vector2 p1 = corners[i]; Vector2 p2 = corners[(i + 1) % 4]; // 下一个点,最后一个点连回第一个 Debug.DrawLine(p1, p2, color, 100f, false); } } private GameObject card_item; private GameObject Popup; // Update is called once per frame void Update() { if (Input.GetMouseButtonDown(0)) { // if (Popup == null) Popup = GameObject.Find("Popup"); // if (Popup.transform.childCount != 0) return; Ray ray = main_camera.ScreenPointToRay(Input.mousePosition); RaycastHit hit; int layerMask = 1 << 6; // 只与第6层的碰撞器碰撞 // 如果射线与layerMask指定层的碰撞器发生碰撞 if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerMask)) { Debug.Log("Hit " + hit.collider.transform.parent.gameObject.name); HitCard(hit.collider.transform.parent.gameObject.name); // GameDispatcher.Instance.Dispatch(GameMsg.card_click, hit.collider.gameObject.name); } } if (Input.GetMouseButtonDown(1)) { Debug.Log("chehui"); } } List dark_hand_cards_list = new List(); List cards = new List { // 上层半圆 new CardInfo { number = 7, suit = 0, initial_position = new Vector3(-4.2f, 2.5f, -0.10f), initial_rotation = new Vector3(0,0,-25f), isBack = true, is_dark_hand = false }, new CardInfo { number = 11, suit = 3, initial_position = new Vector3(-2.95f, 2.22f, -1.10f), initial_rotation = new Vector3(0,0,-18f), isBack = true, is_dark_hand = false }, new CardInfo { number = 12, suit = 2, initial_position = new Vector3(-1.5f, 3.0f, -2.10f), initial_rotation = new Vector3(0,0,-8f), isBack = true, is_dark_hand = false }, new CardInfo { number = 8, suit = 1, initial_position = new Vector3(0.0f, 3.1f, -3.10f), initial_rotation = new Vector3(0,0,0f), isBack = true, is_dark_hand = false }, new CardInfo { number = 10, suit = 0, initial_position = new Vector3(1.5f, 3.0f, -4.10f), initial_rotation = new Vector3(0,0,8f), isBack = true, is_dark_hand = false }, new CardInfo { number = 9, suit = 2, initial_position = new Vector3(3.0f, 2.7f, -5.10f), initial_rotation = new Vector3(0,0,18f), isBack = true, is_dark_hand = false }, new CardInfo { number = 13, suit = 1, initial_position = new Vector3(4.2f, 2.5f, -6.10f), initial_rotation = new Vector3(0,0,25f), isBack = true, is_dark_hand = false }, // 下层覆盖 new CardInfo { number = 5, suit = 0, initial_position = new Vector3(-4.4f, 0.9f, -7.10f), initial_rotation = new Vector3(0,0,-20f), isBack = true, is_dark_hand = false }, new CardInfo { number = 6, suit = 1, initial_position = new Vector3(-2.2f, 2.5f, -8.10f), initial_rotation = new Vector3(0,0,-10f), isBack = true, is_dark_hand = false }, new CardInfo { number = 3, suit = 2, initial_position = new Vector3(-0.5f, 2.7f, -9.10f), initial_rotation = new Vector3(0,0,-3f), isBack = true, is_dark_hand = false }, new CardInfo { number = 4, suit = 3, initial_position = new Vector3(1.0f, 2.7f, -10.10f), initial_rotation = new Vector3(0,0,3f), isBack = true, is_dark_hand = false }, new CardInfo { number = 2, suit = 0, initial_position = new Vector3(2.5f, 2.5f, -11.10f), initial_rotation = new Vector3(0,0,10f), isBack = true, is_dark_hand = false }, new CardInfo { number = 1, suit = 3, initial_position = new Vector3(3.9f, 2.2f, -12.10f), initial_rotation = new Vector3(0,0,20f), isBack = true, is_dark_hand = false,is_hand=true }, // 底部单张 new CardInfo { number = 9, suit = 2, initial_position = new Vector3(0f, 0.5f, -13.10f), initial_rotation = new Vector3(0,0,0f), isBack = true, is_dark_hand = false }, // 新增十张(is_dark_hand = true) new CardInfo { number = 1, suit = 0, initial_position = new Vector3(-5f, 1f, -14.10f), initial_rotation = new Vector3(0,0,-30f), isBack = true, is_dark_hand = true }, new CardInfo { number = 2, suit = 1, initial_position = new Vector3(-3.5f, 1.2f, -15.10f), initial_rotation = new Vector3(0,0,-20f), isBack = true, is_dark_hand = true }, new CardInfo { number = 3, suit = 2, initial_position = new Vector3(-2f, 1.5f, -16.10f), initial_rotation = new Vector3(0,0,-10f), isBack = true, is_dark_hand = true }, new CardInfo { number = 4, suit = 3, initial_position = new Vector3(-0.5f, 1.8f, -17.10f), initial_rotation = new Vector3(0,0,0f), isBack = true, is_dark_hand = true }, new CardInfo { number = 5, suit = 0, initial_position = new Vector3(1f, 2.0f, -18.10f), initial_rotation = new Vector3(0,0,10f), isBack = true, is_dark_hand = true }, new CardInfo { number = 6, suit = 1, initial_position = new Vector3(2.5f, 2.2f, -19.10f), initial_rotation = new Vector3(0,0,20f), isBack = true, is_dark_hand = true }, new CardInfo { number = 7, suit = 2, initial_position = new Vector3(4f, 2.4f, -20.10f), initial_rotation = new Vector3(0,0,30f), isBack = true, is_dark_hand = true }, new CardInfo { number = 8, suit = 3, initial_position = new Vector3(-4f, 0.5f, -21.10f), initial_rotation = new Vector3(0,0,-15f), isBack = true, is_dark_hand = true }, new CardInfo { number = 9, suit = 0, initial_position = new Vector3(-2f, 0.7f, -22.10f), initial_rotation = new Vector3(0,0,-5f), isBack = true, is_dark_hand = true }, new CardInfo { number = 10, suit = 1, initial_position = new Vector3(0f, 0.9f, -23.10f), initial_rotation = new Vector3(0,0,5f), isBack = true, is_dark_hand = true }, }; } [System.Serializable] public class CardInfo { public int number; // 1-13 (A-K) public int suit; // 0-3 (♣♠♦♥) public Vector3 initial_position; // 卡牌位置 (x, y, z) public Vector3 initial_rotation; // 卡牌旋转 (Euler角) public bool isBack; // 是否显示背面,默认 true public GameObject _gameObject; public bool is_hand; public bool is_dark_hand; }