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

相关推荐
辻弋2012 小时前
一键优化电源计划、游戏模式、独显强制、禁用后台录制——DeltaForceBooster专治三角洲行动卡顿掉帧,所有改动可一键还原
服务器·数据库·windows·游戏·电脑·php
江上闲人.3 小时前
COD23现代战争4试玩进不去报错?TPM2.0安全启动等常见问题解决方法
游戏·使命召唤·cod23·使命召唤现代战争4·cod
郝学胜-神的一滴5 小时前
Horse3D 游戏引擎研发笔记(七):Clydesdale——从流式日志到多输出订阅
c++·qt·unity·游戏引擎·图形渲染·unreal engine·opengl
江上闲人.1 天前
Wardogs战犬\战狗Beta测试启动报错UE崩溃卡顿?解决方法来了
游戏·游戏引擎·虚幻·战犬·战狗·wardogs
雷电小将军1 天前
诡秘之主手游占卜家序列加点 诡秘之主手游占卜家怎么加点
服务器·网络·游戏·电脑·玩游戏
小贺儿开发1 天前
Unity 程序员编曲花絮:汪峰《河流》细节修复
科技·学习·unity·程序员·音乐·demo·写代码
598866753@qq.com1 天前
Unity UniText笔记
unity·unitext
杨丰玮4181 天前
从零手写Java飞机躲障碍游戏|Swing绘图、鼠标跟随、计时器碰撞检测实战(五)
java·python·游戏·游戏引擎·图形渲染·动画·贴图
yangmu32031 天前
《明末:渊虚之羽》1.7版百款MOD终极指南:硬核配置与保姆级安装教程
游戏
鼎艺创新科技2 天前
不依赖 UE/Unity:我们如何从零搭建一套国产三维 GIS 渲染引擎
人工智能·算法·unity·游戏引擎·三维电子沙盘