用unity实现大转盘

转盘这个东西在游戏中见多了 抽奖啥的都可以用到 我们也可能被它坑过好多次
这篇博客带大家用unity实现一下转盘

1.创建场景

首先整一个转盘的模型 (图片即可)
在这里插入图片描述
然后把它弄进unity的相关文件夹中 修改一下格式 改成Sprite(UI and 2D)
用UGUI创建一个Image 把它贴上去 即可
然后创建一个指针类型的图片

2.实现转盘的旋转

我的思路是让转盘旋转 也可以让指针旋转
对于旋转 我们在游戏中见到的转盘都是 开始速度比较大 然后慢慢停下来的
我们就用速度的随着时间的递减来实现,也可以用时间来限制
我们创建一个按钮来点击的时候 转盘开始旋转

 private float RotateSpeed;//旋转速度
  private void Start()
    {
        RotateSpeed = 0;
    }
    private void Update()

    {
        RotateSpeed -= Time.deltaTime * 100;//随着时间递减
        transform.Rotate(Vector3.forward * Time.deltaTime * RotateSpeed);
       
        if (RotateSpeed <= 0)
        {
            RotateSpeed = 0;
            Time.timeScale = 0;//为了实现旋转速度为0之后不再乱动
        }
    }
    public void StartButton()//开始按钮
    {
        RotateSpeed = Random.Range(1000, 2500);
        Time.timeScale = 1;
    }

上边的StartButton()是给unity中的一个按钮注册的事件
这应该是比较简单的
添加上上边的脚本后 就可以实现点击转盘开始旋转

3.检测获奖类型

这个效果比较难实现 因为其中的transform.rotation是四元数类型的
直接赋值产生错误
然后我百般搜寻 找到一个可以吧四元数转换成Vector3类型的方法

public Vector3 GetInspectorRotationValueMethod(Transform transform)//把四元数转换成为Vector3类型的参数
    {
        // 获取原生值
        System.Type transformType = transform.GetType();
        PropertyInfo m_propertyInfo_rotationOrder = transformType.GetProperty("rotationOrder", BindingFlags.Instance | 		BindingFlags.NonPublic);
        object m_OldRotationOrder = m_propertyInfo_rotationOrder.GetValue(transform, null);
        MethodInfo m_methodInfo_GetLocalEulerAngles = transformType.GetMethod("GetLocalEulerAngles", BindingFlags.Instance | BindingFlags.NonPublic);
        object value = m_methodInfo_GetLocalEulerAngles.Invoke(transform, new object[] { m_OldRotationOrder });
        string temp = value.ToString();
        //将字符串第一个和最后一个去掉
        temp = temp.Remove(0, 1);
        temp = temp.Remove(temp.Length - 1, 1);
        //用‘,’号分割
        string[] tempVector3;
        tempVector3 = temp.Split(',');
        //将分割好的数据传给Vector3
        Vector3 vector3 = new Vector3(float.Parse(tempVector3[0]), 
            float.Parse(tempVector3[1]), float.Parse(tempVector3[2]));
        return vector3;
    }

然后我的思路是记录下来停止的时候转盘旋转的角度
然后根据角度来判断获奖的类型
首先从创建一个枚举类型来创建几个奖品的类型

public enum PrizeType//几种获奖状态
{
    SuperPrize,
    FirstPrize,
    SecondPrize,
    ThirdPrize,
    ThankYou
}

更新获奖的状态 在update中检测 下面的角度都是在unity中试出来的

private void UpdateAngle()//更新状态
    {
        float angle = AngleZ;//临时变量来处理角度的超出范围的问题
        if (angle > 360)
        {
            angle -= 360;
        }
        else if (angle < -331.2f)
        {
            angle += 360;
        }
        if(angle >= -31.7f && angle < 32.6f)
        {
            type = PrizeType.FirstPrize;
        }
        else if (angle >= -91.1f && angle < -31.7f)
        {
            type = PrizeType.SuperPrize;
        }
        else if (angle >= -149.5f && angle < -91.1f)
        {
            type = PrizeType.ThankYou;
        }
        else if (angle >= -210f && angle < -149.5f)
        {
            type = PrizeType.ThirdPrize;
        }
        else if (angle >= -269f && angle < -210f)
        {
            type = PrizeType.SecondPrize ;
        }
        else if (angle >= -331.2f && angle < -269f)
        {
            type = PrizeType.ThankYou;
        }
    }

更新获奖之后UI的提示效果 在update中检测

 private void UpdatePrize()//更新奖品
    {
        switch(type)
        {
            case PrizeType.FirstPrize :
                Text = "恭喜你获得一等奖!";
                break;
            case PrizeType.SecondPrize :
                Text = "恭喜你获得二等奖!";
                break;
            case PrizeType.ThirdPrize:
                Text = "恭喜你获得三等奖!";
                break;
            case PrizeType.SuperPrize:
                Text = "恭喜你获得特等奖!";
                break;
            case PrizeType.ThankYou :
                Text = "感谢参与!";
                break;

        }

    }

4.完整代码

using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public enum PrizeType//几种获奖状态
{
    SuperPrize,
    FirstPrize,
    SecondPrize,
    ThirdPrize,
    ThankYou
}

public class test : MonoBehaviour
{
    private float RotateSpeed;//旋转速度
    private  Vector3   PauseAngle;//获取转变的Vector3类型
    private  float AngleZ;//z轴

    private string Text;//提示文字
    public Text TextUI;//提示文字UI
    private bool enable = false;//控制UI出现的bool值
    
    public  PrizeType type;//奖品类型

    private void Start()
    {
        RotateSpeed = 0;
        TextUI.enabled = false;
    }
    private void Update()

    {
        UpdateAngle();//更新角度
        UpdatePrize();//更新奖品
        RotateSpeed -= Time.deltaTime * 100;
        TextUI.text = Text;
        transform.Rotate(Vector3.forward * Time.deltaTime * RotateSpeed);
       

        if (RotateSpeed <= 0)
        {
            RotateSpeed = 0;
            Time.timeScale = 0;
            PauseAngle = GetInspectorRotationValueMethod(transform);
            AngleZ = PauseAngle.z;
            if(enable)
            {
                TextUI.enabled = true;
            }
        }
        
       
    }
    public void StartButton()//开始按钮
    {
        RotateSpeed = Random.Range(1000, 2500);
        Time.timeScale = 1;
        enable = true;
    }

    private void UpdateAngle()//更新状态
    {
        float angle = AngleZ;//临时变量来处理角度的超出范围的问题
        if (angle > 360)
        {
            angle -= 360;
        }
        else if (angle < -331.2f)
        {
            angle += 360;
        }
        if(angle >= -31.7f && angle < 32.6f)
        {
            type = PrizeType.FirstPrize;
        }
        else if (angle >= -91.1f && angle < -31.7f)
        {
            type = PrizeType.SuperPrize;
        }
        else if (angle >= -149.5f && angle < -91.1f)
        {
            type = PrizeType.ThankYou;
        }
        else if (angle >= -210f && angle < -149.5f)
        {
            type = PrizeType.ThirdPrize;
        }
        else if (angle >= -269f && angle < -210f)
        {
            type = PrizeType.SecondPrize ;
        }
        else if (angle >= -331.2f && angle < -269f)
        {
            type = PrizeType.ThankYou;
        }
    }
    public Vector3 GetInspectorRotationValueMethod(Transform transform)//把四元数转换成为Vector3类型的参数
    {
        // 获取原生值
        System.Type transformType = transform.GetType();
        PropertyInfo m_propertyInfo_rotationOrder = transformType.GetProperty("rotationOrder", BindingFlags.Instance | BindingFlags.NonPublic);
        object m_OldRotationOrder = m_propertyInfo_rotationOrder.GetValue(transform, null);
        MethodInfo m_methodInfo_GetLocalEulerAngles = transformType.GetMethod("GetLocalEulerAngles", BindingFlags.Instance | BindingFlags.NonPublic);
        object value = m_methodInfo_GetLocalEulerAngles.Invoke(transform, new object[] { m_OldRotationOrder });
        string temp = value.ToString();
        //将字符串第一个和最后一个去掉
        temp = temp.Remove(0, 1);
        temp = temp.Remove(temp.Length - 1, 1);
        //用‘,’号分割
        string[] tempVector3;
        tempVector3 = temp.Split(',');
        //将分割好的数据传给Vector3
        Vector3 vector3 = new Vector3(float.Parse(tempVector3[0]), 
            float.Parse(tempVector3[1]), float.Parse(tempVector3[2]));
        return vector3;
    }

    private void UpdatePrize()//更新奖品
    {
        switch(type)
        {
            case PrizeType.FirstPrize :
                Text = "恭喜你获得一等奖!";
                break;
            case PrizeType.SecondPrize :
                Text = "恭喜你获得二等奖!";
                break;
            case PrizeType.ThirdPrize:
                Text = "恭喜你获得三等奖!";
                break;
            case PrizeType.SuperPrize:
                Text = "恭喜你获得特等奖!";
                break;
            case PrizeType.ThankYou :
                Text = "感谢参与!";
                break;

        }

    }
}

其中有一些关于UI最最简单的操作 我就没有详细写
就这样就实现了一个转盘的效果

5.实现每次抽到都是三等奖或是感谢参与

这样做是比较坏的 哈哈
但是游戏中很多时候都是 先氪金或充值才能抽到很好的装备等
我们可以在如果在特等奖或一等奖的时候 转盘的速度稍微加上一个合适的值(一定要小 让人看不出来)
然后就慢慢滑到了谢谢参与上或者三等奖上边
然后检测到氪金之后
可以正常抽奖
本人热爱交友 qq 1149293885

发布了52 篇原创文章 · 获赞 47 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44302602/article/details/103528561