Unity幸运转轮 实现

来源:互联网 发布:数据防泄漏软件 编辑:程序博客网 时间:2024/04/29 23:38

本来针对个人应用修改较多,请阅读参考链接:孙广东 http://blog.csdn.net/u010019717/article/details/51902837

简介:
现如今很多的游戏都有幸运转轮活动,有的是特效按顺序一次播放形成旋转效果(如王者荣耀),有的是转动轮盘或者指针,这里讲的是后一种(如图)。
幸运转盘

1.场景设置
转轮:
-美术做好UI界面,确保幸运轮的每个部分大小一致。
-在幸运轮边缘建立圆形的小碰撞器并将它们作为幸运轮的子游戏物体。

箭头:
给箭头添加BoxCollider2D和HingeJoint2D组件,和下面的脚本。

注:Hinge Joint铰链 官方文档https://docs.unity3d.com/Manual/class-HingeJoint.html

2.编码:

using UnityEngine;  using System.Collections;  using System.Collections.Generic;  public class SpinWheel : MonoBehaviour  {      public List<AnimationCurve> animationCurves; //动画曲线列表     private bool spinning;  //是否在旋转中    private float anglePerItem;  //每个item角度(360/item个数)    private int randomTime;  //旋转时间    private int itemNumber;  //item个数    private bool rotateCommand = false; //旋转命令    private int targetItemIndex; //目标item索引(从0开始)    private bool CW = true; //是否顺时针    private System.Action EndCallBack; //旋转结束回调    void Start(){          spinning = false;          //避免没有预设曲线报错(这里建一条先慢再快再慢的动画曲线)        if (animationCurves== null)        {             Keyframe[] ks = new Keyframe[3];            ks[0] = new Keyframe(0, 0);            ks[0].inTangent = 0;            ks[0].outTangent = 0;            ks[1] = new Keyframe(0.5f,0.5f);            ks[1].inTangent = 1;            ks[1].outTangent = 1;            ks[2] = new Keyframe(1,1);            ks[2].inTangent =0;            ks[2].outTangent =0;            AnimationCurve animationCurve = new AnimationCurve(ks);            animationCurves.Add(animationCurve);        }       }      /// <summary>    /// 开启旋转调用(外部调用)    /// </summary>    /// <param name="itemNum">item总个数</param>    /// <param name="itemIndex">目标item索引,从0开始</param>    /// <param name="cw">是否顺时针</param>    /// <param name="callback">结束回调</param>    public void RotateUp(int itemNum, int itemIndex, bool cw, System.Action callback)    {        itemNumber = itemNum;        anglePerItem = 360 / itemNumber;        targetItemIndex = itemIndex;        CW = cw;        EndCallBack = callback;        rotateCommand = true;    }    void  Update ()      {          if (rotateCommand && !spinning) {              randomTime = Random.Range (6,8);  //随机获取旋转全角的次数             float maxAngle = 360 * randomTime + (targetItemIndex * anglePerItem);  //需要旋转的角度            rotateCommand = false;            StartCoroutine (SpinTheWheel (randomTime, maxAngle));          }      }      IEnumerator SpinTheWheel (float time, float maxAngle)      {          spinning = true;          float timer = 0.0f;               float startAngle = transform.eulerAngles.z;               //减去相对于0位置的偏移角度        maxAngle = maxAngle - GetFitAngle(startAngle);        //根据顺时针逆时针不同,不同处理        int cw_value = 1;        if (CW)        {            cw_value = -1;        }        int animationCurveNumber = Random.Range (0, animationCurves.Count);  //获取一个随机索引        while (timer < time) {          //计算旋转,动画曲线的Evaluate函数返回了给定时间下曲线上的值:从0到1逐渐变化,速度又每个位置的切线斜率决定。            float angle = maxAngle * animationCurves [animationCurveNumber].Evaluate (timer / time) ;              //得到的angle从0到最大角度逐渐变化 速度可变,让给加到旋转物角度上实现逐渐旋转 速度可变            transform.eulerAngles = new Vector3 (0.0f, 0.0f, cw_value *angle + startAngle);              timer += Time.deltaTime;              yield return 0;          }          //避免旋转有误,最终确保其在该在的位置        transform.eulerAngles = new Vector3 (0.0f, 0.0f, cw_value *maxAngle + startAngle);         //执行回调         if (EndCallBack != null)        {            EndCallBack();            EndCallBack = null;        }        spinning = false;      }          //获取相对角度    private float GetFitAngle(float angle)    {        if (angle > 0)        {            if (angle - 360 > 0)            {                return GetFitAngle(angle - 360);            }            else            {                return angle;            }        }        else        {            if (angle + 360 < 0)            {                return GetFitAngle(angle + 360);            }            else            {                return angle;            }        }    }}  

注解:
这里使用AnimationCurve动画曲线来控制轮子转动,设置不同的曲线类型可以实现不同的效果。
1/ 可以先前把脚本放到物体上,预设好曲线
这里写图片描述

2/ 也可以代码动态创建曲线
因为官方没有预设曲线demo,所以要自己创建,常用3种如下:

No.1 先慢再快再慢

Keyframe[] ks = new Keyframe[3];ks[0] = new Keyframe(0, 0);ks[0].inTangent = 0;ks[0].outTangent = 0;ks[1] = new Keyframe(0.5f,0.5f);ks[1].inTangent = 1;ks[1].outTangent = 1;ks[2] = new Keyframe(1,1);ks[2].inTangent =0;ks[2].outTangent =0;AnimationCurve animationCurve = new AnimationCurve(ks);

得到曲线:
这里写图片描述

No.2 先慢再快

Keyframe[] ks = new Keyframe[2];ks[0] = new Keyframe(0, 0);ks[0].inTangent = 0;ks[0].outTangent = 0;ks[1] = new Keyframe(1,1);ks[1].inTangent = 2;ks[1].outTangent = 2;AnimationCurve animationCurve = new AnimationCurve(ks);

得到曲线:
这里写图片描述

No.3 先快再慢

Keyframe[] ks = new Keyframe[2];ks[0] = new Keyframe(0, 0);ks[0].inTangent = 2;ks[0].outTangent = 2;ks[1] = new Keyframe(1,1);ks[1].inTangent = 0;ks[1].outTangent = 0;AnimationCurve animationCurve = new AnimationCurve(ks);

得到曲线:
这里写图片描述

这里简单介绍一下Unity动画曲线AnimationCurve,详细内容参考AnimationCurve:
http://blog.csdn.net/qq_33337811/article/details/54914905

0 0
原创粉丝点击