using UnityEngine; using System.Collections.Generic; using UnityEngine.EventSystems; using SC.XR.Unity.Module_InputSystem; public class RollList : BaseList, IDragHandler, IPointerEnterHandler, IPointerExitHandler, IPointerUpHandler, IPointerDownHandler { private float moveTime=0.2f; public List controlPoints; // public LineRenderer lineRenderer; public bool isFixed; Vector3 v1; Vector3 v2; Vector3 v3; [HideInInspector] private int startItem = 0; [HideInInspector] private int endItem = 0; //private j private float speedTime = 0; private float dragTime = 0.2f; private float clickTime = 0.2f; private float lastClickTime; private float lastDragTime; public virtual void Update() { if (isJiasudu) { speedTime = speedTime + Time.deltaTime; if(speedTime>3) { speedTime = 0; isJiasudu = false; fixedItems(); } jiasudu = jiasudu / 1.4f; Move(jiasudu); } DrawCurve(); if(eventEnterData!=null) { RollView rv = OnCheckView(eventEnterData); if(rv==null&& chooseView!=null) { chooseView.OnPointerExit(eventEnterData); // chooseView = null; } if (chooseView != rv&& chooseView!=null) { if (rv != null) { chooseView.OnPointerExit(eventEnterData); chooseView = rv; chooseView.OnPointerEnter(eventEnterData); } }; } } public override void initList(List c) { base.initList(c); DrawCurve(); Column = 1; startItem = 0; endItem = Row * Column; } float time = 1f; void Move(float f) { if (Mathf.Abs(f) >= 1) { if (f > 0) { f = 1; } else { f = -1; } } if (Mathf.Abs(f) <= 1) { for (int i = 0; i < Views.Count; i++) { if (f > 0) { if (i + 1 < Views.Count) { // LeanTween.moveLocal(itemView[i], pos[i+1], time); // Views[i].transform.localPosition = Vector3.Lerp(Views[i].transform.localPosition, pos[i + 1], Mathf.Abs(f)); Views[i].transform.localPosition = Views[i].transform.localPosition + (pos[i + 1] - Views[i].transform.localPosition) * f; // Views[i].gameObject.SetActive(true); } else { Views[i].transform.localPosition = Views[i].transform.localPosition + (pos[i + 1] - Views[i].transform.localPosition) * f; // Views[i].gameObject.SetActive(false); } } else { if ((i - 1) >= 0) { Views[i].transform.localPosition = Views[i].transform.localPosition - (pos[i - 1] - Views[i].transform.localPosition) * f; // Views[i].gameObject.SetActive(true); } else { Views[i].transform.localPosition = Views[i].transform.localPosition - (pos[i - 1] - Views[i].transform.localPosition) * f; // Views[i].gameObject.SetActive(false); } } } } if (f > 0) { if (Vector3.Distance(Views[0].transform.localPosition, pos[1]) < (Vector3.Distance(pos[0], pos[1]) / 10)) { moveRightEnd(); } } else if (f < 0) { if (Vector3.Distance(Views[1].transform.localPosition, pos[0]) < (Vector3.Distance(pos[0], pos[1]) / 10)) { moveleftEnd(); } } // Invoke("moveEnd", time); } void getShowItem() { List showItemS = new List(); int ct=0; int vCt = 0; if (Views.Count > configs.Count) { vCt = Views.Count; } else { vCt = configs.Count; } // Debug.Log("滚动次数===》"+ rCount); for (int i = rCount; i < Views.Count+ rCount; i++) { ct = i; if (i<0) { ct = vCt - Mathf.Abs(i); } else if(i >= vCt) { ct = i - vCt; } // Debug.Log(ct); showItemS.Add(ct); } showItems(showItemS); } void moveleftEnd(bool Tween=false) { rCount++; if(Mathf.Abs(rCount)>=configs.Count) { rCount = 0; } List controlPoints2 = new List(); Views[0].transform.localPosition = pos[Views.Count - 1]; for (int i = 0; i < Views.Count; i++) { if (i == (Views.Count - 1)) { if(Tween) { LeanTween.moveLocal(Views[0].gameObject, pos[i], moveTime); } else { Views[0].transform.localPosition = pos[i]; } controlPoints2.Add(Views[0]); } else { if (Tween) { LeanTween.moveLocal(Views[i + 1].gameObject, pos[i], moveTime); } else { Views[i + 1].transform.localPosition = pos[i]; } controlPoints2.Add(Views[i + 1]); } } Views = controlPoints2; controlPoints2[Views.Count - 1].gameObject.SetActive(true); getShowItem(); // Move(); } void moveRightEnd(bool Tween = false) { rCount--; if (Mathf.Abs(rCount) >= configs.Count) { rCount = 0; } List controlPoints2 = new List(); Views[Views.Count - 1].transform.localPosition = pos[0]; for (int i = 0; i < Views.Count; i++) { if (i == 0) { if (Tween) { LeanTween.moveLocal(Views[Views.Count - 1].gameObject, pos[i], moveTime); }else { Views[Views.Count - 1].transform.localPosition = pos[i]; } controlPoints2.Add(Views[Views.Count - 1]); } else { if (Tween) { LeanTween.moveLocal(Views[i - 1].gameObject, pos[i], moveTime); } else { Views[i - 1].transform.localPosition = pos[i]; } controlPoints2.Add(Views[i - 1]); } } Views = controlPoints2; controlPoints2[0].gameObject.SetActive(true); getShowItem(); } bool isStart=false; public Dictionary pos = new Dictionary(); // List pos = new List(); void DrawCurve() { if (controlPoints.Count > 0) { v1 = controlPoints[0].transform.localPosition; v2 = controlPoints[1].transform.localPosition; v3 = controlPoints[2].transform.localPosition; pos = new Dictionary(); int count = -1; for (int i = 0; i < Row+2; i++) { float t = i / ((float)Row+2); Vector3 pixel = CalculateCubicBezierPoint(t, v1, v2, v3); pos.Add(count, pixel); if (!isStart&& Views.Count>(i-1)&&i>=1) Views[i-1].transform.localPosition = pos[count]; count++; // itemView[i].transform.localPosition = pixel; } } isStart = true; } Vector3 CalculateCubicBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2) { float u = 1 - t; float tt = t * t; float uu = u * u; Vector3 p = uu * p0; p += 2 * u * t * p1; p += tt * p2; return p; } bool isMove; private Vector3 startPos; private float oldNum=0; public virtual void OnDrag(PointerEventData eventData) { if ((Time.time - lastClickTime) < clickTime) { return; } isMove = true; SCPointEventData sCPointEventData = eventData as SCPointEventData; float num = 0; Vector3 pos3d = sCPointEventData.Position3D / this.transform.localScale.x; num = (startPos.x - pos3d.x); num = Vector3.Cross(this.transform.forward, pos3d).y- oldNum; oldNum = Vector3.Cross(this.transform.forward, pos3d).y; Vector3 a = GSXRManager.Instance.leftCamera.WorldToScreenPoint(startScreenV3); Vector3 b = GSXRManager.Instance.leftCamera.WorldToScreenPoint(sCPointEventData.Position3D); num = (a - b).x; startPos = pos3d; startScreenV3 = sCPointEventData.Position3D; if(Mathf.Abs(num)>10) { if(num>0) num = 10; else { num = -10; } } else if(Mathf.Abs(num) < 2f) { num = 0; } Move(-num / 50); jTime = jTime + Time.deltaTime; if(jTime>0.3f) { jTime = 0; jiasudu = 0; } else { jiasudu = jiasudu - num/50; } } PointerEventData eventEnterData; public virtual void OnPointerEnter(PointerEventData eventData) { eventEnterData = eventData; chooseView = OnCheckView(eventData); if(chooseView!=null) chooseView.OnPointerEnter(eventData); } public virtual void OnPointerExit(PointerEventData eventData) { eventEnterData = null; if (chooseView!=null) { chooseView.OnPointerExit(eventData); chooseView = null; } } public RollView OnCheckView(PointerEventData eventData) { if(isMove) { return null; } SCPointEventData sCPointEventData = eventData as SCPointEventData; Vector3 v3event = sCPointEventData.inputDevicePartBase.detectorBase.pointerBase.cursorBase.transform.position; RollView baseView = null; float distanceMin=10; for (int i = 0; i < Views.Count; i++) { Vector3 v3 = this.transform.InverseTransformPoint(Views[i].transform.position); v3 = new Vector3(v3.x, v3.y, 0); v3 = this.transform.TransformPoint(v3); float disView = Vector3.Distance(v3event, v3); if(distanceMin> disView) { distanceMin = disView; baseView =(RollView)Views[i]; } } return baseView; } public virtual void OnPointerUp(PointerEventData eventData) { if (jiasudu!=0) isJiasudu = true; else { fixedItems(); } if (Time.time - lastDragTime < dragTime) { if (eventData.pointerEnter) { var tmpbutton = eventData.pointerEnter.GetComponentInParent(); if (tmpbutton != null) { tmpbutton.OnPointerClick(eventData); } } } if (chooseView != null) { if ((Time.time - lastClickTime)< clickTime) { chooseView.OnClick(eventData); } chooseView.OnPointerUp(eventData); // chooseView = null; } isMove = false; } private void fixedItems() { if(isFixed&&!isJiasudu) { if (Vector3.Distance(Views[1].transform.localPosition, pos[1]) > Vector3.Distance(pos[1], pos[2])/2f) { moveleftEnd(true); } if (Vector3.Distance(Views[1].transform.localPosition, pos[1]) > Vector3.Distance(pos[0], pos[1]) / 2f) { moveRightEnd(true); } else { // Debug.Log("滚动次数===》"+ rCount); for (int i = 0; i < Views.Count; i++) { LeanTween.moveLocal(Views[i].gameObject, pos[i], 0.3f); //Views[i].transform.localPosition = pos[i]; } } } } private float jiasudu; private float jTime; private bool isJiasudu; private Vector3 startScreenV3; private RollView chooseView; public virtual void OnPointerDown(PointerEventData eventData) { SCPointEventData sCPointEventData = eventData as SCPointEventData; Vector3 pos3d = sCPointEventData.Position3D / this.transform.localScale.x; startScreenV3 = sCPointEventData.Position3D; // num = Vector3.Cross(this.transform.forward, pos3d).y; startPos = pos3d; isJiasudu = false; speedTime = 0; lastDragTime = Time.time; lastClickTime = Time.time; chooseView = OnCheckView(eventData); if(chooseView!=null) chooseView.OnPointerDown(eventData); } public override void updateConfig(List c) { base.updateConfig(c); if (this.configs.Count < c.Count) { configs = new List(); c.ForEach(i => configs.Add(i)); if(c.Count> Views.Count) { rCount = c.Count - Views.Count; } getShowItem(); } else if(rCount>(c.Count - 1)) { configs = new List(); c.ForEach(i => configs.Add(i)); if (c.Count > Views.Count) { rCount = c.Count - Views.Count; } getShowItem(); } else { configs = new List(); c.ForEach(i => configs.Add(i)); getShowItem(); } } } public class BezierUtils { /// /// 根据T值,计算贝塞尔曲线上面相对应的点 /// /// T值 /// 起始点 /// 控制点 /// 目标点 /// 根据T值计算出来的贝赛尔曲线点 private static Vector3 CalculateCubicBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2) { float u = 1 - t; float tt = t * t; float uu = u * u; Vector3 p = uu * p0; p += 2 * u * t * p1; p += tt * p2; return p; } /// /// 获取存储贝塞尔曲线点的数组 /// /// 起始点 /// 控制点 /// 目标点 /// 采样点的数量 /// 存储贝塞尔曲线点的数组 public static Vector3[] GetBeizerList(Vector3 startPoint, Vector3 controlPoint, Vector3 endPoint, int segmentNum) { Vector3[] path = new Vector3[segmentNum]; for (int i = 1; i <= segmentNum; i++) { float t = i / (float)segmentNum; Vector3 pixel = CalculateCubicBezierPoint(t, startPoint, controlPoint, endPoint); path[i - 1] = pixel; Debug.Log(path[i - 1]); } return path; } }