GQ_Communicate/GQ_URP/GQ/Assets/script/MenuCarousel/CarouselMenu.cs

314 lines
9.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}