这段时间工作比较空闲,想做个抽奖系统,发现网上的抽奖系统看不懂,然后自己做了一个可以随意定义奖品概率,不管什么时候停下来指针最终都会转到指定的奖品哪。
成都创新互联,专注为中小企业提供官网建设、营销型网站制作、响应式网站、展示型网站制作、网站建设等服务,帮助中小企业通过网站体现价值、有效益。帮助企业快速建站、解决网站建设与网站营销推广问题。废话不多说,动手一步一步来。
这个抽奖系统就使用了两张图片,一个指针,一个圆形的图片。
然后做一个预制体,图片就是圆形图片,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; ////// 奖品数据 /// private class GrifData { ////// 奖品的名称 /// public string mText; ////// 图片的Amount值 /// public float point; ////// 奖品停留在指针时父物体要旋转的角度 /// public float angle; ////// 该奖品对应UI面板上的名称 /// public string mtran; ////// 该奖品的ID /// public int gID; } ////// 奖品的描述信息 /// private class GrifInfo { public Text mText; public string msg; } private ListmListSD = new List (); /// /// 奖品的id和概率对应 /// private DictionarymPoints = new Dictionary (); /// /// 用于储存奖品信息(顺序排列)(奖品的id,名称,所占的百分比) /// private ListgrigtData = new List (); /// /// 这个也是用于储存奖品信息,不过是乱序排列(奖品的id,名称,所占的百分比) /// private ListrandomData = new List (); /// /// 20种奖品的Transform,(最多20个不用的奖励) /// private ListmTransLs = new List (); private List mColors = new List (); private Transform cloneParent; private GameObject clonePrefab; /// /// 抽奖停止时父物体转动的角度 /// public float tarAngle; ////// 该奖品对应UI面板上的名称 /// public string tarName; public int giftID; ////// 用于检验概率有没有为100% /// private ListcheckProbability = new List (); private void Start() { cloneParent = transform.Find("cloneParent"); clonePrefab = Resources.Load ("Clone"); dialRotate = GetComponent (); 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 ().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(); } /// /// 获得随机颜色 /// ///private Color GetColors() { return new Color(Random.Range(0, 1.0f), Random.Range(0, 1.0f), Random.Range(0, 1.0f)); } /// /// 清除奖品的相关数据和设置新的颜色 /// public void ClearData() { grigtData.Clear(); foreach (Transform tr in mTransLs) { tr.GetComponent().color = GetColors(); tr.gameObject.SetActive(false); } } /// /// 设置奖励信息 /// /// 名称 /// 所占的百分比 /// 该奖品的ID 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); } ////// 设置奖品转盘的面积的大小显示 /// 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; // ListtemDate = 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 = randomData[i].mText; GrifInfo grifInfo = new GrifInfo(); //暂时预留,发奖品不是单倍的时候有用 grifInfo.mText = text; //暂时预留,发奖品不是单倍的时候有用 grifInfo.msg = randomData[i].mText; //暂时预留,发奖品不是单倍的时候有用 mListSD.Add(grifInfo); //暂时预留,发奖品不是单倍的时候有用 tr.GetComponent ().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); } } /// /// 设置奖品的倍数 /// /// 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; } } } ////// 获得结果(得到概率) /// 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); } }
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。