///
/// 缩放曲线模拟当前缩放值
///
private float GetScaleValue(float sliderValue, float added)
{
float scaleValue = scaleCurve.Evaluate(sliderValue + added);
return scaleValue;
}
///
/// 位置曲线模拟当前x轴位置
///
private float GetXPosValue(float sliderValue, float added)
{
float evaluateValue = positionCurve.Evaluate(sliderValue + added) * posCurveFactor;
return evaluateValue;
}
public void UpdateEnhanceScrollView(float fValue)
{
for (int i = 0; i < scrollViewItems.Count; i++)
{
EnhanceItem itemScript = scrollViewItems[i];
float xValue = GetXPosValue(fValue, dHorizontalValues[itemScript.scrollViewItemIndex]);
float scaleValue = GetScaleValue(fValue, dHorizontalValues[itemScript.scrollViewItemIndex]);
itemScript.UpdateScrollViewItems(xValue, yPositionValue, scaleValue);
}
}
void Update()
{
currentDuration += Time.deltaTime;
if (currentDuration > duration)
{
// 更新完成设置选中item的对象就可以
currentDuration = duration;
if(centerItem != null)
centerItem.SetSelectColor(true);
if(preCenterItem != null)
preCenterItem.SetSelectColor(false);
canChangeItem = true;
}
SortDepth();
float percent = currentDuration / duration;
horizontalValue = Mathf.Lerp(originHorizontalValue, horizontalTargetValue, percent);
UpdateEnhanceScrollView(horizontalValue);
}
控制层级
仅仅有正确的层级控制。才干够保证"不穿帮",上文也说过,也能够通过AnimationCurve做一个层级曲线,在当前item的时间以下该item的depth或者层级应该是多少,该demo採用的是比較粗暴的list排序方法。依照每一个item距离"屏幕的远近"事实上就是scale系数。推断哪个item在前,哪个在后面,当然也有些问题,假设距离同样,可能存在item相互打架的可能(这个能够通过控制scaleCurve进行控制)
该Demo使用的UITexture控制层级(其它的不论什么方式原理一样,仅仅是处理对象不一样,用mesh实现。那就是z轴等等)
详细实现例如以下:
public void SortDepth()
{
textureTargets.Sort(new CompareDepthMethod());
for (int i = 0; i < textureTargets.Count; i++)
textureTargets[i].depth = i;
}
///
/// 用于层级对照接口
///
public class CompareDepthMethod : IComparer
{
public int Compare(UITexture left, UITexture right)
{
if (left.transform.localScale.x > right.transform.localScale.x)
return 1;
else if (left.transform.localScale.x < right.transform.localScale.x)
return -1;
else
return 0;
}
}
实现滚动循环
说道循环滚动,由于我们使用到了AnimationCurve,先天性的动画曲线会有三种模式一种是pingpong。loop,一种是clamp,当中我们须要的是LOOP,没听错,这就是滚动循环的关键点(我们的缩放曲线。位移系数曲线从0到1的效果模拟完成,假设我们继续向前添加时间流水值,那么进入到下一个曲线的时候。全部的item都会反过来进行採样曲线值。就行巧妙的实现循环效果(缩放系数。位移系数))假设不理解的,可以自己设置一个AnimationCurve,研究下,以下截图示意:
代码部分仅仅是须要知道。假设点击了一个Item将该item移动到中心相应的时间流应该往前或者往后走多少
///
/// 获得当前要移动到中心的Item须要移动的factor间隔数
///
private int GetMoveCurveFactorCount(float targetXPos)
{
int centerIndex = scrollViewItems.Count / 2;
for (int i = 0; i < scrollViewItems.Count;i++ )
{
float factor = (0.5f - dFactor * (centerIndex - i));
float tempPosX = positionCurve.Evaluate(factor) * posCurveFactor;
if (Mathf.Abs(targetXPos - tempPosX) < 0.01f)
return Mathf.Abs(i - centerIndex);
}
return -1;
}
注意问题
制作曲线。记得保证0-1时间轴填充完成。这样在进行循环处理的时候才不会出现偏差
额,假设自己用这样的方法尝试的朋友,假设有问题,请细致查看Demo中的參数就可以......(主要就是曲线制作问题)
该Demo使用的NGUI,尽管笔者没实用过UGUI,我想不论什么一个界面Tools都能够通过该方法实现,由于共同点一样。仅仅是层级处理,缩放处理有差别而已
实现效果
改进目标
该项目还有很多须要改进的地方,以后花时间继续完好
支持Editor模式下的编辑,不用执行就可以查看效果(这个应该是最关键的功能)
支持偶数个Item进行滑动
支持Drag操作
支持和NGUI类似的DragScrollView和CenterOnChild功能
优化每一个Item的层级设置算法效率
优化更新每一个Item位置,缩放算法效率
问题:
1. 在处理曲线循环的地方,因为准确度不够。导致持续点按过后会造成卡片大小发生变化,兴许直接使用单一曲线或者通过程序控制曲线精确~
GitHub地址:兴许更新会直接在版本号库中更新
总结
全部的内容都讲述完成。假设这篇文章可以帮助到您获得对看到结束的朋友有一个简单的启示,请支持下~,文中存在错误或者描写叙述不清楚的也请指正,共同交流学习,最好的方法就是直接下载Demo。然后看下逻辑和动画曲线的设置參数
欢迎转载,请注明出处~
By NPC燕(AndyKun)