Unity幸运转轮 实现

本文介绍了一种在Unity中实现幸运转盘的方法,包括场景设置、编码实现等步骤,并提供了控制轮盘转动速度变化的动画曲线示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本来针对个人应用修改较多,请阅读参考链接:孙广东 http://blog.youkuaiyun.com/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.youkuaiyun.com/qq_33337811/article/details/54914905

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值