using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; /// /// /// public class UI_Control_ScrollFlow : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler { /// /// /// public RectTransform Rect; /// /// /// public List ItemList = new List(); /// /// 卡牌的像素宽度 /// public float itemWidth = 500; /// /// 最大缩放 /// public float MaxScale = 1.0f; /// /// 开始坐标值 /// private float startValue = 0.5f; /// /// /// private int defaultItemIndex = 0; /// /// 卡牌之间的间隔坐标 /// private float spaceValue = 0.2f; /// /// 移动速度曲线 /// public AnimationCurve SpeedCurve; /// /// 坐标曲线 /// public AnimationCurve PositionCurve; /// /// 缩放幅度大小曲线 /// public AnimationCurve ScaleCurve; /// /// 拖拽时候的,托主幅度量 /// private float dragV = 0; /// /// 拖拽时候的,计算值 /// private Vector2 start_point, add_vect; /// /// 移动结束事件 /// public event CallBack MoveEnd; /// /// 更改当前卡牌的状态 /// public event CallBack EventRefreshCardState; /// /// 是否开启动画 /// public bool _anim = false; /// /// 移动的量 /// private float AddV = 0; /// /// 移动方向 /// private float Vk = 0; /// /// /// private float Vtotal = 0; /// /// 动画速度 * 单位时间* 移动方向,计算出来的移动值 /// private float CurrentV = 0; /// /// /// private float VT = 0; /// /// /// private float _v1 = 0, _v2 = 0; /// /// 动画速度 /// public float _anim_speed = 1f; /// /// /// public UI_Control_ScrollFlow_Item Current; /// /// 初始化组件 /// public void InitComponments() { Rect = this.transform.GetComponent(); MaxScale = 1.0f; itemWidth = 500; //PositionCurve = AnimationCurve.EaseInOut(0, 0, 1.0f, 1.0f); float[] tixxx = new float[] {-0.22f, -0.02f, 0.18f, 0.5f, 0.82f, 1.02f, 1.22f, 1.42f, 1.62f, 1.82f, 2.02f, 2.22f, 2.42f, 2.62f, 2.82f, 3.02f, 3.22f, 3.42f, 3.62f, 3.82f, 4.02f, 4.22f, 4.42f, 4.62f, 4.82f }; Keyframe[] ks = new Keyframe[3]; ks[0] = new Keyframe(0, 0.95f); ks[1] = new Keyframe(0.5f, 1.0f); ks[2] = new Keyframe(1.0f, 0.95f); ScaleCurve = new AnimationCurve(ks); Keyframe[] spks = new Keyframe[5]; spks[0] = new Keyframe(-1.0f, 2.0f); spks[1] = new Keyframe(-0.5f, 1.5f); spks[2] = new Keyframe(0, 0.5f); spks[3] = new Keyframe(0.5f, 1.5f); spks[4] = new Keyframe(1.0f, 2.0f); SpeedCurve = new AnimationCurve(spks); Keyframe[] posArr = new Keyframe[tixxx.Length]; int index = 0; for (int i = -3; i <= 21; i++) { posArr[index] = new Keyframe(startValue + i * spaceValue, tixxx[index]); index++; } PositionCurve = new AnimationCurve(posArr); } /// /// 接手到通知,某个子对象的选中状态发生改变了 /// public void OnReceiveUpdateState(bool isSelected, UI_Control_ScrollFlow_Item item) { if (EventRefreshCardState != null) { EventRefreshCardState(isSelected, item); } } /// /// /// public void Refresh(bool resetPosition = false) { if (Rect.childCount > 0) { int count = 0; for (int i = 0; i < Rect.childCount; i++) { Transform tran = Rect.GetChild(i); if (ItemsOld.Contains(tran)) { continue; } if (!tran.gameObject.activeSelf) { continue; } count++; } //// Debug.LogError("countcountcount:::" + count); if (count > 5) { defaultItemIndex = 5; } else { defaultItemIndex = count - 1; } } //// Debug.LogError("defaultItemIndex::::" + defaultItemIndex); int rIndex = 0; for (int i = 0; i < Rect.childCount; i++) { Transform tran = Rect.GetChild(i); if (ItemsOld.Contains(tran)) { continue; } if (!tran.gameObject.activeSelf) { continue; } UI_Control_ScrollFlow_Item item = tran.GetComponent(); if (item != null) { item.Init(this, ItemList.Count); ItemList.Add(item); //item.Drag(startValue - (ItemList.Count - 1) * spaceValue); float dv = startValue + (rIndex - defaultItemIndex) * spaceValue; item.Drag(dv); //// Debug.LogError("CurrentItem::::" + dv); if (Mathf.Abs(dv - startValue) < 0.05f) { Current = item; //// Debug.LogError("CurrentItem::::" + item.gameObject.name); } rIndex++; } } //if (MoveEnd != null) //{ // MoveEnd(Current); //} for (int i = 0; i < ItemList.Count; i++) { ItemList[i].Refresh(); } ItemsOld.Clear(); } /// /// /// public List ItemsOld; /// /// /// public void Clear() { ItemsOld = new List(); for (int i = 0; i < ItemList.Count; i++) { ItemsOld.Add(ItemList[i].transform); Destroy(ItemList[i].gameObject); } ItemList.Clear(); } /// /// /// /// public void OnBeginDrag(PointerEventData eventData) { start_point = eventData.position; add_vect = Vector3.zero; _anim = false; } /// /// /// /// public void OnDrag(PointerEventData eventData) { //判断此时 是不是已经到列表尽头,然后做一个极限设定 if (ItemList[0].v > startValue) { float abs = Mathf.Abs(startValue - ItemList[0].v); if (abs > spaceValue) { return; } } if (ItemList[ItemList.Count - 1].v < startValue) { float abs = Mathf.Abs(startValue - ItemList[ItemList.Count - 1].v); if (abs > spaceValue) { return; } } add_vect = eventData.position - start_point; dragV = eventData.delta.x * 1.00f / itemWidth; //计算移动量,对应卡牌的比例 for (int i = 0; i < ItemList.Count; i++) { ItemList[i].Drag(dragV); } } /// /// 这块需要调整 /// 要不然不知道拖拽到哪个了...................... /// /// public void OnEndDrag(PointerEventData eventData) { float k = 0, v1; for (int i = 0; i < ItemList.Count; i++) { if (ItemList[i].v >= startValue) { v1 = (ItemList[i].v - startValue) % spaceValue; if (add_vect.x >= 0) { k = spaceValue - v1; //确定向右移动 () } else { k = v1 * -1; } break; } } add_vect = Vector3.zero; // 判断是否拖拽到极限 if (ItemList[0].v > startValue) { //说明向右滑道头了 k = ItemList[0].v; k = startValue - k; AnimToEnd(k); return; } if (ItemList[ItemList.Count - 1].v < startValue) { k = ItemList[ItemList.Count - 1].v; k = startValue - k; AnimToEnd(k); return; } AnimToEnd(k); } /// /// /// /// /// public float GetPosition(float v, int _index) { //return v * itemWidth; return PositionCurve.Evaluate(v) * itemWidth; } /// /// 获取卡牌移动速度 /// /// /// public float GetMoveSpeed(float v) { //return v * itemWidth; return SpeedCurve.Evaluate(v) * 1.0f; } /// /// /// /// /// public float GetScale(float v) { return ScaleCurve.Evaluate(v) * MaxScale; } /// /// 主要进行排序 /// 除了中间之外的, 左侧的,从左到右绘制. /// 中间右侧,从右到左绘制 /// public void LateUpdate() { List left = new List(); List right = new List(); List middle = new List(); int index = 0; for (int i = 0; i < ItemList.Count; i++) { float abs = Mathf.Abs(startValue - ItemList[i].v); if (abs < 0.05f) { middle.Add(ItemList[i]); } else { if (ItemList[i].v > startValue) { right.Add(ItemList[i]); } else { left.Add(ItemList[i]); } } } for (int i = 0; i < left.Count; i++) { left[i].rect.SetSiblingIndex(index); index++; } for (int i = right.Count - 1; i >= 0; i--) { right[i].rect.SetSiblingIndex(index); index++; } for (int i = 0; i < middle.Count; i++) { middle[i].rect.SetSiblingIndex(index); index++; } } /// /// 移动结束 /// /// 移动距离 public void AnimToEnd(float k) { AddV = k; if (AddV > 0) { Vk = 1; } else if (AddV < 0) { Vk = -1; } else { return; } Vtotal = 0; _anim_speed = GetMoveSpeed(k); _anim = true; } /// /// /// private void Update() { if (_anim) { //// Debug.LogError("flow:::" + Time.deltaTime + " VKKK:" + Vk); CurrentV = Time.deltaTime * _anim_speed * Vk; ////通过update 来累加 CurrentV; ////直到移动量,达到要求的结束动画. ////主要对点击某个卡牌,移动直到显示某个具体位置卡牌有效. VT = Vtotal + CurrentV; if (Vk > 0 && VT >= AddV) { _anim = false; CurrentV = AddV - Vtotal; } if (Vk < 0 && VT <= AddV) { _anim = false; CurrentV = AddV - Vtotal; } ////============================================= for (int i = 0; i < ItemList.Count; i++) { ItemList[i].Drag(CurrentV); if (ItemList[i].v - startValue < 0.05f) { Current = ItemList[i]; } } Vtotal = VT; if (!_anim) { //// Debug.LogError("end ened"); if (MoveEnd != null) { MoveEnd(Current); } } } } /// /// 转到指定子对象显示 /// /// public void ToAppointedItem(UI_Control_ScrollFlow_Item script) { if (script == null) return; float k = script.v; k = startValue - k; AnimToEnd(k); } }