unity 转盘记录

unity 转盘

设置pointer点对象,可以设置指针转动或者转盘转动,具体看代码
可以设置顺逆旋转
在这里插入图片描述

注意结构
在这里插入图片描述
在这里插入图片描述

数据的配置 自己可以选择自己的写法,这里因为比较简单就用scriptableobject弄一下
在这里插入图片描述
在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using XYX;

public enum SpinState
{
    None,       //待机状态
    Start,      //加速阶段
    Prepared,   //等待数据阶段
    End,        //减速阶段
}

/// <summary>
/// 转盘
/// </summary>
public class TurnTableView : UIBase
{
    [Tooltip("转动的东西")]
    public Transform pointer;//转动点
    public Animator arrowAnim;
    public Sprite advImg;
    public Sprite flower;

    Transform[] Spins;//对应的slots,需要提前制定数量
    Text spinNum;
    Image spinImg;

    protected override void Awake()
    {
        base.Awake();
        root =transform.Find("root") as RectTransform;
        Transform Spin = GetUIComponent<Image>("Spin").transform;
        Spins = new Transform[Spin.childCount];
        for (int i = 0; i < Spin.childCount; i++)
        {
            Spins[i] = Spin.GetChild(i);
            Spin.GetChild(i).GetChild(1).GetComponent<Text>().text = GameManager.turnTable_SO.spinReward[i].num_Str;
        }
        spinNum = GetUIComponent<Text>("spinNum");
        spinImg = GetUIComponent<Image>("spinImg");

        CheckMySpinNumber();
    }

    //检查自己还能转多少
   void CheckMySpinNumber()
    {
        spinImg.sprite = advImg;
        if(GameDataManager.GetInstance().commonData.turnTabelData.rotateNum<=0)
        {
           GetUIComponent<Image>("getSpinBtn").GetComponent<TweenEffects>().StopTween(true);
            spinImg.sprite = advImg;
            spinNum.text =  "+1";
        }
        else
        {
            GetUIComponent<Image>("getSpinBtn").GetComponent<TweenEffects>().StopTween(false);
            spinImg.sprite = flower;
            spinNum.text = GameDataManager.GetInstance().commonData.turnTabelData.rotateNum + "/"+ GameDataManager.GetInstance().commonData.turnTabelData.rotateNum;
        }

        spinImg.SetNativeSize();
    }


    public override void ShowView()
    {
        base.ShowView();
        _spinstate = SpinState.None;
    }

    protected override void OnClickBUt(string btnName)
    {
        switch (btnName)
        {
            case "closeBtn":
                if(_spinstate == SpinState.None)
                HideView();
                break;
            case "spinBtn":
                StartClickSpin();
                break;
            case "getSpinBtn":
                if (SdkManager.GetInstance().m_sdk_state != Mode_SDK_State.Adv) return;

                if (GameDataManager.GetInstance().commonData.turnTabelData.rotateNum <= 0)
                {
                    SdkManager.GetInstance().ShowRewardVideoAd(()=> {
                        GameDataManager.GetInstance().commonData.turnTabelData.rotateNum += 1;
                        GameDataManager.GetInstance().SaveData(XYX_Tag.COMMON);
                        CheckMySpinNumber();
                    });
                    //TODO 直接看广告
                }
                break;
        }
    }

    //开始
    void StartClickSpin()
    {
        if (_spinstate == SpinState.None)
        {
                if (GameDataManager.GetInstance().commonData.turnTabelData.rotateNum <= 0)
            {
                UIManager.GetInstance().MessageBoxUI("次数用完了!");
                return;
            }
            _spinstate = SpinState.Start;
            arrowAnim.SetBool("show",true);

            UIManager.GetInstance().FlyTxT("-1",Color.red, spinNum.transform.position);
          
            StartCoroutine("RoateTimer");//必须停止的时间
            _time = 0;
            GameDataManager.GetInstance().commonData.turnTabelData.rotateNum--;
            if (GameDataManager.GetInstance().commonData.turnTabelData.rotateNum < 0)
                GameDataManager.GetInstance().commonData.turnTabelData.rotateNum = 0;
            GameDataManager.GetInstance().SaveData(XYX_Tag.COMMON);

            CheckMySpinNumber();
            print("今日抽将次数 " + GameDataManager.GetInstance().commonData.turnTabelData.rotateNum);

        }
    }

    public int testRewardIndex = 2;

    /// <summary>
    /// 停止转动的时间
    /// </summary>
    /// <returns></returns>
    IEnumerator RoateTimer()
    {
        yield return new WaitForSeconds(GameManager.turnTable_SO.timerStop);
            OnprobabilityStopArea(testRewardIndex);//test
         //   OnprobabilityStopArea();
    }

    // 根据几率来让指针停止到对应区域 可以写特殊关照
    void OnprobabilityStopArea(int specialValue = -1)
    {
        if (specialValue < 0)
            EndAngle = GameManager.turnTable_SO.spinReward[ProbabilityChoose()].angle;
        else
        {
            spinRewardId = specialValue;
            EndAngle = GameManager.turnTable_SO.spinReward[specialValue].angle;//特殊关照的item
        }
      // print("奖励角度==========:"+ EndAngle);
   //    print("奖励角度==========:" + GameManager.turnTable_SO.spinReward[specialValue].angle);

        _spinstate = SpinState.Prepared;
    }

    int spinRewardId;

    //几率选择-返回奖励数组编号 
    int ProbabilityChoose()
    {
        //概率总精度为100
        float totalRank = 100;
        //float totalRank = 0;
        //for (int i = 0; i < GameManager.turnTable_SO.spinReward.Length; i++)
        //{
        //    totalRank += GameManager.turnTable_SO.spinReward[i].probability;//总概率=1;
        //}
        spinRewardId = 0;
        foreach (var item in GameManager.turnTable_SO.spinReward)
        {
            //产生一个0到100之间的随机数
            float random = Random.Range(0, totalRank);
            //将该随机数和奖品的概率比较
            if (random <= item.probability)
            {
                spinRewardId = item.id;
                Debug.Log(spinRewardId);
                //抽奖结果
                //为转盘指针随机生成旋转角度
                //    float angle = Random.Range(item.MinAngle, item.MaxAngle);
                //旋转转盘指针,此处略
                break;
            }
            else
            {
                totalRank -= item.probability;
            }
        }
        return spinRewardId;
    }

    private void Update()
    {
        RotateState();
    }

    private float _time;//时间统计
    private float _tmpAngle = 0f;//角度缓存
    private float _minTime = 3.0f; //减速前的最短持续时间
    private float _factor;
    private SpinState _spinstate;//转盘的状态属性

    void RotateState()
    {
        if (_spinstate == SpinState.None) return;

        _time += Time.deltaTime;
        if (_spinstate == SpinState.End)
        {
            //通过差值运算实现精准地旋转到指定角度(球型插值无法实现大于360°的计算)
            float k = 2.5f;  //如果嫌减速太慢,可以加个系数修正一下
            _tmpAngle = Mathf.Lerp(_tmpAngle, EndAngle, Time.deltaTime * k);

            // Debug.Log(_tmpAngle+"=="+EndAngle);
            //这里只存在一个方向的旋转,所以不存在欧拉角万向节的问题,所以使用欧拉角和四元数直接赋值都是可以的
            // pointer.rotation = Quaternion.Euler(0, 0, _tmpAngle);//顺
            //  pointer.rotation = Quaternion.Euler(0, 0, -_tmpAngle);//逆

            pointer.rotation = Quaternion.Euler(0, 0, GameManager.turnTable_SO.rotateDirect * _tmpAngle);
            // print("减速阶段");

            if (1 >= Mathf.Abs(_tmpAngle - EndAngle))
            {
                GetReward();
                _spinstate = SpinState.None;
            }
        }
        else
        {
            _factor = _time / GameManager.turnTable_SO.AcceleateTime;   //加速速度因子
            _factor = _factor > 1 ? 1 : _factor;//最大为1

            //   pointer.Rotate(Vector3.forward, _factor * velocity * Time.deltaTime, Space.Self);//逆时针
            // pointer.Rotate(Vector3.back, _factor * velocity * Time.deltaTime, Space.Self);//顺时针

            pointer.Rotate(Vector3.back * GameManager.turnTable_SO.rotateDirect, _factor * GameManager.turnTable_SO.velocity * Time.deltaTime, Space.Self);
        }

        //当收到数据之后并且旋转了一定时间后开始减速
        if (_spinstate == SpinState.Prepared && _time > _minTime)
        {

            _tmpAngle = GetCurClockwiseAngle();
            //  print("准备进入减速了" + _tmpAngle + "===" + EndAngle + "===" + pointer.eulerAngles.z);
            _spinstate = SpinState.End;

        }
    }

      float GetCurClockwiseAngle()// 将当前指针的欧拉角转换成顺时针统计角度
    {
        //读取到的值是 0-180,180- -180-0 [0, 180] U [-180, 0],左边由0至180递增,右边由180转变成-180,然后递增至0,所以需要转相应的转换
        return (-GameManager.turnTable_SO.rotateDirect) * (360 - pointer.eulerAngles.z) % 360;
        //return (-1) * (360 - pointer.eulerAngles.z) % 360;//顺
        //return (1) * (360 - pointer.eulerAngles.z) % 360;//逆
    }

    void GetReward()
    {
            arrowAnim.SetBool("show",false);
        Debug.Log("奖励!!"+spinRewardId);
        UIManager.GetInstance().ShowView<RewardView>("RewardView", E_UI_Layer.Mid,(v)=> { 
                              v.DrawReward(0, GameManager.turnTable_SO.spinReward[spinRewardId].num);
        });

    }

    private float _endAngle = 0f;
    /// <summary>
    /// 最终停止的角度[0, 360]
    /// </summary>
    private float EndAngle
    {
        get   { return _endAngle; }
        set
        {
            _endAngle = Mathf.Abs(value);
            //    print("End Angle: " + value);
            _endAngle = (_endAngle % 360);    //将角度限定在[0, 360]这个区间
            _endAngle = -_endAngle - 360 * GameManager.turnTable_SO.turnsNum;    //多N圈并取反,圈数能使减速阶段变得更长
        }
    }
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XyX许

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值