這段時(shí)間工作比較空閑,想做個(gè)抽獎(jiǎng)系統(tǒng),發(fā)現(xiàn)網(wǎng)上的抽獎(jiǎng)系統(tǒng)看不懂,然后自己做了一個(gè)可以隨意定義獎(jiǎng)品概率,不管什么時(shí)候停下來指針最終都會(huì)轉(zhuǎn)到指定的獎(jiǎng)品哪。
專注于為中小企業(yè)提供成都做網(wǎng)站、成都網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)方正免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了超過千家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
廢話不多說,動(dòng)手一步一步來。
這個(gè)抽獎(jiǎng)系統(tǒng)就使用了兩張圖片,一個(gè)指針,一個(gè)圓形的圖片。
然后做一個(gè)預(yù)制體,圖片就是圓形圖片,image type選擇filled,fill amount控制這個(gè)圖片的面積大小,同時(shí)也是該圖片的概率,Text組件是該獎(jiǎng)品的名稱。
再接下來就做一下界面布局的工作
Bg就是那個(gè)灰色的圖片,Rotate是個(gè)空物體,用來掛在腳本的(DialRotate.cs和Slot.cs),cloneParent也是個(gè)空物體,作為預(yù)制體的父物體,要注意的是cloneParent中心那個(gè)藍(lán)色的圓圈要和Rotate的藍(lán)色的圈的位置一致,界面布局工作完成。
接下來到代碼了,Slot.cs腳本,一開始會(huì)實(shí)例化獎(jiǎng)品,K鍵和L鍵可以隨意修改獎(jiǎng)品名稱,概率(這里概率做了限制,需要使用的自己修改一下代碼即可),空格鍵會(huì)隨機(jī)拋出物品,并且開始旋轉(zhuǎn),鼠標(biāo)右鍵是停止轉(zhuǎn)動(dòng)(想什么時(shí)候停下來都行,最后都會(huì)得到所拋出的物體)DialRotate.cs腳本用于處理旋轉(zhuǎn)的。這兩個(gè)腳本涉及到一些數(shù)學(xué)計(jì)算,慢慢理解即可。
以下是這個(gè)工程的腳本,需要的話直接復(fù)制黏貼即可使用
Slot.cs
using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class Slot : MonoBehaviour { private DialRotate dialRotate; ////// 獎(jiǎng)品數(shù)據(jù) /// private class GrifData { ////// 獎(jiǎng)品的名稱 /// public string mText; ////// 圖片的Amount值 /// public float point; ////// 獎(jiǎng)品停留在指針時(shí)父物體要旋轉(zhuǎn)的角度 /// public float angle; ////// 該獎(jiǎng)品對(duì)應(yīng)UI面板上的名稱 /// public string mtran; ////// 該獎(jiǎng)品的ID /// public int gID; } ////// 獎(jiǎng)品的描述信息 /// private class GrifInfo { public Text mText; public string msg; } private ListmListSD = new List (); /// /// 獎(jiǎng)品的id和概率對(duì)應(yīng) /// private DictionarymPoints = new Dictionary (); /// /// 用于儲(chǔ)存獎(jiǎng)品信息(順序排列)(獎(jiǎng)品的id,名稱,所占的百分比) /// private ListgrigtData = new List (); /// /// 這個(gè)也是用于儲(chǔ)存獎(jiǎng)品信息,不過是亂序排列(獎(jiǎng)品的id,名稱,所占的百分比) /// private ListrandomData = new List (); /// /// 20種獎(jiǎng)品的Transform,(最多20個(gè)不用的獎(jiǎng)勵(lì)) /// private ListmTransLs = new List (); private List mColors = new List (); private Transform cloneParent; private GameObject clonePrefab; /// /// 抽獎(jiǎng)停止時(shí)父物體轉(zhuǎn)動(dòng)的角度 /// public float tarAngle; ////// 該獎(jiǎng)品對(duì)應(yīng)UI面板上的名稱 /// public string tarName; public int giftID; ////// 用于檢驗(yàn)概率有沒有為100% /// private ListcheckProbability = new List (); private void Start() { cloneParent = transform.Find("cloneParent"); clonePrefab = Resources.Load ("Clone"); dialRotate = GetComponent (); Init(); } void Update() { #region 測試修改獎(jiǎng)品,概率 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("薯?xiàng)l", 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("薯?xiàng)l", 0.3f, 1); AddData("漢堡", 0.1f, 2); AddData("炸雞", 0.2f, 4); AddData("啤酒", 0.05f, 5); AddData("可樂", 0.15f, 6); AddData("烤肉", 0.2f, 7); SetPriceRange(); } /// /// 獲得隨機(jī)顏色 /// ///private Color GetColors() { return new Color(Random.Range(0, 1.0f), Random.Range(0, 1.0f), Random.Range(0, 1.0f)); } /// /// 清除獎(jiǎng)品的相關(guān)數(shù)據(jù)和設(shè)置新的顏色 /// public void ClearData() { grigtData.Clear(); foreach (Transform tr in mTransLs) { tr.GetComponent().color = GetColors(); tr.gameObject.SetActive(false); } } /// /// 設(shè)置獎(jiǎng)勵(lì)信息 /// /// 名稱 /// 所占的百分比 /// 該獎(jiǎng)品的ID public void AddData(string text, float point, int gID) { if (point < 0.05f) { Debug.LogError("獎(jiǎng)品的概率不能小于5%"); } if (point >1.0f) { Debug.LogError("獎(jiǎng)品的概率不能大于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); } ////// 設(shè)置獎(jiǎng)品轉(zhuǎn)盤的面積的大小顯示 /// public void SetPriceRange() { float total = 0; for (int i = 0; i < checkProbability.Count; i++) { total += checkProbability[i]; } if (total.ToString() !="1") { Debug.LogError("獎(jiǎng)品的概率總和不等于百分百,請(qǐng)從新設(shè)定概率"); return; } transform.localEulerAngles = Vector3.zero; // ListtemDate = mData.OrderBy(mData => mData.point).ToList(); //升序排序 //亂序排列 randomData.Clear(); int count = grigtData.Count; //所設(shè)置的獎(jiǎng)品的個(gè)數(shù) 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++) //把設(shè)置了獎(jiǎng)品的顯示出來 { Transform tr = mTransLs[i]; tr.gameObject.SetActive(true); // Debug.Log(ramData[i].mText + "/n"); //因?yàn)槔L制獎(jiǎng)勵(lì)區(qū)域是從轉(zhuǎn)盤的下面6點(diǎn)順時(shí)針方向開始繪制,而指針是在上面9點(diǎn),轉(zhuǎn)盤是順時(shí)針轉(zhuǎn)動(dòng),加多180度, //ramData[i].point/2 使得轉(zhuǎn)盤停下來時(shí)使得獎(jiǎng)品剛好處于指針的中間 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(); //暫時(shí)預(yù)留,發(fā)獎(jiǎng)品不是單倍的時(shí)候有用 grifInfo.mText = text; //暫時(shí)預(yù)留,發(fā)獎(jiǎng)品不是單倍的時(shí)候有用 grifInfo.msg = randomData[i].mText; //暫時(shí)預(yù)留,發(fā)獎(jiǎng)品不是單倍的時(shí)候有用 mListSD.Add(grifInfo); //暫時(shí)預(yù)留,發(fā)獎(jiǎng)品不是單倍的時(shí)候有用 tr.GetComponent ().fillAmount = randomData[i].point; //這個(gè)是旋轉(zhuǎn)所設(shè)置的獎(jiǎng)品的角度 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); } } /// /// 設(shè)置獎(jiǎng)品的倍數(shù) /// /// 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; } } } ////// 獲得結(jié)果(得到概率) /// 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]; //該獎(jiǎng)品對(duì)應(yīng)的概率(Amount值) if (probability < nowSub) { tarAngle = randomData[i].angle; //該獎(jiǎng)品停止轉(zhuǎn)動(dòng)時(shí)需要轉(zhuǎn)動(dòng)的角度 tarName = randomData[i].mtran; //該獎(jiǎng)品的名稱 giftID = randomData[i].gID; //ID testStr ="獎(jiǎng)品名稱 = " + randomData[i].mText + " 獎(jiǎng)品概率 = " + (mPoints[randomData[i].gID] * 100 + " UI上的名稱 = " + tarName + " 獎(jiǎng)品的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, //開始轉(zhuǎn)動(dòng) ConstantSpeed, //勻速運(yùn)動(dòng) Stop, //停止運(yùn)動(dòng) } public class DialRotate : MonoBehaviour { private RollType nowType = RollType.None; private float tarAngle; //該獎(jiǎng)品停下來時(shí)父物體Z軸需要轉(zhuǎn)動(dòng)的角度 ////// 當(dāng)前Z軸的值 /// private float nowAngle = 0; private string grifName; private float time;//計(jì)時(shí)器 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; //這些數(shù)值影響轉(zhuǎn)盤的轉(zhuǎn)動(dòng)速度,自己看著喜歡調(diào)節(jié)即可 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; //勻速旋轉(zhuǎn) transform.localEulerAngles = new Vector3(0, 0, nowAngle); } else if (nowType == RollType.Stop) { //速度慢慢變小,轉(zhuǎn)盤慢慢的慢下來 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("轉(zhuǎn)盤停止轉(zhuǎn)動(dòng)"); 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; } }
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。