标签:
需求
实现技术关键点
下面一一讲述当前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都可以通过该方法实现,因为共同点一样,只是层级处理,缩放处理有区别而已
该项目还有许多需要改进的地方,以后花时间继续完善
期待1.1版本吧~
里面包含了NGUI3.6.6版本,所有工程有点大
项目工程地址:http://pan.baidu.com/s/1gdAiWZD
安装地址:http://pan.baidu.com/s/1bnfPasJ
所有的内容都讲述完毕,如果这篇文章能够帮助到您获得对看到结束的朋友有一个简单的启发,请支持下~,文中存在错误或者描述不清楚的也请指正,共同交流学习,最好的方法就是直接下载Demo,然后看下逻辑和动画曲线的设置参数
欢迎转载,请注明出处~
By 漂流燕(Andy)版权声明:本文为博主原创文章,未经博主允许不得转载。
Unity3D问题之EnhanceScollView选择角色3D循环滚动效果实现
标签:
原文地址:http://blog.csdn.net/fredomyan/article/details/46926107