314 lines
9.7 KiB
C#
314 lines
9.7 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.EventSystems;
|
||
using UnityEngine.UI;
|
||
namespace Toolset.UI
|
||
{
|
||
/// <summary>
|
||
/// 轮播图菜单
|
||
/// </summary>
|
||
public class CarouselMenu : MonoBehaviour/*, IBeginDragHandler, IDragHandler, IEndDragHandler*/, IPointerClickHandler
|
||
{
|
||
public float width = 1000;
|
||
public float maxScale = 1;
|
||
public float startValue = 0.1f;
|
||
public float addValue = 0.4f;
|
||
public float minValue = 0.1f;
|
||
public float maxValue = 0.9f;
|
||
public float rollSpeed = 1;//旋转速度
|
||
public AnimationCurve positionCurve;
|
||
public AnimationCurve scaleCurve;//缩放曲线
|
||
public AnimationCurve alphaCurve;
|
||
public Action<CarouselItem> MoveEndAction;//打印名字的事件
|
||
|
||
private RectTransform rect;
|
||
[SerializeField]private List<CarouselItem> itemList = new List<CarouselItem>();
|
||
[SerializeField] private List<CarouselItem> itemFrontList = new List<CarouselItem>();
|
||
[SerializeField] private List<CarouselItem> itemBackList = new List<CarouselItem>();
|
||
private bool isRoll = false;//是否旋转
|
||
public CarouselItem current;//记录子物体V值小于1的
|
||
private Vector2 startPoint;
|
||
private Vector2 addVect;
|
||
|
||
private void Start()
|
||
{
|
||
Refresh();
|
||
MoveEndAction += SelectItem;
|
||
}
|
||
|
||
private void Update()
|
||
{
|
||
if (isRoll)
|
||
{
|
||
currentV = Time.deltaTime * rollSpeed * vk;//确定转动方向
|
||
vt = vTotal + currentV;
|
||
if (vk > 0 && vt >= addV) { isRoll = false; currentV = addV - vTotal; }
|
||
if (vk < 0 && vt <= addV) { isRoll = false; currentV = addV - vTotal; }
|
||
|
||
for (int i = 0; i < itemList.Count; i++)
|
||
{
|
||
itemList[i].CalculateTrans(currentV);
|
||
if (itemList[i].v - 0.5f < 0.05f)
|
||
{
|
||
current = itemList[i];
|
||
}
|
||
}
|
||
Check(currentV);
|
||
vTotal = vt;
|
||
|
||
if (!isRoll)
|
||
{
|
||
MoveEndAction?.Invoke(current);
|
||
}
|
||
}
|
||
}
|
||
|
||
public void Refresh()
|
||
{
|
||
itemList = new List<CarouselItem>();
|
||
itemFrontList = new List<CarouselItem>();
|
||
itemBackList = new List<CarouselItem>();
|
||
int num = 0;
|
||
rect = GetComponent<RectTransform>();//父物体RectTransform
|
||
for (int i = 0; i < rect.childCount; i++)
|
||
{
|
||
Transform trans = rect.GetChild(i);//子物体Transform
|
||
if (trans.gameObject.activeSelf)
|
||
{
|
||
CarouselItem item = trans.GetComponent<CarouselItem>();//子物体CarouselItem脚本
|
||
item.v = 0;
|
||
if (item != null)
|
||
{
|
||
item.transform.GetChild(0).GetComponent<Text>().text = i.ToString();//命名
|
||
itemList.Add(item);//记录脚本添加列表
|
||
item.Init(this);//子物体初始化
|
||
//item.CalculateTrans(startValue + i * addValue);
|
||
item.CalculateTrans(startValue + num * addValue);
|
||
if (item.v - 0.5f < 0.05f)
|
||
{
|
||
//current = itemList[i];
|
||
current = itemList[num];
|
||
}
|
||
}
|
||
num++;
|
||
}
|
||
}
|
||
//if (rect.childCount < 5)
|
||
if (num < 5)
|
||
{
|
||
maxValue = startValue + 4 * addValue;
|
||
}
|
||
else
|
||
{
|
||
//maxValue = startValue + (rect.childCount - 1) * addValue;
|
||
maxValue = startValue + (num - 1) * addValue;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取每个菜单的显隐
|
||
/// </summary>
|
||
/// <param name="v"></param>
|
||
/// <returns></returns>
|
||
public float GetAlpha(float v)
|
||
{
|
||
return alphaCurve.Evaluate(v);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取每个菜单的位置
|
||
/// </summary>
|
||
/// <param name="v"></param>
|
||
/// <returns></returns>
|
||
public float GetPosition(float v)
|
||
{
|
||
return positionCurve.Evaluate(v) * width;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取每个菜单的缩放
|
||
/// </summary>
|
||
/// <param name="v"></param>
|
||
/// <returns></returns>
|
||
public float GetScale(float v)
|
||
{
|
||
return scaleCurve.Evaluate(v) * maxScale;
|
||
}
|
||
|
||
///// <summary>
|
||
///// 开始拖拽触发
|
||
///// </summary>
|
||
///// <param name="eventData"></param>
|
||
//public void OnBeginDrag(PointerEventData eventData)
|
||
//{
|
||
// startPoint = eventData.position;
|
||
// addVect = Vector2.zero;
|
||
// isRoll = false;
|
||
//}
|
||
|
||
///// <summary>
|
||
///// 拖动中触发
|
||
///// </summary>
|
||
///// <param name="eventData"></param>
|
||
//public void OnDrag(PointerEventData eventData)
|
||
//{
|
||
// addVect = eventData.position - startPoint;
|
||
// float v = eventData.delta.x * 1.0f / width;
|
||
// for (int i = 0; i < itemList.Count; i++)
|
||
// {
|
||
// itemList[i].CalculateTrans(v);
|
||
// }
|
||
// Check(v);
|
||
//}
|
||
|
||
///// <summary>
|
||
///// 停止拖动触发
|
||
///// </summary>
|
||
///// <param name="eventData"></param>
|
||
//public void OnEndDrag(PointerEventData eventData)
|
||
//{
|
||
// float k = 0, vTemp;
|
||
// for (int i = 0; i < itemList.Count; i++)
|
||
// {
|
||
// if (itemList[i].v >= minValue)
|
||
// {
|
||
// vTemp = (itemList[i].v - minValue) % addValue;
|
||
// if (addVect.x > 0)
|
||
// {
|
||
// k = addValue - vTemp;
|
||
// }
|
||
// else
|
||
// {
|
||
// k = vTemp * -1;
|
||
// }
|
||
// break;
|
||
// }
|
||
// }
|
||
// addVect = Vector2.zero;
|
||
// AnimToEnd(k);
|
||
//}
|
||
|
||
/// <summary>
|
||
/// 点击UI接口
|
||
/// </summary>
|
||
/// <param name="eventData"></param>
|
||
public void OnPointerClick(PointerEventData eventData)
|
||
{
|
||
if (addVect.sqrMagnitude <= 1)
|
||
{
|
||
CarouselItem item = eventData.pointerPressRaycast.gameObject.GetComponent<CarouselItem>();//记录子物体CarouselItem脚本
|
||
if (item != null)
|
||
{
|
||
float k = item.v;
|
||
k = 0.5f - k;
|
||
AnimToEnd(k);
|
||
}
|
||
}
|
||
}
|
||
|
||
private float addV = 0, vk = 0, currentV = 0, vTotal = 0, vt = 0;
|
||
|
||
/// <summary>
|
||
/// 大于0左,小于0右
|
||
/// </summary>
|
||
/// <param name="k"></param>
|
||
private void AnimToEnd(float k)
|
||
{
|
||
addV = k;
|
||
if (k > 0) vk = 1;
|
||
else if (k < 0) vk = -1;
|
||
else return;
|
||
vTotal = 0;
|
||
isRoll = true;
|
||
}
|
||
|
||
|
||
private void Check(float _v)
|
||
{
|
||
if (_v < 0)//向左滑动
|
||
{
|
||
for (int i = 0; i < itemList.Count; i++)
|
||
{
|
||
if (itemList[i].v < (minValue - addValue / 2))
|
||
{
|
||
itemBackList.Add(itemList[i]);
|
||
}
|
||
}
|
||
if (itemBackList.Count > 0)
|
||
{
|
||
for (int i = 0; i < itemBackList.Count; i++)
|
||
{
|
||
itemBackList[i].v = itemList[itemList.Count - 1].v + addValue;
|
||
itemList.Remove(itemBackList[i]);
|
||
itemList.Add(itemBackList[i]);
|
||
}
|
||
itemBackList.Clear();
|
||
}
|
||
}
|
||
else if (_v > 0)//向右滑动
|
||
{
|
||
for (int i = itemList.Count - 1; i > 0; i--)
|
||
{
|
||
if (itemList[i].v > maxValue)
|
||
{
|
||
itemFrontList.Add(itemList[i]);
|
||
}
|
||
}
|
||
if (itemFrontList.Count > 0)
|
||
{
|
||
for (int i = 0; i < itemFrontList.Count; i++)
|
||
{
|
||
itemFrontList[i].v = itemList[0].v - addValue;
|
||
itemList.Remove(itemFrontList[i]);
|
||
itemList.Insert(0, itemFrontList[i]);
|
||
}
|
||
itemFrontList.Clear();
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
public void SelectItem(CarouselItem item)
|
||
{
|
||
print(item.name);
|
||
}
|
||
|
||
|
||
void OnDestroy()
|
||
{
|
||
MoveEndAction -= SelectItem;
|
||
}
|
||
|
||
|
||
public void Btn_Left(Button button)
|
||
{
|
||
StartCoroutine(delayed_Left(button));
|
||
}
|
||
|
||
IEnumerator delayed_Left(Button button)
|
||
{
|
||
button.interactable = false;
|
||
AnimToEnd(+0.2f);
|
||
yield return new WaitForSeconds(0.2f);
|
||
button.interactable = true;
|
||
|
||
}
|
||
|
||
public void Btn_Right(Button button)
|
||
{
|
||
StartCoroutine(delayed_Right(button));
|
||
}
|
||
|
||
IEnumerator delayed_Right(Button button)
|
||
{
|
||
button.interactable = false;
|
||
AnimToEnd(-0.2f);
|
||
yield return new WaitForSeconds(0.2f);
|
||
button.interactable = true;
|
||
|
||
}
|
||
}
|
||
}
|