using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using System.Collections;
///
///
///
public class UI_ScrollFlow : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
///
/// 元素初始化
///
/// 游戏对象
/// 数据索引
public delegate void OnInitializeItem(GameObject go, int dataIndex);
///
/// 元素初始化
///
public OnInitializeItem onInitializeItem;
///
/// 卡牌的像素宽度
///
public float itemWidth = 700;
///
/// 最大缩放
///
public float MaxScale = 1.0f;
///
/// 开始坐标值
///
public 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_ScrollFlow_Item Current;
///
/// 初始化
///
/// 数据的数量
public void Init(int dataCount)
{
// 不显示元素预制物体
goItemPrefab.SetActive(false);
// 如果数据数量为 0 ,没有初始化的必要
if (dataCount <= 0)
{
return;
}
mDataCount = dataCount;
unUseItem.Clear();
useItemList.Clear();
Debug.LogError("Init!!!!!" + useItemList.Count);
setUpdateRectItem(0, true);
}
///
/// 初始化 英雄滑动列表的组件设置
///
public void InitHeroComponmentsSetting()
{
MaxScale = 1.0f;
itemWidth = 500;
float[] tixxx = new float[] { -0.95f, -0.59f, -0.23f, 0.13f, 0.5f, 0.87f, 1.23f, 1.59f, 1.95f };
Keyframe[] ks = new Keyframe[3];
ks[0] = new Keyframe(0, 0.9f);
ks[1] = new Keyframe(0.5f, 1.0f);
ks[2] = new Keyframe(1.0f, 0.9f);
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 = -4; i <= 4; i++)
{
posArr[index] = new Keyframe(startValue + i * spaceValue, tixxx[index]);
index++;
}
PositionCurve = new AnimationCurve(posArr);
}
///
/// 初始化 图鉴滑动列表的组件设置
///
public void InitBook_ComponmentsSetting()
{
MaxScale = 1.0f;
itemWidth = 200;
Keyframe[] spks = new Keyframe[5];
spks[0] = new Keyframe(-1.0f, 1.5f);
spks[1] = new Keyframe(-0.5f, 1);
spks[2] = new Keyframe(0, 0.5f);
spks[3] = new Keyframe(0.5f, 1);
spks[4] = new Keyframe(1.0f, 1.5f);
SpeedCurve = new AnimationCurve(spks);
Keyframe[] ks = new Keyframe[2];
ks[0] = new Keyframe(-1.0f, 1.0f);
ks[1] = new Keyframe(1.0f, 1.0f);
ScaleCurve = new AnimationCurve(ks);
float[] tixxx = new float[] { -3.0f, -2.0f, -1.0f, 0, 1.0f, 2.0f, 3.0f };
Keyframe[] posArr = new Keyframe[tixxx.Length];
int index = 0;
for (int i = -3; i <= 3; i++)
{
posArr[index] = new Keyframe(startValue + i * spaceValue, tixxx[index]);
index++;
}
PositionCurve = new AnimationCurve(posArr);
}
///
///
///
public void InitPvp_ComponmentsSetting()
{
MaxScale = 1.0f;
itemWidth = 800;
Keyframe[] spks = new Keyframe[5];
spks[0] = new Keyframe(-1.0f, 1.5f);
spks[1] = new Keyframe(-0.5f, 1);
spks[2] = new Keyframe(0, 0.5f);
spks[3] = new Keyframe(0.5f, 1);
spks[4] = new Keyframe(1.0f, 1.5f);
SpeedCurve = new AnimationCurve(spks);
Keyframe[] ks = new Keyframe[3];
ks[0] = new Keyframe(0, 0.9f);
ks[1] = new Keyframe(0.5f, 1.0f);
ks[2] = new Keyframe(1.0f, 0.9f);
ScaleCurve = new AnimationCurve(ks);
float[] tixxx = new float[] { -3.0f, -2.0f, -1.0f, 0, 1.0f, 2.0f, 3.0f };
Keyframe[] posArr = new Keyframe[tixxx.Length];
int index = 0;
for (int i = -3; i <= 3; i++)
{
posArr[index] = new Keyframe(startValue + i * spaceValue, tixxx[index]);
index++;
}
PositionCurve = new AnimationCurve(posArr);
}
///
/// 当前处于选中的对象数据索引
///
public int CurSelectElementIndex = -1;
///
/// 接手到通知,某个子对象的选中状态发生改变了
///
public void OnReceiveUpdateState(bool isSelected, UI_ScrollFlow_Item item)
{
if (isSelected)
{
if (CurSelectElementIndex != item.Index)
{
CurSelectElementIndex = item.Index;
RefreshDraw();
}
}
if (EventRefreshCardState != null)
{
EventRefreshCardState(isSelected, item);
}
}
///
/// 当前元素总值
///
public int mDataCount;
///
/// 上次定位的位置
///
private int _lastCurIndex;
///
///
///
private int lastCurIndex
{
get { return _lastCurIndex; }
set
{
if (_lastCurIndex != value)
{
_lastCurIndex = value;
}
}
}
///
///
///
private int curIndex = 0;
///
/// 英雄列表滑动的数据发生变化
///
public void Hero_DataChanged(int dataCount, bool bResetPos)
{
CurSelectElementIndex = -1;
Current = null;
mDataCount = dataCount;
if (bResetPos)
{
//if (mDataCount > 5)
//{
// defaultItemIndex = 5;
//}
//else
//{
// defaultItemIndex = mDataCount - 1;
//}
//lastCurIndex = defaultItemIndex;
}
//// Debug.LogError("bResetPos:::" + bResetPos + " lastCurIndex:: " + lastCurIndex);
/*
* 如果需要重新定位的话
* 重新计算每个数据在时间轴的位置
*/
// 因为数据改变了,元素要重新获取数据
for (int i = useItemList.Count - 1; i >= 0; i--)
{
UI_ScrollFlow_Item item = useItemList[i];
item.Index = -1;
useItemList.Remove(item);
unUseItem.Enqueue(item);
}
//// Debug.LogError("DataChanged!!!!!" + useItemList.Count);
setUpdateRectItem(lastCurIndex, true);
//////if (bResetPos)
//////{
////// if (useItemList.Count > 0)
////// {
////// UI_ScrollFlow_Item script = useItemList[0];
////// if (script == null)
////// {
////// return;
////// }
////// if (Current != script)
////// {
////// //// Debug.LogError("Current 0.5fIndex:::" + Current.Index + " script:: " + script.Index);
////// ToAppointedItem(script);
////// }
////// }
//////}
//////else
//////{
////// UI_ScrollFlow_Item script = null;
////// //// Debug.LogError(" lastCurIndex:: " + lastCurIndex + " useItemList count::: " + useItemList.Count);
////// if (useItemList.Count > 0)
////// {
////// if (lastCurIndex >= useItemList.Count)
////// {
////// script = useItemList[useItemList.Count - 1];
////// }
////// else
////// {
////// script = useItemList[lastCurIndex];
////// }
////// }
////// if (script != null)
////// {
////// //// Debug.LogError("0.5fIndex:::script:: " + script.Index);
////// ToAppointedItem(script);
////// }
//////}
if (Current != null)
{
ToAppointedItem(Current);
}
RefreshDraw();
}
///
/// 图鉴的数据发生变化
///
public void Book_DataChanged(int dataCount)
{
Current = null;
mDataCount = dataCount;
lastCurIndex = 2;
/*
* 如果需要重新定位的话
* 重新计算每个数据在时间轴的位置
*/
// 因为数据改变了,元素要重新获取数据
for (int i = useItemList.Count - 1; i >= 0; i--)
{
UI_ScrollFlow_Item item = useItemList[i];
item.Index = -1;
useItemList.Remove(item);
unUseItem.Enqueue(item);
}
setUpdateRectItem(lastCurIndex, true);
UI_ScrollFlow_Item script = null;
if (useItemList.Count > 0)
{
if (lastCurIndex >= useItemList.Count)
{
script = useItemList[useItemList.Count - 1];
}
else
{
script = useItemList[lastCurIndex];
}
}
if (script != null)
{
ToAppointedItem(script);
}
}
#region
///
/// 刷新元素
///
/// 当前所处的行数
private void setUpdateRectItem(int scrollPerLineIndex, bool isNeedFindCurrent = false)
{
if (scrollPerLineIndex < 0)
{
return;
}
int startDataIndex = 0;
int endDataIndex = mDataCount;
// 移除
for (int i = useItemList.Count - 1; i >= 0; i--)
{
UI_ScrollFlow_Item item = useItemList[i];
int index = item.Index;
if (index < startDataIndex || index >= endDataIndex)
{
item.Index = -1;
useItemList.Remove(item);
unUseItem.Enqueue(item);
}
}
// 显示
for (int dataIndex = startDataIndex; dataIndex < endDataIndex; dataIndex++)
{
if (dataIndex < 0)
{
continue;
}
if (dataIndex >= mDataCount)
{
continue;
}
if (isExistDataByDataIndex(dataIndex))
{
//需要重置下坐标位置
continue;
}
////StartCoroutine(createItem(dataIndex, isNeedFindCurrent));
createItem(dataIndex, isNeedFindCurrent);
}
}
private int tempStartIndex = 0;
private int tempEndIndex = 0;
///
/// content 对象
///
public RectTransform nodeContent = null;
///
/// 元素预制物体
///
public GameObject goItemPrefab = null;
///
/// 创建元素
///
/// 数据索引
private void createItem(int dataIndex, bool isNeedFindCurrent)
{
UI_ScrollFlow_Item item = null;
if (unUseItem.Count > 0)
{
item = unUseItem.Dequeue();
}
else
{
GameObject temp = addChild(goItemPrefab, nodeContent);
item = temp.GetComponent();
if (item == null)
{
AssemblyHelper.Instance.BindScript("UI_ScrollFlow_Item", temp);
item = temp.GetComponent();
}
}
item.gameObject.name = dataIndex.ToString();
item.gameObject.SetActive(true);
item.ScrollFlowParent = this;
item.Index = dataIndex;
useItemList.Add(item);
float dv = startValue + (dataIndex - lastCurIndex) * spaceValue;
//// Debug.LogError("dv !!!!!" + dv);
item.Drag(dv);
if (isNeedFindCurrent)
{
if (Mathf.Abs(dv - startValue) < 0.05f)
{
Current = item;
}
}
////yield return null;
}
///
/// 当前数据是否存在 List 中
///
/// 数据索引
/// 是否已存在
private bool isExistDataByDataIndex(int dataIndex, bool isNeedFindCurrent = false)
{
if (useItemList == null || useItemList.Count <= 0)
{
return false;
}
for (int i = 0; i < useItemList.Count; i++)
{
if (useItemList[i].Index == dataIndex)
{
return true;
}
}
return false;
}
///
/// 实例化预设对象 、添加实例化对象到指定的子对象下
///
/// 元素预制物体
/// 父节点
/// 新创建的元素对象
private GameObject addChild(GameObject goPrefab, Transform parent)
{
if (goPrefab == null || parent == null)
{
Debug.LogError("异常。UIWarpContent.cs addChild(goPrefab = null || parent = null)");
return null;
}
GameObject goChild = GameObject.Instantiate(goPrefab) as GameObject;
goChild.transform.SetParent(parent, false);
goChild.SetActive(true);
return goChild;
}
///
/// 正在使用中的元素
///
private List useItemList = new List();
///
/// 未在使用中的元素
///
private Queue unUseItem = new Queue();
///
/// 销毁
///
private void OnDestroy()
{
nodeContent = null;
goItemPrefab = null;
onInitializeItem = null;
useItemList.Clear();
unUseItem.Clear();
useItemList = null;
unUseItem = null;
}
#endregion
///
///
///
///
public void OnBeginDrag(PointerEventData eventData)
{
start_point = eventData.position;
add_vect = Vector3.zero;
_anim = false;
}
///
///
///
///
public void OnDrag(PointerEventData eventData)
{
//判断此时 是不是已经到列表尽头,然后做一个极限设定
if (useItemList[0].v > startValue)
{
float abs = Mathf.Abs(startValue - useItemList[0].v);
if (abs > spaceValue)
{
return;
}
}
if (useItemList[useItemList.Count - 1].v < startValue)
{
float abs = Mathf.Abs(startValue - useItemList[useItemList.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 < useItemList.Count; i++)
{
useItemList[i].Drag(dragV);
}
}
///
/// 这块需要调整
/// 要不然不知道拖拽到哪个了......................
///
///
public void OnEndDrag(PointerEventData eventData)
{
float k = 0, v1;
for (int i = 0; i < useItemList.Count; i++)
{
if (useItemList[i].v >= startValue)
{
v1 = (useItemList[i].v - startValue) % spaceValue;
if (add_vect.x >= 0)
{
k = spaceValue - v1;
//确定向右移动 ()
}
else
{
k = v1 * -1;
}
break;
}
}
add_vect = Vector3.zero;
// 判断是否拖拽到极限
if (useItemList[0].v > startValue)
{
//说明向右滑道头了
k = useItemList[0].v;
k = startValue - k;
AnimToEnd(k);
return;
}
if (useItemList[useItemList.Count - 1].v < startValue)
{
k = useItemList[useItemList.Count - 1].v;
k = startValue - k;
AnimToEnd(k);
return;
}
AnimToEnd(k);
}
///
///
///
///
///
public float GetPositionX(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()
{
if (!IsOPenReDraw)
{
return;
}
List left = new List();
List right = new List();
List middle = new List();
int index = 0;
// Debug.LogError("LateUpdate:::" + useItemList.Count);
for (int i = 0; i < useItemList.Count; i++)
{
float abs = Mathf.Abs(startValue - useItemList[i].v);
if (abs < 0.05f)
{
middle.Add(useItemList[i]);
}
else
{
if (useItemList[i].v > startValue)
{
right.Add(useItemList[i]);
}
else
{
left.Add(useItemList[i]);
}
}
}
////按照 顺序重新绘制 左侧 索引 右侧绘制从大到小
left.Sort(sortByIndex);
right.Sort(sortByIndex);
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++;
}
IsOPenReDraw = false;
}
private bool IsOPenReDraw = false;
///
///
///
public void RefreshDraw()
{
// 停止创建元素
////StopCoroutine("ReDraw");
////StartCoroutine("ReDraw");
IsOPenReDraw = true;
}
////private IEnumerator ReDraw()
////{
//// Dictionary xx = new Dictionary();
//// foreach (UI_ScrollFlow_Item ele in useItemList)
//// {
//// xx.Add(ele.ResetSiblingIndex(), ele);
//// }
//// List temp = new List();
//// temp.AddRange(xx.Keys);
//// temp.Sort();
//// temp.Reverse();
//// foreach (int key in temp)
//// {
//// xx[key].rect.SetAsLastSibling();
//// }
//// yield return null;
////}
private int sortByIndex(UI_ScrollFlow_Item item1, UI_ScrollFlow_Item item2)
{
int result = 0;
if (item1.Index > item2.Index)
{
result = 1;
}
else if (item1.Index < item2.Index)
{
result = -1;
}
return result;
}
///
/// 移动结束
///
/// 移动距离
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)
{
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 < useItemList.Count; i++)
{
useItemList[i].Drag(CurrentV);
if (useItemList[i].v - startValue < 0.05f)
{
Current = useItemList[i];
}
}
Vtotal = VT;
if (!_anim)
{
lastCurIndex = Current.Index;
//setUpdateRectItem(lastCurIndex);
if (MoveEnd != null)
{
MoveEnd(Current);
}
}
}
}
///
/// 转到指定子对象显示
///
///
public void ToAppointedItem(UI_ScrollFlow_Item script)
{
if (script == null)
return;
float k = script.v;
k = startValue - k;
AnimToEnd(k);
}
}