unity开发抽奖系统
这段时间工作比较空闲,想做个抽奖系统,发现网上的抽奖系统看不懂,然后自己做了一个可以随意定义奖品概率,不管什么时候停下来指针最终都会转到指定的奖品哪。。。
废话不多说,动手一步一步来。
这个抽奖系统就使用了两张图片,一个指针,一个圆形的图片。
然后做一个预制体,图片就是圆形图片,image type选择filled,fill amount控制这个图片的面积大小,同时也是该图片的概率,Text组件是该奖品的名称。
再接下来就做一下界面布局的工作
Bg就是那个灰色的图片,Rotate是个空物体,用来挂在脚本的(DialRotate.cs和Slot.cs),cloneParent也是个空物体,作为预制体的父物体,要注意的是cloneParent中心那个蓝色的圆圈要和Rotate的蓝色的圈的位置一致,界面布局工作完成。
接下来到代码了,Slot.cs脚本,一开始会实例化奖品,K键和L键可以随意修改奖品名称,概率(这里概率做了限制,需要使用的自己修改一下代码即可),空格键会随机抛出物品,并且开始旋转,鼠标右键是停止转动(想什么时候停下来都行,最后都会得到所抛出的物体)DialRotate.cs脚本用于处理旋转的。这两个脚本涉及到一些数学计算,慢慢理解即可。
以下是这个工程的脚本,需要的话直接复制黏贴即可使用
Slot.cs
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Slot : MonoBehaviour {
private DialRotate dialRotate;
/// <summary>
/// 奖品数据
/// </summary>
private class GrifData
{
/// <summary>
/// 奖品的名称
/// </summary>
public string mText;
/// <summary>
/// 图片的Amount值
/// </summary>
public float point;
/// <summary>
/// 奖品停留在指针时父物体要旋转的角度
/// </summary>
public float angle;
/// <summary>
/// 该奖品对应UI面板上的名称
/// </summary>
public string mtran;
/// <summary>
/// 该奖品的ID
/// </summary>
public int gID;
}
/// <summary>
/// 奖品的描述信息
/// </summary>
private class GrifInfo
{
public Text mText;
public string msg;
}
private List<GrifInfo> mListSD = new List<GrifInfo>();
/// <summary>
/// 奖品的id和概率对应
/// </summary>
private Dictionary<int, float> mPoints = new Dictionary<int, float>();
/// <summary>
/// 用于储存奖品信息(顺序排列)(奖品的id,名称,所占的百分比)
/// </summary>
private List<GrifData> grigtData = new List<GrifData>();
/// <summary>
/// 这个也是用于储存奖品信息,不过是乱序排列(奖品的id,名称,所占的百分比)
/// </summary>
private List<GrifData> randomData = new List<GrifData>();
/// <summary>
/// 20种奖品的Transform,(最多20个不用的奖励)
/// </summary>
private List<Transform> mTransLs = new List<Transform>();
private List<Color> mColors = new List<Color>();
private Transform cloneParent;
private GameObject clonePrefab;
/// <summary>
/// 抽奖停止时父物体转动的角度
/// </summary>
public float tarAngle;
/// <summary>
/// 该奖品对应UI面板上的名称
/// </summary>
public string tarName;
public int giftID;
/// <summary>
/// 用于检验概率有没有为100%
/// </summary>
private List<float> checkProbability = new List<float>();
private void Start()
{
cloneParent = transform.Find("cloneParent");
clonePrefab = Resources.Load<GameObject>("Clone");
dialRotate = GetComponent<DialRotate>();
Init();
}
void Update()
{
#region 测试修改奖品,概率
if (Input.GetKeyDown(KeyCode.K))
{
ClearData();
if (checkProbability.Count > 0)
{
checkProbability.Clear();
}
if (mPoints.Count > 0)
{
mPoints.Clear();
}
AddData("111", 0.3f,1);
AddData("222", 0.1f,2);
AddData("333", 0.2f,4);
AddData("444", 0.05f,5);
AddData("555", 0.15f,6);
AddData("666", 0.2f,7);
SetPriceRange();
}
if (Input.GetKeyDown(KeyCode.J))
{
ClearData();
if (checkProbability.Count > 0)
{
checkProbability.Clear();
}
if (mPoints.Count > 0)
{
mPoints.Clear();
}
AddData("薯条", 0.3f, 1);
AddData("汉堡", 0.1f, 2);
AddData("炸鸡", 0.2f, 4);
AddData("啤酒", 0.05f, 5);
AddData("可乐", 0.15f, 6);
AddData("烤肉", 0.2f, 7);
SetPriceRange();
}
#endregion
if (Input.GetKeyDown(KeyCode.Space))
{
StartRotate();
}
}
private void Init()
{
for (int i = 0; i < 20; i++)
{
GameObject go = Instantiate(clonePrefab) as GameObject;
go.transform.SetParent(cloneParent);
go.transform.localScale = Vector3.one;
go.transform.localPosition = Vector3.zero;
go.name = "" + i;
mTransLs.Add(go.transform);
}
foreach (Transform tr in mTransLs)
{
tr.GetComponent<Image>().color = GetColors();
tr.gameObject.SetActive(false);
}
AddData("薯条", 0.3f, 1);
AddData("汉堡", 0.1f, 2);
AddData("炸鸡", 0.2f, 4);
AddData("啤酒", 0.05f, 5);
AddData("可乐", 0.15f, 6);
AddData("烤肉", 0.2f, 7);
SetPriceRange();
}
/// <summary>
/// 获得随机颜色
/// </summary>
/// <returns></returns>
private Color GetColors()
{
return new Color(Random.Range(0, 1.0f), Random.Range(0, 1.0f), Random.Range(0, 1.0f));
}
/// <summary>
/// 清除奖品的相关数据和设置新的颜色
/// </summary>
public void ClearData()
{
grigtData.Clear();
foreach (Transform tr in mTransLs)
{
tr.GetComponent<Image>().color = GetColors();
tr.gameObject.SetActive(false);
}
}
/// <summary>
/// 设置奖励信息
/// </summary>
/// <param name="text">名称</param>
/// <param name="point">所占的百分比</param>
/// <param name="gID">该奖品的ID</param>
public void AddData(string text, float point, int gID)
{
if (point < 0.05f)
{
Debug.LogError("奖品的概率不能小于5%");
}
if (point >1.0f)
{
Debug.LogError("奖品的概率不能大于100%");
}
GrifData data = new GrifData();
data.mText = text;
data.point = point;
data.gID = gID;
grigtData.Add(data);
if (mPoints.ContainsKey(gID))
{
// mPoints[gID] = point;
Debug.LogError("物品的ID不能一致,无法添加到字典");
return;
}
mPoints.Add(gID, point);
checkProbability.Add(point);
}
/// <summary>
/// 设置奖品转盘的面积的大小显示
/// </summary>
public void SetPriceRange()
{
float total = 0;
for (int i = 0; i < checkProbability.Count; i++)
{
total += checkProbability[i];
}
if (total.ToString() !="1")
{
Debug.LogError("奖品的概率总和不等于百分百,请从新设定概率");
return;
}
transform.localEulerAngles = Vector3.zero;
// List<SData> temDate = mData.OrderBy(mData => mData.point).ToList(); //升序排序
//乱序排列
randomData.Clear();
int count = grigtData.Count; //所设置的奖品的个数
for (int i = 0; i < count; i++)
{
int ra = Random.Range(0, grigtData.Count);
randomData.Add(grigtData[ra]);
grigtData.RemoveAt(ra);
}
if (mListSD.Count > 0)
{
mListSD.Clear(); //先清空
}
float nowAmount = 0;
Text text;
for (int i = 0; i < count; i++) //把设置了奖品的显示出来
{
Transform tr = mTransLs[i];
tr.gameObject.SetActive(true);
// Debug.Log(ramData[i].mText + "/n");
//因为绘制奖励区域是从转盘的下面6点顺时针方向开始绘制,而指针是在上面9点,转盘是顺时针转动,加多180度,
//ramData[i].point/2 使得转盘停下来时使得奖品刚好处于指针的中间
float target = 180 + (nowAmount + randomData[i].point/2) * 360;
if (target > 360)
target -= 360;
text = tr.Find("Text").GetComponent<Text>();
text.text = randomData[i].mText;
GrifInfo grifInfo = new GrifInfo(); //暂时预留,发奖品不是单倍的时候有用
grifInfo.mText = text; //暂时预留,发奖品不是单倍的时候有用
grifInfo.msg = randomData[i].mText; //暂时预留,发奖品不是单倍的时候有用
mListSD.Add(grifInfo); //暂时预留,发奖品不是单倍的时候有用
tr.GetComponent<Image>().fillAmount = randomData[i].point;
//这个是旋转所设置的奖品的角度
tr.localEulerAngles = new Vector3(0, 0, -nowAmount * 360); //0.1Amount = 36度
nowAmount += randomData[i].point;
// Debug.Log(" i = " + i + "target = " + target);
randomData[i].angle = target;
randomData[i].mtran = tr.name;
// Debug.Log("target = " + target);
}
}
/// <summary>
/// 设置奖品的倍数
/// </summary>
/// <param name="multiple"></param>
public void SetMultiple(int multiple)
{
foreach (GrifInfo ss in mListSD)
{
if (multiple == 1)
{
ss.mText.text = ss.msg;
}
else
{
ss.mText.text = ss.msg + " X" + multiple;
}
}
}
/// <summary>
/// 获得结果(得到概率)
/// </summary>
public void GetResult()
{
float probability = Random.Range(0.0f, 1.0f);
float nowSub = 0;
string testStr = "";
for (int i = 0; i < randomData.Count; i++)
{
nowSub += mPoints[randomData[i].gID]; //该奖品对应的概率(Amount值)
if (probability < nowSub)
{
tarAngle = randomData[i].angle; //该奖品停止转动时需要转动的角度
tarName = randomData[i].mtran; //该奖品的名称
giftID = randomData[i].gID; //ID
testStr ="奖品名称 = " + randomData[i].mText + " 奖品概率 = " + (mPoints[randomData[i].gID] * 100 + " UI上的名称 = " + tarName + " 奖品的ID = " + giftID);
Debug.Log(testStr);
break;
}
}
}
private void StartRotate()
{
GetResult();
dialRotate.StartQuan(tarAngle, tarName);
Debug.Log("StartRotate() : tarAngle = " + tarAngle);
}
}
-------------------------------------------------------------------分割线----------------------------------------------------------------------------
-------------------------------------------------------------------分割线----------------------------------------------------------------------------
-------------------------------------------------------------------分割线----------------------------------------------------------------------------
DialRotate.cs
using UnityEngine;
public enum RollType
{
None,
Start, //开始转动
ConstantSpeed, //匀速运动
Stop, //停止运动
}
public class DialRotate : MonoBehaviour {
private RollType nowType = RollType.None;
private float tarAngle; //该奖品停下来时父物体Z轴需要转动的角度
/// <summary>
/// 当前Z轴的值
/// </summary>
private float nowAngle = 0;
private string grifName;
private float time;//计时器
private float speed = 0;
public float angleSpeed = 2;
void Update () {
if (Input.GetMouseButtonDown(1))
{
if (nowType == RollType.ConstantSpeed)
{
nowType = RollType.Stop;
// Debug.Log("tarAngle = " + tarAngle + " nowAngle = " + nowAngle);
tarAngle += nowAngle + 360;
time = 0;
}
}
if (nowType == RollType.Start)
{
time += Time.deltaTime;
float x = angleSpeed * time * time; //这些数值影响转盘的转动速度,自己看着喜欢调节即可
nowAngle -= x;
speed += 4 * time;
transform.localEulerAngles = new Vector3(0, 0, nowAngle);
if (speed > 400)
{
nowType = RollType.ConstantSpeed;
}
}
else if (nowType == RollType.ConstantSpeed)
{
nowAngle -= speed * Time.deltaTime; //匀速旋转
transform.localEulerAngles = new Vector3(0, 0, nowAngle);
}
else if (nowType == RollType.Stop)
{
//速度慢慢变小,转盘慢慢的慢下来
speed = Mathf.Lerp(speed, Mathf.Min(speed, tarAngle * 0.25f), Time.deltaTime);
// Debug.Log("speed = " + speed);
if (speed < 5)
{
speed = 5;
}
float angle = speed * Time.deltaTime;
tarAngle -= angle;
nowAngle -= angle;
if (tarAngle < 0)
{
Debug.Log("转盘停止转动");
nowType = RollType.None;
}
else
{
transform.localEulerAngles = new Vector3(0, 0, nowAngle);
}
}
if (nowAngle < -360)
{
nowAngle += 360;
}
}
public void StartQuan(float tarAngle, string giftName)
{
if (nowType != RollType.None)
{
return;
}
grifName = giftName;
this.tarAngle = 360 * 2 - tarAngle;
nowType = RollType.Start;
time = 0;
nowAngle = transform.localEulerAngles.z;
speed = 0;
}
}
-------------------------------------------------完毕---------------------
unity开发抽奖系统相关推荐
- 使用unity开发答题系统
该项目的代码没有什么坑,工程下载下来直接使用即可,工程下载链接:https://download.csdn.net/download/qq_37491893/10922322 忘记做自适应了,使用的分 ...
- 【蓝鸥Unity开发基础三】课时3 Terrain地形系统【未完】
[蓝鸥Unity开发基础三]课时3 Terrain地形系统[未完] 推荐视频讲师博客:http://11165165.blog.51cto.com/ 一.Terrain地形系统 Terrain地形系 ...
- 抽奖功能java开发_基于Java实现抽奖系统
摘要:这篇Java开发技术栏目下的"基于Java实现抽奖系统",介绍的技术点是"抽奖系统.Java.抽奖.基于.系统.实现",希望对大家开发技术学习和问题解决有 ...
- 问卷调查抽奖系统开发
问卷调查抽奖系统开发 核心功能:问卷抽奖.多开版本.强制关注.抽奖开关.支持实物/红包.区域限制.提交/中奖限制.自定义表单.多店员核销. 简介:一款附带抽奖模块的表单多开应用,内置:单行文本,数字, ...
- H5盲盒商城网站源码开发小程序抽奖系统商城搭建 VUE+PHP后台项目
这是H5盲盒商城网站源码开发小程序抽奖系统商城搭建 VUE+PHP后台项目(代码不加密,开源) 1.带推广二维码功能 2.含充值3级分销功能 3.盲盒回收成余/额功能 等功能 可以个性化定制开发等 源 ...
- 【干货】我是如何开发公司年会抽奖系统的?
文章目录 需求出现 需求分析 并发问题 性能问题 前端优化 总结 需求出现 年会将近,而年会抽奖环节必不可少,但是抽奖系统却还没有.所以某一天,PM走过来说:小伙,手头的需求修完成了吧!在年会开始 ...
- php开发的抽奖系统源码,幸运九宫格类型的,带后台可控制
好代码简介: 幸运九宫格抽奖码抽奖系统,适合营销,门店活动,公司活动,微信抽奖,公众号抽奖.可设置背景音乐,可设置中奖概率,可以设置奖项. 抽奖营销工具,广泛应用于 :公司年会.商场促销.销售促销.答 ...
- unity开发入门_Unity游戏开发终极入门指南
unity开发入门 Unity is a great tool for prototyping everything from games, to interactive visualisations ...
- 从限流削峰到性能优化,谈1号店抽奖系统架构实践
1.前言 抽奖是一个典型的高并发场景应用,平时流量不多,但遇到大促活动,流量就会暴增,今年的周年庆期间的日均UV就超过百万.在过去的一年里,负责过这个项目的多次重构工作,期间各种踩坑无数,就以此文当做 ...
最新文章
- 一文了解人脸识别:从实现方法到应用场景都讲明白了
- 优秀案例:12个精美的设计工作室 设计公司网站
- [WPF]ListView点击列头排序功能实现
- r.java是什么_R.java文件介绍
- Python可视化 | Seaborn(01)
- 补发《超级迷宫》站立会议八
- 微信小程序 地图实现查找标记地点
- html怎样制作表格模板,Word怎么做入职表格模板
- SEKAI CTF 部分WP(我超,初音未来)
- HACCP的相关文献包含哪些?
- 四旋翼无人机动力学模型及控制
- 量子计算机采用超导技术吗,新发现的超导体材料可能是量子计算机的硅
- 谈谈#define xxxx(x,y) x##y
- ICA简介:独立成分分析
- vue实现登录时的图片验证码(纯前端)
- CAN休眠唤醒压力测试
- 内存不能为read/written 问题的简单解决办法
- 大数据周会-本周学习内容总结017
- java 2实验指导_java2实用教程实验指导模版代码答案.doc
- 互联网快讯:极米优质产品助力大屏观影;中兴手机官宣吴京为全新代言人
热门文章
- 快速数论变换与多项式常用运算
- PWM的周期和占空比是如何计算
- 香帅的北大金融学课笔记3 -- 投资银行
- Five I/O Models
- 《四叶游戏》:梦想执念·棒球1号位
- linux防火墙端口配置策略路由,Linux iptables防火墙详解 + 配置抗DDOS攻击策略实战...
- 快速调用编辑器来写一条长,复杂或难的命令--用Enki学Linux系列(5)
- sqlserver 抓取所有执行语句 SQL语句分析 死锁 抓取
- python电子英汉词典显示_如何使用python为Linux打造一款命令行下的在线英汉词典...
- FAT32 学习及注意事项