UGUI卡片选择

王者荣耀选择皮肤的效果大家都应该知道吧。一张张的卡片选择,今天给大家一个类,就可以实现这个功能。功能只提供了一些基本的,根据需求不同,也要各位自己做扩展。废话不多说,看代码
效果图
属性设置

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using DG.Tweening;
using System;

enum FINGER { FINGER_STATE_NUL, FINGER_STATE_TOUCH, FINGER_STATE_ADD }
public class CardMove : MonoBehaviour
{

    private GameObject[] sprites;
    private int halfSize;
    Vector2 screenCenterPos;
    public float startAngle = -90;//中间卡牌的角度
    float deltaAngle = 20;//相邻卡牌的角度差值
                          /* public float moveSpeed;//移动动画的速度*/
    public string currentSelectName;
    public Vector2 center;//椭圆中心点
    public float Y_axis = 400;//long axis
    public float X_axis = 100;//short axis
    private int cardcount;//卡牌数量

    private float fingerActionSensitivity = Screen.width * 0.05f; //手指动作的敏感度,这里设定为 二十分之一的屏幕宽度.

    private float fingerBeginX;
    private float fingerBeginY;
    private float fingerCurrentX;
    private float fingerCurrentY;
    private float fingerSegmentX;
    private float fingerSegmentY;
    private FINGER fingerTouchState;
    float angle;
    public float mouseSpeed = 1;
    public Action MoveEndAction;
   
    void Start()
    {
       
        deltaAngle = Screen.width / 100f;
        Y_axis = Screen.width / 2;
     
        UpdateChild();
    }

    /// <summary>
    /// 初始化卡牌显示位置
    /// </summary>
    void InitSprites()
    {
        screenCenterPos = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f);
        cardcount = transform.childCount;
        halfSize = (cardcount - 1) / 2;
        sprites = new GameObject[cardcount];
        for (int i = 0; i < cardcount; i++)
        {
            sprites[i] = transform.GetChild(i).gameObject;
            SetPosition(i, false);
            SetDeeps(i);
        }

    }
    /// <summary>
    /// 椭圆的半长轴为A,半短轴为B,计算椭圆上一点的位置
    /// x=A*cos(angle),y=B*sin(angle)
    /// </summary>
    /// <param name="index">Index.</param>
    /// <param name="userTweener">是否使用tween动画.</param>
    void SetPosition(int index, bool userTweener = true)
    {
        //计算每一张卡片在椭圆上相对中间卡牌的角度
        angle = 0;


        if (index < halfSize)
        {//left
            angle = startAngle - (halfSize - index) * deltaAngle;
            sprites[index].GetComponent<RectTransform>().DOScale(1f, 0.3f);
        }
        else if (index > halfSize)
        {//right

            angle = startAngle + (index - halfSize) * deltaAngle;
            sprites[index].GetComponent<RectTransform>().DOScale(1f, 0.3f);
        }
        else
        {//medim
            angle = startAngle;
            sprites[index].GetComponent<RectTransform>().DOScale(1.5f, 0.3f).OnComplete(MoveEnd);

        }

        //通过卡牌的角度,计算对应的位置
        float xpos = Y_axis * Mathf.Cos((angle / 180) * Mathf.PI) + center.x;
        float ypos = X_axis * Mathf.Sin((angle / 180) * Mathf.PI) + center.y;

        Vector2 pos = new Vector2(xpos, ypos);
        // Vector2 pos = new Vector2(center.x, center.y);
        if (!userTweener)
        {
            sprites[index].GetComponent<RectTransform>().DOMove(new Vector2(screenCenterPos.x + pos.x, screenCenterPos.y + pos.y), 0f);
        }
        else
            sprites[index].GetComponent<RectTransform>().DOMove(new Vector2(screenCenterPos.x + pos.x, screenCenterPos.y + pos.y), 0.2f);


    }
    /// <summary>
    /// 选择移动动画结束后的设置当前选择的名字和回调
    /// </summary>
    void MoveEnd()
    {
        currentSelectName = transform.GetChild(transform.childCount - 1).name;
        if (MoveEndAction != null) MoveEndAction();

    }

    /// <summary>
    /// 计算每一张卡片的层级
    /// </summary>
    /// <param name="index">Index.</param>
    void SetDeeps(int index)
    {
        int deep = 0;
        if (index < halfSize)
        {//左侧卡牌层级,从左侧到中间,层级依此递增
            deep = index;
        }
        else if (deep > halfSize)
        {//右侧卡牌层级,从中间到右侧,层级依此递减
            deep = sprites.Length - (index + 1);
        }
        else
        {
            deep = halfSize;
        }
        sprites[index].GetComponent<RectTransform>().SetSiblingIndex(deep);
    }
    public void LeftMove()
    {
        int length = sprites.Length;

        GameObject temp = sprites[0];
        for (int i = 0; i < length; i++)
        {//移动卡片在数组中的位置,依此向前移动一位
            if (i == length - 1)
                sprites[i] = temp;
            else
                sprites[i] = sprites[i + 1];

        }

        for (int i = 0; i < length; i++)
        {//更新数组卡片需要显示的位置和层级
            if (i < length - 1) SetPosition(i);
            else SetPosition(i, false);
            SetDeeps(i);



        }
    }
    public void RightMove()
    {
        int length = sprites.Length;
        GameObject temp = sprites[length - 1];
        for (int i = length - 1; i >= 0; i--)
        {
            if (i == 0)
                sprites[i] = temp;
            else
                sprites[i] = sprites[i - 1];
        }
        for (int i = 0; i < length; i++)
        {
            if (i == 0) SetPosition(i, false);
            else SetPosition(i);
            SetDeeps(i);
        }
    }
    private void Update()
    {
        CheckMouse();
    }
    private void AddFingerAction()
    {
        fingerTouchState = FINGER.FINGER_STATE_ADD;
        if (Mathf.Abs(fingerSegmentX) > Mathf.Abs(fingerSegmentY))
        {
            fingerSegmentY = 0;
        }
        else
        {
            fingerSegmentX = 0;
        }

        if (fingerSegmentY == 0)
        {
            if (fingerSegmentX > 0)
            {
                RightMove();
            }
            else
            {
                LeftMove();
            }
        }

    }

    readonly string MYMouseScrollWheel = "Mouse ScrollWheel";
    float timer, axis;//timer可以防止快速滚轮导致速度过快动画得bug
    void CheckMouse()
    {

        switch (fingerTouchState)
        {
            case FINGER.FINGER_STATE_NUL:
                if (Input.GetKeyDown(KeyCode.Mouse0))
                {
                    fingerTouchState = FINGER.FINGER_STATE_TOUCH;
                    fingerBeginX = Input.mousePosition.x;
                    fingerBeginY = Input.mousePosition.y;
                }
                break;
            case FINGER.FINGER_STATE_TOUCH:
                fingerCurrentX = Input.mousePosition.x;
                fingerCurrentY = Input.mousePosition.y;
                fingerSegmentX = fingerCurrentX - fingerBeginX;
                fingerSegmentY = fingerCurrentY - fingerBeginY;

                float fingerDistance = fingerSegmentX * fingerSegmentX + fingerSegmentY * fingerSegmentY;

                if (fingerDistance > (fingerActionSensitivity * fingerActionSensitivity))
                {
                    AddFingerAction();
                }
                break;
            case FINGER.FINGER_STATE_ADD:
                break;
        }
        if (Input.GetKeyUp(KeyCode.Mouse0))
        {
            fingerTouchState = FINGER.FINGER_STATE_NUL;
        }
        timer += Time.deltaTime;

        axis = Input.GetAxis(MYMouseScrollWheel);
        if (axis > 0 && timer > 0.2f)
        {
            timer = 0;
            LeftMove();
        }
        else if (axis < 0 && timer > 0.2f)
        {
            timer = 0;
            RightMove();
        }

    }
    void InitData()
    {
        fingerActionSensitivity = Screen.width * 0.05f;
        fingerBeginX = 0;
        fingerBeginY = 0;
        fingerCurrentX = 0;
        fingerCurrentY = 0;
        fingerSegmentX = 0;
        fingerSegmentY = 0;
    }


    public void UpdateChild()
    {
        InitSprites();
        InitData();

    }
}

卡片都会在一个椭圆的轨迹上切换,根据自己的需求不同,可以设置椭圆的X轴Y轴,也可以设置椭圆的中心点。

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值