需求
实现技术关键点
(3D循环效果,依据数学函数和细致研究下详细效果非常easy通过计算方式直接实现,本文主要目的是介绍下AnimationCurve工具,通过这个工具可以帮助我们实现一些需求当然也包含实现酷炫的3D滚动效果)
以下一一讲述当前Demo採用的方法
说到实现的核心,须要知道Unity3D中提供的一个叫做AnimationCurve的组件。这个不不过表面上美术能够使用的组件,也不不过单纯的动画曲线的概念,当然它就是动画曲线,可是我们能够赋予AnimationCurve不同的意义。则能够借助Curve实现不同的功能,(AnimationCurve定义了一个变化趋势或者曲线,在不同的时间点,我们能够得到当前时间点下该曲线相应的y轴信息。这个信息能够是角色跳跃的高度。模型缩放的一个系数,摄像机距离目标的长度。一个角色当前的心情数值等等。曲线能够表示非常多的意义)
没用过AnimationCurve的朋友,直接去官网看下介绍就明确怎样使用
以下简单说下使用AnimationCurve能够完毕的一些功能(上面已经介绍了一部分场景)
我们也赋予AnimationCurve不同的意义,实现我们核心目标(控制位移。控制缩放 当然也能够控制层级)
/// <summary> /// 缩放曲线模拟当前缩放值 /// </summary> private float GetScaleValue(float sliderValue, float added) { float scaleValue = scaleCurve.Evaluate(sliderValue + added); return scaleValue; } /// <summary> /// 位置曲线模拟当前x轴位置 /// </summary> 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; } /// <summary> /// 用于层级对照接口 /// </summary> public class CompareDepthMethod : IComparer<UITexture> { 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移动到中心相应的时间流应该往前或者往后走多少
/// <summary> /// 获得当前要移动到中心的Item须要移动的factor间隔数 /// </summary> 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; }
该Demo使用的NGUI,尽管笔者没实用过UGUI,我想不论什么一个界面Tools都能够通过该方法实现,由于共同点一样。仅仅是层级处理,缩放处理有差别而已
该项目还有很多须要改进的地方,以后花时间继续完好
GitHub地址:兴许更新会直接在版本号库中更新
https://github.com/tinyantstudio/EnhancedScrollView
APK測试安装地址:http://pan.baidu.com/s/1bnfPasJ
全部的内容都讲述完成。假设这篇文章可以帮助到您获得对看到结束的朋友有一个简单的启示,请支持下~,文中存在错误或者描写叙述不清楚的也请指正,共同交流学习,最好的方法就是直接下载Demo。然后看下逻辑和动画曲线的设置參数
欢迎转载,请注明出处~
By NPC燕(AndyKun)
Unity3D问题之EnhanceScollView选择角色3D循环滚动效果实现
原文:http://www.cnblogs.com/mengfanrong/p/5314002.html