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实现简单抽奖系统 的全部内容, 来源链接: utcz.com/z/356089.html

回到顶部