转盘这个东西在游戏中见多了 抽奖啥的都可以用到 我们也可能被它坑过好多次
这篇博客带大家用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