Unity 之 三种抽奖示例(跑马灯,转盘,老虎机实例 文中源码)

3,683 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

一,跑马灯抽奖

效果图: 1.1 设计思路:

  • 点击按钮 ,根据需求(概率)计算本次抽奖获得物品
  • 模拟转动 (先加速后减速), 一段时间后停止

场景搭建: 1.2 一个按钮,一个组奖品(放到一个父物体上),一个光环(当前选中的那个奖品)

实现代码:

using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class RotaryTablePanel : MonoBehaviour
{
    // 抽奖按钮,
    public Button drawBtn;
    // 抽奖图片父物体
    public Transform rewardImgTran;
    // 光环
    public Transform HaloImgTransform;
    // 抽奖图片
    private Transform[] rewardTransArr;

    // 默认展示状态
    private bool isInitState;
    // 抽奖结束 -- 结束状态,光环不转
    private bool drawEnd;
    // 中奖
    private bool drawWinning;
    
    // 展示状态时间 --> 控制光环转动速度
    private float rewardTime = 0.8f;
    private float rewardTiming = 0;

    // 当前光环所在奖励的索引
    private int haloIndex = 0;
    // 本次中奖ID
    private int rewardIndex = 0;
    
    // 点了抽奖按钮正在抽奖
    private bool isOnClickPlaying;
    
    void Start()
    {
        drawBtn.onClick.AddListener(OnClickDrawFun);
        rewardTransArr = new Transform[rewardImgTran.childCount];
        for (int i = 0; i < rewardImgTran.childCount; i++)
        {
            rewardTransArr[i] = rewardImgTran.GetChild(i);
        }
        
        // 默认展示时间
        rewardTime = 0.6f;
        rewardTiming = 0;
        
        drawEnd = false;
        drawWinning = false;
        isOnClickPlaying = false;
    }

    
    void Update()
    {
        if (drawEnd) return;
        
        // 抽奖展示
        rewardTiming += Time.deltaTime;
        if (rewardTiming >= rewardTime)
        {
            rewardTiming = 0;
            haloIndex++;
            if (haloIndex >= rewardTransArr.Length)
            {
                haloIndex = 0;
            }
            SetHaloPos(haloIndex);
        }
    }
    
    // 设置光环显示位置
    void SetHaloPos(int index)
    {
        HaloImgTransform.position = rewardTransArr[index].position;

        // 中奖 && 此ID == 中奖ID
        if (drawWinning && index == rewardIndex)
        {
            isOnClickPlaying = false;
            drawEnd = true;
            //todo...展示中奖物品,维护数据 --> 注意: index是索引
            Debug.Log("恭喜您中奖,中奖物品索引是:" + index + "号");
        }
    }

    // 点击抽奖按钮
    void OnClickDrawFun()
    {
        if (!isOnClickPlaying)
        {
            // 随机抽中ID
            rewardIndex =  Random.Range(0, rewardTransArr.Length);
            Debug.Log("开始抽奖,本次抽奖随机到的ID是:" + rewardIndex);
            isOnClickPlaying = true;
            drawEnd = false;
            drawWinning = false;
            StartCoroutine(StartDrawAni());
        }
    }

    /// <summary>
    /// 开始抽奖动画
    /// 先快后慢 -- 根据需求调整时间
    /// </summary>
    /// <returns></returns>
    IEnumerator StartDrawAni()
    {
        rewardTime = 0.8f;
        // 加速
        for (int i = 0; i < 7; i++)
        {
            yield return new WaitForSeconds(0.1f);
            rewardTime -= 0.1f;
        }

        yield return new WaitForSeconds(2f);
        // 减速
        for (int i = 0; i < 5; i++)
        {
            yield return new WaitForSeconds(0.1f);
            rewardTime += 0.1f;
        }
        
        yield return new WaitForSeconds(1f);
        drawWinning = true;
    }
    
}


二,转盘抽奖

效果图: 2.1 设计思路:(和上面差不多)

  • 点击按钮 ,根据需求(概率)计算本次抽奖获得物品索引
  • 根据随机到的索引,计算需要旋转的角度
  • 模拟转动 , 一段时间后停止到计算的角度上

场景搭建: 1.2 一个按钮,一个转盘,一个指针;

实现代码:

using UnityEngine;
using UnityEngine.UI;

public class RotaryDrawDemo : MonoBehaviour
{
    // 转盘
    public Transform RotateTableTrans;
    // 抽奖按钮
    public Button DrawBtn;

    // 转盘区域数 -- (Demo中图片是10份)
    private int rotateTableNumber = 10;
    
    // 旋转动画时间      
    private float rotateTime = 3f;
    private float rotateTiming = 0f;

    /// <summary>
    /// 需要转动到的目标位置
    /// </summary>
    private Quaternion targetAngels = Quaternion.identity;

    // 转动的速度 
    private float rotateSpeed = 20;
    // 模拟抽奖的选择时间 
    private float RotateTime = 3f;

    /// <summary>
    /// 是否开始抽奖转动
    /// </summary>
    private bool isStartRotate = false;
    // 本次中奖ID
    private int rewardIndex = 0;

    void Start()
    {
        DrawBtn.onClick.AddListener(OnClickDrawFun);
    }

    void Update()
    {
        if (!isStartRotate) return;
        
        rotateTiming += Time.deltaTime;
        // 过了动画时间
        if (rotateTiming >= RotateTime)
        {
            RotateTableTrans.Rotate(Vector3.back * 2);
            // 计算当前正在旋转的角度和目标角度的夹角
            if (Quaternion.Angle(RotateTableTrans.rotation, targetAngels) <= 2)
            {
                // 设置目标夹角
                RotateTableTrans.rotation = targetAngels;
                // 转动停止
                isStartRotate = false;

                // todo... 奖品展示,数据维护
                Debug.Log("***** 恭喜或的奖品,奖品索引:" + rewardIndex + " ,转盘角度是:" 
                          + RotateTableTrans.localEulerAngles.z + "*****");
            }
        }
        else
        {
            // 转动转盘(back为顺时针, forward为逆时针)
            RotateTableTrans.Rotate(Vector3.back * 10);
        }
    }

    // 点击抽奖按钮
    void OnClickDrawFun()
    {
        if (!isStartRotate)
        {
            //开始旋转
            isStartRotate = true;
            rotateTiming = 0;

            // 随机到转盘第几块区域
            rewardIndex = Random.Range(0, rotateTableNumber);
            // 根据区域计算角度 --> 36 = 360 / rotateTableNumber;
            float targetRot = rewardIndex * 36; 
            //设置目标位置
            targetAngels = Quaternion.Euler(0, 0, targetRot);
            
            Debug.Log("----- 开始抽奖 随机到的区域,索引是:" + rewardIndex + ",角度是:" + targetRot + "-----");
        }
    }
}

三,老虎机抽奖

效果图: 3.1 具体参考:Unity 之 实现老虎机滚动抽奖效果


若还有不明白的地方,可以评论咨询,或者点击链接查看示例源码: 一,二示例源码链接 没有积分的同学可以V信搜"开发同学留步",回复“Unity抽奖”获得项目源码。