一,跑马灯抽奖
效果图:
设计思路:
- 点击按钮 ,根据需求(概率)计算本次抽奖获得物品
- 模拟转动 (先加速后减速), 一段时间后停止
场景搭建:
一个按钮,一个组奖品(放到一个父物体上),一个光环(当前选中的那个奖品)
实现代码:
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;
}
}
二,转盘抽奖
效果图:
设计思路:(和上面差不多)
- 点击按钮 ,根据需求(概率)计算本次抽奖获得物品索引
- 根据随机到的索引,计算需要旋转的角度
- 模拟转动 , 一段时间后停止到计算的角度上
场景搭建:
一个按钮,一个转盘,一个指针;
实现代码:
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 + "-----");
}
}
}
三,老虎机抽奖
效果图:
具体参考:Unity 之 实现老虎机滚动抽奖效果