using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace Toolset.UI { /// /// 轮播图菜单 /// 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 MoveEndAction;//打印名字的事件 private RectTransform rect; private List itemList = new List(); private List itemFrontList = new List(); private List itemBackList = new List(); 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() { rect = GetComponent();//父物体RectTransform for (int i = 0; i < rect.childCount; i++) { Transform trans = rect.GetChild(i);//子物体Transform CarouselItem item = trans.GetComponent();//子物体CarouselItem脚本 if (item != null) { item.transform.GetChild(0).GetComponent().text = i.ToString();//命名 itemList.Add(item);//记录脚本添加列表 item.Init(this);//子物体初始化 item.CalculateTrans(startValue + i * addValue); if (item.v - 0.5f < 0.05f) { current = itemList[i]; } } } if (rect.childCount < 5) { maxValue = startValue + 4 * addValue; } else { maxValue = startValue + (rect.childCount - 1) * addValue; } } /// /// 获取每个菜单的显隐 /// /// /// public float GetAlpha(float v) { return alphaCurve.Evaluate(v); } /// /// 获取每个菜单的位置 /// /// /// public float GetPosition(float v) { return positionCurve.Evaluate(v) * width; } /// /// 获取每个菜单的缩放 /// /// /// public float GetScale(float v) { return scaleCurve.Evaluate(v) * maxScale; } ///// ///// 开始拖拽触发 ///// ///// //public void OnBeginDrag(PointerEventData eventData) //{ // startPoint = eventData.position; // addVect = Vector2.zero; // isRoll = false; //} ///// ///// 拖动中触发 ///// ///// //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); //} ///// ///// 停止拖动触发 ///// ///// //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); //} /// /// 点击UI接口 /// /// public void OnPointerClick(PointerEventData eventData) { if (addVect.sqrMagnitude <= 1) { CarouselItem item = eventData.pointerPressRaycast.gameObject.GetComponent();//记录子物体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; /// /// 大于0左,小于0右 /// /// 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; } } }