100个 Unity小游戏系列六 -Unity 抽奖游戏专题四 翻卡游戏

一、演示效果

二、知识点讲解

2.1 布局

cs 复制代码
  void CreateItems()
        {
            reward_data_list = reward_data_list ?? new List<RewardData>();
            reward_data_list.Clear();


            for (int i = 0; i < ItemCount; i++)
            {

                GameObject item;
                if (i + 1 <= itemParent.childCount)
                {
                    item = itemParent.GetChild(i).gameObject;
                }
                else
                {
                    item = Instantiate(itemParent.GetChild(0).gameObject, itemParent);
                }

                item.transform.localPosition = initPosArr[i];
                item.transform.localScale = Vector3.one;
                var cardGraphics = item.transform.Find("Graphics").GetComponent<RectTransform>();

                RefreshCardData(cardGraphics, false, rewardDatas[i]);
                SetCardOpen(false, item.GetComponent<Button>(), true, rewardDatas[i]);
            }

            StartAnim(rewardDatas);
        }

/// <summary>
        /// 明牌,洗牌动画
        /// </summary>
        private void StartAnim(RewardData[] rewardsArr)
        {
            CardSelectable = false;

            if (rewardsArr.Length != itemParent.childCount)
            {
                Debug.LogErrorFormat("rewards length is not equals cards count:{0}", itemParent.childCount);
                return;
            }

            isSwapCard = true;
            var seqAnim = DOTween.Sequence();
            seqAnim.AppendInterval(2f);
            seqAnim.AppendCallback(() =>
            {
                int overCount = itemParent.childCount;
                for (int i = 0; i < itemParent.childCount; i++)
                {
                    SetCardOpen(false, itemParent.GetChild(i).GetComponent<Button>(), false, null, 0.2f, () =>
                    {
                        //所有卡片翻回去之后开始洗牌
                        if (--overCount <= 0)
                        {
                            List<int> cardsList = new List<int>();

                            for (int childIndex = 0; childIndex < itemParent.childCount; childIndex++)
                            {
                                cardsList.Add(childIndex);
                            }


                            SwapCards(cardsList, 10, () =>
                            {
                                RefreshCardADState(false);
                                CardSelectable = true;
                            });
                        }
                    });
                }
            });
        }

2.2 转动逻辑

cs 复制代码
 private void SwapCards(List<int> cardsList, int swapCount, Action onComplete)
        {
            if (swapCount <= 0)
            {
                onComplete?.Invoke();
                return;
            }

            SwapCardAnim(cardsList, () =>
            {
                ListRandom(cardsList);
                SwapCards(cardsList, --swapCount, onComplete);
            });
        }

        public static void ListRandom<T>(List<T> sources)
        {
            int index;
            T temp;
            for (int i = 0; i < sources.Count; i++)
            {
                index = UnityEngine.Random.Range(0, sources.Count);
                if (index != i)
                {
                    temp = sources[i];
                    sources[i] = sources[index];
                    sources[index] = temp;
                }
            }
        }
        /// <summary>
        /// 洗牌动画
        /// </summary>
        /// <param name="onSwapOver"></param>
        private void SwapCardAnim(List<int> cardsindexList, Action onSwapOver)
        {
            if (itemParent.childCount % 2 != 0)
            {
                Debug.LogError("cardsRoot 卡片个数不能为奇数");
                return;
            }

            int moveMission = itemParent.childCount;
            TweenCallback onMoveOver = () =>
            {
                if (--moveMission <= 0)
                {
                    onSwapOver?.Invoke();
                }
            };
            for (int i = 0; i < cardsindexList.Count; i += 2)
            {
                var indexA = cardsindexList[i];
                var indexB = cardsindexList[i + 1];
                var cardA = itemParent.GetChild(indexA);
                var cardB = itemParent.GetChild(indexB);
                float moveDuration = Vector2.Distance(initPosArr[indexA], initPosArr[indexB]) / 1500;
                moveDuration = Mathf.Clamp(moveDuration, 0, 0.18f);

                cardA.DOLocalMove(initPosArr[indexB], moveDuration).onComplete = onMoveOver;
                cardB.DOLocalMove(initPosArr[indexA], moveDuration).onComplete = onMoveOver;
            }
        }

        private void SetCardOpen(bool isUser, Button cardBt, bool isOpen, RewardData reward = null, float duration = 0.2f, Action onCardAnimOver = null)
        {
            if (isOpen && reward == null)
            {
                Debug.LogError("翻卡传入奖励数据为null");
                return;
            }
            if (isUser && !CardSelectable)
            {
                return;
            }
            CardSelectable = false;
            int texIndex = 0;
            int colorIndex = 0;
            string tmStr = string.Empty;
            Vector3 halfRotate = new Vector3(0, 90, 0);
            if (isOpen)
            {
                texIndex = reward.type;
                colorIndex = reward.type - 1;
                tmStr = reward.amount.ToString();
                halfRotate.y = 270;
            }

            cardBt.interactable = !isOpen;

            var card = cardBt.transform;
            var cardGraphics = card.Find("Graphics").GetComponent<RectTransform>();

            var seqAnim = DOTween.Sequence();
            seqAnim.Append(cardGraphics.DOLocalRotate(halfRotate, duration).SetEase(Ease.Linear));
            seqAnim.AppendCallback(() =>
            {
                RefreshCardData(cardGraphics, isOpen, reward);
            });
            seqAnim.Append(cardGraphics.DOLocalRotate(halfRotate + Vector3.up * 90, duration).SetEase(Ease.Linear));
            seqAnim.onComplete = () =>
            {
                if (!isUser)
                {
                    //CardSelectable = true;
                    onCardAnimOver?.Invoke();
                }
            };
            if (isUser)
            {
                card.SetSiblingIndex(itemParent.childCount);
                //float moveDuration = Vector2.Distance(card.transform.localPosition, Vector3.zero) / 400;
                //moveDuration = Mathf.Clamp(moveDuration, 0, 0.4f);
                //card.DOMove(Vector3.zero, moveDuration);
                //card.DOScale(1.4f, moveDuration).onComplete = () =>
                //{
                //    var moveSeq = DOTween.Sequence();
                //    moveSeq.AppendInterval(1.0f);
                //    moveSeq.AppendCallback(() =>
                //    {
                //        var smallCard = smallCardsRoot.GetChild(CurClaimIndex);
                //        moveDuration = Mathf.Clamp(Vector2.Distance(card.position, smallCard.position) / 10, 0, 0.4f);
                //        card.DOScale(smallCard.GetComponent<RectTransform>().sizeDelta.x / card.GetComponent<RectTransform>().sizeDelta.x, moveDuration);
                //        card.DOMove(smallCard.position, moveDuration).onComplete = () =>
                //        {
                //            CardSelectable = true;
                //            GF.Sound.PlaySound("poker_end.wav", false);

                //            //加奖励
                //            GF.UserData.ClaimReward(UserDataType.LuckpokerRedpacket, reward, GF.UserData.GameUIForm.gameMainView.levelSocreTxt.transform);
                //            onCardAnimOver?.Invoke();
                //        };
                //    });
                //};


                CardSelectable = true;
                onCardAnimOver?.Invoke();
            }
        }

三 、完整代码逻辑

https://github.com/lixianjun0903/luckydraw-master.git

相关推荐
myshare20228 分钟前
Dungeon Saga 套装加成与品质共鸣:影响英雄的哪一部分
游戏·dungeon saga·品质共鸣
Martina_03219 小时前
同一片森林换个镜头就忽冷忽暖?用6步统一曝光、LUT与相机后处理
人工智能·游戏·数学建模·3d·自然语言处理·aigc·游戏策划
外收内放10 小时前
08 | 优化篇③ 60 张动作立绘和 50 张特效贴图是怎么进游戏的
python·游戏·pygame
外收内放11 小时前
06 | 优化篇① 游戏改名《鳞光纪》了:这次翻新,把“脸“全换了
python·游戏·pygame
Liuchang091111 小时前
洛谷 P2670 [NOIP 2015 普及组] 扫雷游戏
c++·算法·游戏
WarPigs11 小时前
Unity对象不应该使用null传播的问题
unity
每日出拳老爷子1 天前
【VR】【Unity】抓走转放系列21|一天搭完门和抽屉工具槽:小场景按这个次序拼装
unity·vr·驱动·排错·snap zone
勤劳X码农1 天前
2026年AI配音做教育视频怎么选?
人工智能·游戏·音视频
bryant_meng2 天前
【Game】Powerful——Pets(4.5)145
游戏·幻唐志·暗夜龙姬·撼山·银角·金角
淡海水2 天前
02-02-原理篇-分代GC
算法·unity·c#·游戏引擎·.net·gc