Unity3D问题之EnhanceScollView选择角色3D循环滚动效果实现

需求

  • 呈现3D效果(2D素材)选择角色效果
  • 滚动保证层级,缩放比例,间距正常跟随
  • 循环滚动
  • 这个界面需求一般也会有游戏会采用(貌似有挺多)

如何实现

实现技术关键点

  1. 如何控制每个Item之间的间隔(位置),缩放比例,差值平滑
  2. 如何实现item层级关系正确显示("离" 屏幕近的层级高)
  3. 如何实现循环滚动

下面一一讲述当前Demo采用的方法

说到实现的核心,需要知道Unity3D中提供的一个叫做AnimationCurve的组件,这个不仅仅是表面上美术可以使用的组件,也不只是单纯的动画曲线的概念,当然它就是动画曲线,但是我们可以赋予AnimationCurve不同的意义,则可以借助Curve实现不同的功能,(AnimationCurve定义了一个变化趋势或者曲线,在不同的时间点,我们可以得到当前时间点下该曲线对应的y轴信息,这个信息可以是角色跳跃的高度,模型缩放的一个系数,摄像机距离目标的长度,一个角色当前的心情数值等等,曲线可以表示很多的意义)

没用过AnimationCurve的朋友,直接去官网看下介绍就明白如何使用

下面简单说下使用AnimationCurve可以完成的一些功能(上面已经介绍了一部分场景)

  1. 角色2D跳跃
  2. 摄像机移动
  3. 角色心情指数
  4. 缩放系数
  5. 距离系数
  6. ......

我们也赋予AnimationCurve不同的意义,实现我们核心目标(控制位移,控制缩放 当然也可以控制层级)

控制位移,缩放(3D效果的关键),差值过度动画平滑

  1. 创建两个AnimationCurve一个是scaleAnimationCurve和positionXAnimationCurve,分别控制缩放和位移
  2. 时间流水线控制(我们把所有的Item设置好自己对应的时间流位置即可,每次只要一动时间流水线,然后从两个曲线内获得当前流水线对应的缩放系数,位移系数,然后设置item的位移和缩放即可)
  3. 如何制作动画(这个其实就是简单的时间流水线的差值处理,一定时间时间流水值达到目标值即可)

下面放上两张曲线截图和具体实现:

/// <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;
    }

注意问题

  1. 制作曲线,记得保证0-1时间轴填充完毕,这样在进行循环处理的时候才不会出现偏差
  2. 额,如果自己用这种方法尝试的朋友,如果有问题,请仔细查看Demo中的参数即可......(主要就是曲线制作问题)

该Demo使用的NGUI,虽然笔者没有用过UGUI,我想任何一个界面Tools都可以通过该方法实现,因为共同点一样,只是层级处理,缩放处理有区别而已

实现效果

改进目标

该项目还有许多需要改进的地方,以后花时间继续完善

  • 支持Editor模式下的编辑,不用运行即可查看效果(这个应该是最关键的功能)
  • 支持偶数个Item进行滑动
  • 支持Drag操作
  • 支持和NGUI类似的DragScrollView和CenterOnChild功能
  • 优化每个Item的层级设置算法效率
  • 优化更新每个Item位置,缩放算法效率

期待1.1版本吧~

Demo地址

里面包含了NGUI3.6.6版本,所有工程有点大

项目工程地址:http://pan.baidu.com/s/1gdAiWZD

安装地址:http://pan.baidu.com/s/1bnfPasJ

总结

所有的内容都讲述完毕,如果这篇文章能够帮助到您获得对看到结束的朋友有一个简单的启发,请支持下~,文中存在错误或者描述不清楚的也请指正,共同交流学习,最好的方法就是直接下载Demo,然后看下逻辑和动画曲线的设置参数

欢迎转载,请注明出处~

By 漂流燕(Andy)

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-06 01:11:00

Unity3D问题之EnhanceScollView选择角色3D循环滚动效果实现的相关文章

JS实用的带停顿的逐行文本循环滚动效果

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>JS实用的带停顿的逐行文本循环滚动效果丨k

unity 背景无限循环滚动效果

背景无限循环滚动效果如下示: 步骤如下: 导入背景图片后,设置图片的格式,如下图: 2.图片格式也可以设置是Texture格式,但是Wrap Mode 一定要是Repeat[重复发生]:然后记得Apply一下.[解释:Wrap mode :循环模式:换行模式:包裹模式:缠绕] 3.在Hierachy视图中,新建2D Object-〉Sprite 或者一个Image,将之前设置好的精灵放入Texture. 4.在Project视图鼠标右键新建一个Shader,命名随意,然后在编辑器中修改Shade

图片循环滚动效果shader

背景无限循环滚动效果,有X和Y轴的速度控制,方便控制.见下图,操作步骤同之前的背景循环设置. shader如下: Shader "Custom/Scroll" { Properties{ _MainTint("Diffuse Tint" , Color) = (1,1,1,1) _MainTex("Base (RGB)", 2D) = "white" {} //x轴滚动速度 _ScrollXSpeed("X Scro

使用jQuery实现向上循环滚动效果(超简单)

代码如下 <body> <ul style="border: 1px solid blue;height: 60px;width:300px;overflow: hidden;"> <li>aaaaaaaaaaaaaaaaaaaaa</li> <li>bbbbbbbbbbbbbbbbbbbbb</li> <li>ccccccccccccccccccccc</li> <li>ddd

循环滚动图片

1.概述 循环滚动图片,不仅可以增添Web页面的动态效果,而且可以节省页面空间,有效地保证在有限的页面中显示更多的图片. 2.技术要点 主要应用setTimeout()方法实现图片的循环滚动效果.setTimeout()方法的语法格式如下: setTimeout(function,milliseconds,[arguments]) 参数说明: a. function:要调用的JavaScript自定义函数名称. b. Milliseconds:设置超时时间(以毫秒为单位). 功能:经过超时时间后

黑马程序员— C语言选择结构和循环结构的总结

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 在学习完C语言的流程控制后,发现选择结构跟循环结构都各自有各自的特点,下面就来对选择结构与循环结构进行一个综合的总结 第一讲  选择结构与循环结构 选择结构主要包括if语句和switch语句,而循环结构包括for循环,while循环以及do while循环: 一 选择结构 1.if(条件){ }else if(条件2){ }else{ } 特点:同一时刻只有一个大括号里面的代码会执行. 2.s

Java基本知识(运算符/选择结构语句/循环结构语句/方法/标识符)

Java基本知识(运算符/选择结构语句/循环结构语句/方法/标识符)一.Java标识符给类.接口.方法等命名的字符序列.1.标识符组成(1)英文字母大小写:(2)数字(不能以数字开头):(3)$和_.2.命名规则常量:每个单次字母均大写,若由多个单词组成,则每个单词间用下划线隔开.变量.方法:第一个单词全部小写,若由多个单词组成,则第一个单词全部小写,从第二个单词开始,每个单词首字母大写其他单词首字母小写.包:所有字母都小写,多级包采用域名反写,每级用"."隔开.类.接口:每个单词首字

Cocos2d-x3.0游戏实例之《别救我》第三篇——循环滚动背景

好,这篇我们来讲解无限循环滚动背景,这个知识已经被讲到烂了,我以前的文章也介绍过,所以就不那么详细地说明了. 笨木头花心贡献,啥?花心?不呢,是用心~ 转载请注明,原文地址:http://www.benmutou.com/blog/archives/823 文章来源:笨木头与游戏开发 为什么是循环滚动背景? 用循环滚动背景,其实是因为我想偷懒,因为这样我只需要准备一张图片就可以了. 我们最终要创建这样的背景,如图: 背景是在滚动的,大家有没有看到?(小若:看你妹,这是jpg,不是gif) 大家是

基于 HTML5 Canvas 的 3D 热力云图效果

前言 数据蕴藏价值,但数据的价值需要用 IT 技术去发现.探索,可视化可以帮助人更好的去分析数据,信息的质量很大程度上依赖于其呈现方式.在数据分析上,热力图无疑是一种很好的方式.在很多行业中都有着广泛的应用. 最近刚好项目中需要用到 3D 热力图的效果展示.网上搜了相关资料,发现大多数是 2D 效果或者伪 3D 的,而 3D 粒子效果对于性能上的体验不是很好,于是取巧写了个 3D 热力图的效果 . Demo : http://www.hightopo.com/demo/heatMap3D/ 部分