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;
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Unity实现跑马灯抽奖效果

    Unity 跑马灯抽奖效果实现代码,供大家参考,具体内容如下 这边用到插件是NGUI+Dotween,思路简单说下:先排版,通过移动图片蒙版来实现效果. 下面是排版和文件目录. 代码部分是通过余数去确认停的位置,boxlist通过unity拖拉加入数据,chooseBoxList直接通过余数判断添加. 代码量很少,稍微看下就明白了. 直接上代码了: using System; using System.Collections; using System.Collections.Generic;

  • Unity 2017使用UGUI实现大转盘抽奖

    本文实例为大家分享了Unity 2017实现大转盘抽奖的具体代码,供大家参考,具体内容如下 涉及到的插件:Dotween 在"Hierarchy"面板创建一个Image,这个Image用来显示大转盘的那个圆盘,我用的UGUI里默认的那个圆圆的图片,放大后很模糊,不过不打紧 接着创建一个Panel名字改成"奖品组",这个是奖品的父物体,记得吧Panel里的Image,Canvas Renderer组件删了 然后在创建一个Panel名字改成"Awar"

  • unity实现简单抽奖系统

    这段时间工作比较空闲,想做个抽奖系统,发现网上的抽奖系统看不懂,然后自己做了一个可以随意定义奖品概率,不管什么时候停下来指针最终都会转到指定的奖品哪. 废话不多说,动手一步一步来. 这个抽奖系统就使用了两张图片,一个指针,一个圆形的图片. 然后做一个预制体,图片就是圆形图片,image type选择filled,fill amount控制这个图片的面积大小,同时也是该图片的概率,Text组件是该奖品的名称. 再接下来就做一下界面布局的工作 Bg就是那个灰色的图片,Rotate是个空物体,用来挂在

  • python实现的简单抽奖系统实例

    本文实例讲述了python实现的简单抽奖系统.分享给大家供大家参考.具体实现方法如下: #!/usr/bin/env python #coding=utf-8 from Tkinter import * import time import random class App: def __init__(self,master): frame = Frame(master) frame.pack() v = StringVar() self.e = Entry(frame,textvariable

  • JavaScript实现简单抽奖系统

    本文实例为大家分享了JavaScript实现简单抽奖系统的具体代码,供大家参考,具体内容如下 模拟实现抽奖系统 前端使用JavaScript代码实现抽奖系统,代码如下: 样式代码: <style>         body{             background: url("bg.jpg") no-repeat;             background-size: 100%;         }         #box{             positi

  • 基于javascript实现简单的抽奖系统

    本文实例为大家分享了js实现简单的抽奖系统,供大家参考,具体内容如下 <!doctype html> <html lang="en"> <head> <meta charset="gb2312"> <title>抽奖活动</title> <style> *{ margin:0;padding:0; } #title{ color:red;text-align:center;margi

  • 用Javascript轻松制作一套简单的抽奖系统

    作者:jegg  年底将至,许多公司忙着搞年会,会上一般都会有一些抽奖活动,下面的程序就是用javascript 写的一个简单的抽奖系统与大家共享. 此代码借鉴了网上的一些网友的代码,又加上了一些诸如不重复抽奖之类的改进.大概思路如下: 1.将所有的的抽奖数据(这里为手机号码)存入数组中. 2.使用random 函数随机产生该数组的INDEX 3.使用setInterval 函数以极短的时间间隔产生该数组随机INDEX所对应的手机号码,并显示.       4.使用removeEleAt(ind

  • js实现简单的抽奖系统

    一个用js编写的简单的抽奖系统,供大家参考,具体内容如下 效果图如图所示:字节带闪动,点击开始,可进行抽奖,并且按钮变为结束按钮,然后点击结束按钮,可以结束,并抽奖成功. 代码如下: <!DOCTYPE html> <html>     <head>         <meta charset="UTF-8">         <title>抽奖</title>         <style type=&qu

  • C语言实现简单的抽奖系统

    本文实例为大家分享了C语言实现简单的抽奖系统的具体代码,供大家参考,具体内容如下 效果图 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<conio.h> #include<time.h> #include <windows.h>   struct data{     char id[20];     char name[20]; };   int t1

  • 简单实现java抽奖系统

    本文为大家分享了java抽奖系统的具体代码,供大家参考,具体内容如下 用户信息类 /* * 用户信息类 * 1.账号 * 2.密码 * 3.卡号 * 4.是否登录 */ public class User { public static String userName = ""; public static String passWord = ""; public static int cardNumber = 0; // 是否登录 public static bo

  • 基于JavaScript实现抽奖系统

    用JavaScript实现一个简单的抽奖系统,有[开始]按钮和[停止]按钮. 功能: - 点开始按钮开始抽奖,随机出现奖品名称: - 点停止按钮即可停止抽奖: - 按下回车键可切换开始抽奖和停止抽奖. 效果 html代码: 创建html结构,最基础的要含有显示的奖品名称和开始.停止按钮. <!doctype html> <html> <head> <title>抽奖系统</title> <meta charset="utf-8&q

  • 基于Java实现抽奖系统

    本次任务要求为某商场开发一套幸运抽奖系统,客户必须首先注册成为该商场会员,会员登录成功后,就可以参加抽奖活动了. 注册 用户选择"注册"菜单,进入注册界面.输入用户名和密码后,系统提示注册成功,并给出会员卡号. 登录 注册成功后,用户选择"登录"菜单,进入登录界面.输入注册时的用户名和密码.登录成功,系统提示欢迎信息.如果用户和密码输入错误,提示用户继续输入,最多有3次机会. 抽奖 登录成功后,用户选择"抽奖"菜单,进入幸运抽奖界面.输入会员卡号

随机推荐