虚幻引擎5.0制作三维可视化图表-柱...

  • 经验类型教程
  • 经验属性原创文章
  • 经验版权署名-非商业性使用-相同方式共享
2334 0 2 2021-09-14

前言


       近期的一个小研究,也是对UE的在一次深入学习。将柱状与曲线进行合并已3D的数字孪生的形式进行多维度的数据展示。
本次教程将不在涉及UE的基础使用说明,如果有哪些节点和逻辑不明白的朋友可以去翻看下我前面的《UE4之全流程开发基础知识》。同时本次使用的UE版本为UE5体验版,可能会与上期教程略有不同。

项目地址

百度云

https://pan.baidu.com/s/1ovqYBz2hssy10Nbd51GUYg    提取码:Xnjl

Github

https://github.com/AnzaiDesign/visualization 


A.准备基础模型

       首先我们需要准备一个模型,这个模型会在后面被蓝图自动生成。模型的样式形状各位可以根据自己的喜好自行修改,这里我就用了一个立方体。但是其中要主要的是,首先UE并没有特定的尺寸。所以最好用其他三维软件进行制作,并且各位请注意图中模型的实际轴坐标点,必须放置在模型的最下方,这样才能在后续的制作中已轴坐标进行修改模型。还有就是图中UE给咱们计算的“大约尺寸”这个数值,也需要咱们记好方便咱们后续根据这个数值去调整实际的图表尺寸。


B.准备字体

       创建一个字体并命名为“Oswald_Light”,这里的命名可以根据自己的喜好。


B.1.设置字体缓存类型

       设置字体缓存类型为“离线”。


B.2. 确认修改缓存类型


B.3. 选择所需字体


B.4.设置细节与页面详细信息

       具体这些参数为什么要这么设置,其实我也是按照官方的参数来的并没有深入的去了解。

B.4.1.细节


B.4.2. 页面详细信息


C.准备材质

       一个图表由1组或多组数据组成,每组数据均有标注元素、图表颜色和字体材质,随意我们最少需要3个材质来做支撑。这3个材质分别是:Histogram(图表颜色材质)、Name_tagging(标注元素材质)、Oswald_material(字体材质)。


C.1. Histogram

       首先我们需要一个可以用来区分每个数据组折线与柱状的材质。同时我想让其从顶部到底部进行一个渐变隐藏。


C.1.1. 材质属性

       既然是渐变隐藏,那么我们就需要将材质属性的混合模式调整为“半透明”模型。


C.1.2. Color/Color coefficient

       为了能够让对每组折线与柱状进行区分,我们这里需要创建一个4位参数“Color”与一个常量参数“Color coefficient”。这2个参数可以在后续的蓝图中通过创建动态材质实例对齐逐一修改。“Color coefficient”参数与“Color”参数相乘,在后续的蓝图中我们可以通过调整“Color coefficient”来控制其发光的亮度,变相的达到一种用户交互的功能。


C.1.3. UVW

       如果我们想要模型一直从上到下渐变隐藏,那么我就需要用到“Bounding Box Based”节点,也就是UVW节点。正常情况下我们仅需要输入UVW节点中B节点即可得到我们想要的效果。但是为了我们能够更好的修改并达到我们满意的效果,那么我们就需要通过“Power”权重节点来控制其范围。
首先我们将UVW节点的B输入到“Power”节点的"Base"作为基础。然后我们需要创建一个4维向量参数“Mask B”与一个常量参数“transparency coefficient”相乘后输出给“Power”的“Exp”,最后将"Power"输出给材质的透明度节点就可以实现随意控制范围。
“Mask B”参数,用来控制整体的透明度,B值如果为“0”那么整体将是不透明。
“transparency coefficient”参数,用来控制透明度的范围,数值越大透明的范围越大。


C.1.4. 材质实例

       完成上述的内容后,我们可以创建一个材质实例并赋予给基础模型,然后通过调整右侧细节面板内的各类参数来得到我们想要的想过。


C.2. Name_tagging

“Name_tagging”材质时用来设置数据点标注的材质,方法与“Histogram”大致相同。


C.3. Oswald_material

       “Oswald_material”材质是一个文本材质,主要用来渲染蓝图中的文本内容。其中的"Color"参数同样用于后续蓝图的颜色标注,就不做多余说明了。


C.3.1. 材质属性

       这里我们需要先将材质属性内的,混合模式更改为“已遮罩”模型,这样我们就可以使用“不透明蒙版”接口。


C.3.2. FontSampleParameter

       "FontSampleParameter"是UE的专门的字体纹理参数节点。注意这个并不是“Texture Sample”纹理节点,而且各位不要选错成“FontSample”节点,UE的文本纹理节点并不能直接右键转换为参数,所以我们一定要选择这个“FontSample”节点,这样后续如果我们想通过实例材质动态修改文本纹理就可以直接进行更改其参数。


  •  细节面板

       这里我们通过字体选择我们直接已经设置好的字体纹理。因为字体与字体的载量不一样,所以可能有些字体会有1+N个页面,所以我们需要在字体纹理页面这里设置我们所需的页面索引。


C.3.3. Lerp

       之后我们“FontSampleParameter”作为“Lerp”的“Alpha”,通过控制“Lerp”的A值和B值来活动一个不透明蒙版,这里要注意的是,AB值的反差越大其文字则越清晰。如果反正AB值的正负,则会获得另一种效果。


D.准备数据

       最后我们要准备一个供我们后续调用的数据表,具体怎么创建数据表可以查看我上期的教程。这里就不在说明了。


D.1. 表结构

       首先我们创建一个表结构并命名为“Spline_Points_Structural”。
       每个图表的数据均由数值与时间组合而成。如果按照上期教程所讲,那么若果有几组数据我们就需要几个数据表。但这次我准备通过数据表列与行的形式来获取所需要的数据,这样以来我们就可以仅用一个数据表就可以装下多组数据。


D.2. 表

       之后我们来创建一个数据表,并命名为“Spline_Points”。
       “Data 01 - 05”数列均是每组数据的所有参数。这样一来如果我们后续需要新增数据组,直接更改表结构即可。然后我们通过先获得列数据,然后再通过行名称或索引获取到指定的数据,并且每行数据都会有一个相同的时间参数。


E.世界场景设置


E.1. 玩家控制器

       首先创建了一个蓝图,选择“玩家控制器”类型并命名为“visualization_play”用来设置我们一些基础性的控制。


E.1.1. 细节面板

       这里我们主要设置一下细节面板中的“鼠标接口”,勾选上显示鼠标光标、启用点击事件、启用悬停事件。下方的默认鼠标光标类型可以自行选择。


E.2. 角色

       之后创建一个蓝图选择“角色”类型并命名为“visualization_role”。


E.2.1. 添加蓝图基础组件

       这里我为角色蓝图另外增加了2个组件“CineCamera”与“Decal”。“CineCamera”电影摄像机组件,确保运行后我们视窗的位置。“Decal”贴花组件,可以很好的告诉用户鼠标是否悬停在物体上,这个组件根据个人可有可无。因为在运行后我们并不需要显示任何角色模型,所以这里我也没有为网格体增加骨骼模型。


E.2.2. 图表事件


  • 开始运行事件

       当运行时我们需要启用“CineCamera”摄像机作为我们的主视角


  • Tick事件      通过获取玩家控制器的光标命中结果获取到光标位置与命中物体的法线方向。之后通过位置来设置“Decal”贴花组件的位置,再由物体法线方向设置“Decal”贴花组件的角度。这样“Decal”贴花组件就可以跟随光标在物体上显示。


E.3. 游戏模式基础

       创建蓝图选择“游戏模式基础”类蓝图并命名为“visualization_Basics”用来设置我们模式的一些基础内容。这个蓝图也是将我们创建的角色蓝图与玩家控制器蓝图组合成了一个蓝图,如果不想创建也可以通过世界场景设置修改游戏模式。不过最好还是自行创建一个新的。


E.3.1. 类

       这里只需要修改“类”中的,玩家控制器类为“visualization_play”默认pawn类为“visualization_role”即可。


E.4. 世界场景设置

       最后我们通过“世界场景设置”下的“游戏模式”分类中的“游戏模式重载”,选择我们创建的“visualization_Basics”游戏默认基础即可将角色模式与控制模式带入。


F.图表蓝图

       柱状图表与曲线图表均是有1+N个柱状与曲线组合而成。其功能是完全相同的,调用数据通过颜色与标注进行数据区分。只是它们所调用的数据和所使用的颜色与标注有所不同。
所以这里我们至需要创建一个基础的图表蓝图后,通过基础蓝图创建子集实例。再由图表主蓝图当做子集Actor组件进行调用。


F.1. Histogram_Columnar

       首先我们创建一个Actor蓝图,并命名为Histogram_Columnar。之后我可以可以基于这个蓝图来创建对应所需数量的子蓝图来创建我们所需的数据图表。


F.1.1. 添加蓝图基础组件

       首先我们需要为蓝图添加一些基础组件分别是“Spline”样条组件“Sphere”5个静态网格组件,这里为了方便管理我还用到了2个“Billboard”公示板组件,用来管理模型很方便。
这里要注意其层级关系,因为我们要确保所有功能性模型都与样条组件为相对位置,所以生成的和手动添加的模型都需要在样条组件的子集。


  • Spline样条组件

       既然我们是在制作一个曲线与柱状结合的图表,那么我们就需要使用到UE的“样条组件”。UE本身并没有真正意义上的样条,如果我想渲染出样条的样子。我们就需要根据“样条组件”上的样条点去生成足够多的模型,来达到视觉的一条曲线。


  • Sphere静态网格体组件

       这里添加的5个“Sphere”静态网格体组件是用于后续添加交互而添加的。毕竟用户需要知道具体位置的具体参数。


F.1.2. 创建“构建图表”函数

       这里我构建了几个函数之所以为什么要用英文就不多说了。
但是还要为上期教程重新补充说明下,函数与事件的区别。上期教程里提到函数与事件的区别是,函数有返回值而事件没有返回值。
这次要补充的是。函数会等待函数结果,有结果后才会继续执行,事件只是触发有没有结果都往后执行
函数可以使用局部变量,而事件不能使用局部变量。局部变量就是只可在当前函数中使用的变量。函数执行的顺序有保证,他会按照咱们所连接的顺序挨个执行。函数被调用时会变成一个事件。
       结合上述补充的内容,所以建议各位在之后的学习中尽量优先使用函数。这里我尽可能的将每个功能单独封装成一个函数,这样可以更清楚的了解每段内容的具体功能和实现方法。


F.1.2.a.Build Chart分组

       这里时初始化生成模型,并设置基础模型与生成模块的一下基础参数的函数分组。


F.1.2.a.1Build Chart 

       这个函数时用来根据样条创建基础的模型的。


  1. 构建样条点位置

           首先我们需要先设置好样条的每个点固定位置,来确定样条的长度与每个数据的位置。这里的样条有5个点,所以我创建了5个向量浮点并创建去设置向前样条“Spline”。各位可以根据自己喜好去调整样条点数量。


  2. 设置样条中心位置

           为了能让样条实时自动位于蓝图的中心位置,我们需要对样条的相对位置进行一下构建。
           这里我们在设置完成样条的样条点后,可以通过获取样条长度,在用样条长度除以2之后去设置样条的相对位置,即可达到样条实时自动位于中心位置。


  3. 创建样条模型

           UE的样条组件并不会被渲染显示出来,所以在我们设置好样条基础参数后,需要生成我们所需的样条模型,来供使用者查阅。


  • 判断是否需要生成模型

       UE本身并没有什么“扫描”“放样”等功能,而如果我们需要渲染一条曲线或者不规则的面,我们则需要足够多的模型去拓步。让其互相链接从视觉上达到一种假象,实则是由多个模型拼凑而成的。
所以首先为了避免运行无用程序降低运行速度,我们需要判断下是否需要生成模型。
这里我设置了一个整数变量,“Number of columns”既是生成模型的数量,我们通过判断这个变量是否大于0再去执行之后的程序。同时请公开这个变量,供之后在子蓝图中可以直接编辑调用。


  • 根据Number of columns生成对应数量的模型

       假设”Number of columns“变量为”5“,For loop从”0“循环”Number of columns“减”1“,共循环5次(这里为什么要从0开始同时为什么要减”1“,因为所有代码技术都是从”0“开始技术,”0“即为”1“所以我们需要进行减”1“计算)。
之后根据长度长度与模型数量获得平均样条长度,来循环5次获取5个平均点的样条距离处的变换。
       得到每处的变换后我们需要创建一个新的变换。首先我们需要每处的X、Y位置用于确定模型的平面位置。然后我们通过Z轴位置来设置模型的生长高度(这里就要说道为将基础模型的轴心放置在最下方了。首先UE并没有具体尺寸这项设定,所以我们需要通过设置模型的缩放来控制模型的高度生长。既然通过缩放那么我就必须只要基础模型的具体参数然后通过数学计算来得到想要的高度)。这里我运用了一个除法运算并建立了一个浮点变量“Model z-axis scaling”并对其公开,这样我们就可以通过这个浮点变量来控制模型生长的比例,控制其生产的高度不至于超出咱们所设想的高度。最后我们将创建的这个变换循环设置给添加的静态网格体。


  • 将添加的静态网格附加到样条并设置模型

       之后为了方便管理与随意更换模型样式,我们需要将添加的静态网格附加到“Spline”作为子集,然后通过静态网格体变量“Added static mesh volume”来设置已经静态网格体模型样式。后续我们只需要在编辑器里拖拽模型到这个变量即可修改咱们想用的模型。


  • 创建模型数组,模型的基础和历史变换数组

       完成上述的所有操作后,我们就可以在视口看到程序自己所生成的模型了。但是咱们的数据不可能只有这么几条,所以为了让图表是可以实时获取最新数据或循环展示所有数据。我们就需要创建一些基础参数。
首先我们需要将所有已经生成的模型添加到一个数组变量里“Static grid component array”供我们后续循环调用这些模型。然后我们还需要创建2个变换数组变换“Transform data old”与“Transform data Basics”。
“Transform data old“用来储存历史变换的数值用作以后新数据变换的插值变量。
“Transform data Basics”用来存储基础的信息用来设置其基础信息,因为咱们变换都是发生在“Z轴”的所以其他变换我们并不需要重新设置,这样做也是为了避免发生错误。


F.1.2.a.2.Build Chart Sphere


       Build Chart Sphere函数是专门用来设置5个Sphere静态网格体位于样条的对应位置与生长高度,函数的方法与Build Chart函数大致相同这里我着重说明其中的不同点。


  1. 判断是否生成模型获取样条每段长度

    ○ 这里在判断是否生成模型时多增加了一条分支,如果不需要生成模型则循环设置每个“Sphere”为游戏中隐藏。

    ○ For loop节点并未使用变量进行控制则是手动输入的从0到4。

    ○ 这里设置的模型是预先设置好的,所以需要创建一个数组并根据循环返回的次数去索引“GET”设置数组中的每一个元素。各位也可以在运行这条函数前就将“Sphere”创建成一个静态网格体数组变量进行调用。


  2. 创建并设置相对变换、创建模型基础和历史变换数组

    ○ 因为模型时预先设置好的所以不在需要生成添加静态网格体,我们仅需去设置每个模型的变换即可。

    ○ 预先设置好的模型无需再次创建静态网格体数组,只需要分辨创建对应的基础与历史变换数组即可。


  3. 总结

       之所以创建这个函数,是因为图表上的每一个曲线或柱状都需要拥有交互行为,为用户提供每个时间点每个数据组上的对应参数。既然如此我们就需要游泳交互事件的真是模型组件,供我们通过调用触发某些事件来运行交互程序。而通过程序生成添加的模型时无法创建交互事件的。所以我们需要手动添加所需的交互模型。


F.1.2.a.3.Angle display


       当用户去旋转图表时因为模型本身会遮挡注一些位置不容易被用户查看到,而且当用户旋转图表到一定角度时我们图表则会从曲线图变换成柱状图。所以我们需要根据用户旋转得角度来讲不容易被查阅或者不许要的数据进行隐藏,来提高用户的阅读效率。而这个Angle display函数就是做这个用的。


  1. 创建旋转角度

           首先为了避免常事件的Tick事件减慢允许速度,我们需要一个布尔变量“Left mouse button”,通过按住或松开鼠标左键开判断是否执行“Angle display”。之后我们还需要获取到蓝图当前的旋转角度并加上90来设置一个变量“Angle”。之所以要加上90只为了能够更好的控制蓝图该从那个方向进行隐藏。


    ○ Angle变量详解

     下方识图为上视图,上方是背景位置,下方是摄像机位置,中坚则是Actor主体位置。
    如图中间绿色圆圈是默认Actor的旋转角度,蓝色圆圈则是Actor旋转加90后的角度。不知为何当Actor默认旋转到-180°/180°时就会切换正负值。
    其次我们需要当用户顺时针旋转Actor时让生成的模型从右到左依次隐藏或逆时针时从左到右依次隐藏,然后当旋转90°后反转隐藏。那么首先我们需要计算出每个生成模型的隐藏角度(模型数量除以90°/-90°),然后我们再去实时判断Actor是否达到模型需要隐藏的角度。
    这时就会出现一个问题,因为我们所得到每个模型隐藏角度均在0°到正负90°之间,那么如果我们使用默认的旋转就需要复杂的计算来判断Actor是否抵达模型消失角度。所以为了省去后续的复杂计算就绪在Angle变量上增加一个90°的基数。
    简单点来说,就是需要将360°分成左右2个部分,4个区域分别是蓝色区域的90°至0°、0°至-90°、270°至180°、180°至90°。之后就需要考虑当旋转到每个区域时是从那个方向隐藏或显示。
    90°至0°:从右到左隐藏
    0°至-90°:从左到右显示
    270°至180°:从左到右隐藏
    180°至90°:从右到左显示
     如此一圈,不管用户是顺时针转还是逆时针转都会有很好的体验。


  2. 创建模型角度正负值变量

           首先我们创建2个函数局部变量,分别是“Static grid component Angle positive(模型数字平均旋转正角度)”、“Static grid component Angle negative(模型数字平均旋转负角度)”。
           然后我需要拿到之前“Build Chart ”函数中所创建的静态网格体数组变量“Static grid component array”。通过“LASTINDEX”获取到数组中最后一个的索引值,用起进行整数加法运算加“1”,然后再进行浮点除法运算除以“90”就可以获取到数组中平均每个模型的旋转角度(之所以要浮点除法是因为角度不可能都是整数)。


  3. 判断旋转所在左右那个部分

           首先在函数运行之初我们就需要根据“Angle”来判断下用户在向左右那个部分进行旋转,从而筛选掉2个程序。


  4. 四个区域的计算与判断逻辑

           这里我只讲解下根据样条组件所生成的模型隐藏方式,后方还有一组是用来隐藏“Sphere”组件的计算逻辑,整体是一样的。


    4.1.左部分


    ○ 判断左部分区域

           我们可以通过“Angle”来进行一个范围内浮点的判断,将之前设置的“Static grid component Angle positive”输入给Min,Max设置为“90”,如果返回Ture当前旋转角度则在“90°至0°”,反之则在“0°至-90°”。


    ○ 90°至0°区域

           当前角度如果位于“90°至0°”的区域里时,循环设置“Static grid component array”数组中的每一个模型的可视性,我们可以通过循环获取到没一个模型的索引值并进行加“1”运算,然后用当前整数乘以“Static grid component Angle positive”变量即可获取到每一个模型所需要隐藏的角度,之后在于“Angle”变量进行小于等于布尔判断并对其可视性进行设置。这样就可以实现不在可视范围内的模型被隐藏,而在可视范围内的模型一直是显示状态。这里我在执行设置可视性之前还增加了一个布尔判断,为了是避免发生错误。


    ○ 0°至-90°

           当前角度如果位于“0°至-90°”的区域里时,基本的运算与“90°至0°”的运算方法大致相同。只是我们的判断角度变成了负值,所以我们需要用每个模型的索引去乘以“Static grid component Angle negative”得到一个负值角度在与“Angle”进行大于布尔判断。


    4.2.右部分


    ○ 判断右部分区域

           通过当旋转值右侧部分后我们也需要一个区域判断,只是这个判断运行略有不同。这里"Angle"变量进行了一次减法运算减去了“90”,也就以为着我们让"Angle"变回了原始默认的数值,但“Angle”变量没有变。如果返回Ture当前旋转角度则在“90°至180°”,反之则在“180°至270°”。


    ○ 90°至180°区域

           当前角度如果位于“90°至180°”的区域里时,运算方法与“90°至0°”几乎一致,只是我们需要在“Angle”后进行一次减法运算,保证输入值是原始默认数值,之后角度判断变成了大于。


    ○ 180°至270°区域

           “180°至270°”的运算同样与“0°至90°”的运算大致相同,只是可以看到我在“Angle”之后不仅进行了一次减90的运算,还又进行了一次减180的运行。这样我就将“180°至270°”这个区域变相的变成了“-90至0°”的区域。然后再用负角度变量进行小于布尔运行去设置可视性。


    4.3.Angle变量补充详解

           通过下图在结合上述我所说的,可以看到黄圈最后通过运算后的真实角度。
           截止到这里,图表的基础蓝图构建功能就算基本完成。


F.1.2.b.Details分组

       "Details"是一个细节初始化分组,针对一些细节来进行初始化设置。


F.1.2.b.1.Initialize Color

       “Initialize Color”是用来初始化基础蓝图内组件颜色的一个函数,通过还可以通过这个函数来调用调整    “Sphere”的后续交互性功能。


  1. 函数输入

           这里我们利用函数输入创建几个输入接口,方便后续跨蓝图调用并传送变量值。

    ○ Name_Color

           线性颜色接口基础的数据区分颜色值,主要用来控制循环生成的模型颜色。

    ○ Color_quotient

           线性颜色接口,用来这时"Sphere"的颜色

    ○ Color_coefficient

           浮点接口,用来设置“Sphere”的交互发光强度。

    ○ New_Visibility

           布尔接口,用于初始化“Sphere”是否在游戏中隐藏,后续我们通过这个接口来控制交互“Sphere”的隐藏和显示。


  2. 循环设置生成模型的材质

           我们可以通过循环获取“Static grid component array”数组内模型的材质,将其创建为动态材质实例,在把这个动态材质重新设置给模型,最后我们就可以通过函数的输入接口来控制设置材质上的对应线性颜色参数。


  3. 设置Sphere的材质

           这里是“Sphere”模型的颜色与交互时让其提高自发光亮度,其实我们也可以通过创建数组的形式来循环设置。这里主要说一下为什么我这设置线性颜色时进行一次“Name_Color”与“Color_quotient”的乘法运算。

           首先当前这个数组不管是生成的模型还是咱们手动添加的模型,其颜色应该属于相同色相,但是我们又需要在交互时可以让用户很清楚的看到交互功能的位置,所以就需要对齐进行一个区分,那么我这里用着2个进行相乘,就会得到一个亮度更高的一个颜色,即不脱离当前色相也能很好的区分。


  4. 设置Sphere是否隐藏

           最后我们需要循环设置“Sphere”在初始时为隐藏状态,之后我们可以通过事件来调用函数循环修改为显示。


F.1.2.b.2.Tangent

       “tangent”函数是一个细节控制函数,众所周知样条不管在什么软件中都是右数个点串联而成,每个点都会有2个切线来控制其样条弧度,UE也不例外。所以这里为了避免因为切线设置错误导致样条不够美观,我们需要初始化一下样条的切线参数。


  1. 根据样条点数量设置循环次数

           我们通过获取样条点的数量,然后进行减法运算减“1”,来设置For loop的循环次数。


  2. 设置样条点进入与离开的切线

           每个样条点都有一个进入切线与离开切线,每条切线又有一组XYZ值。我们可以通过这些值来获得我们所想要的样条样式。这里我只是简单的用了3个浮点变量将其设置为了一个相同的数值,如果有需要的可以自行增加一些参数。


F.1.2.c.Load Data分组

       "Load Data"是针对后续的“Load Data”事件而封装的数据加载动画函数。


F.1.2.c.1.Start Data

  1. 函数输入

           添加“Start Data”函数的输入接口,“Return Value”字符串数组。这个接口在后续的事件调用时用来传送我们所需要的数据表数据。


  2. 创建变量获取行数据

           我们有5个“Sphere”数据点可以用来数据,所以我们需要创建对应的5个整数变量作为索引获取5个数据。这里我将其命名为“Row Index”。并且按照顺序分别设置默认值“0、1、2、3、4”。之后通过“Row Index”索引“GET”获取到“Return Value”字符串数组里的指定数据。


  3. 设置样条点  获取到5个点的数值后,分别去设置5个样条点的“Z”轴数值。


F.1.2.c.2.Set build model New Transform


  1. 创建新的变换并循环设置

           我们需要创建一个新的变换数组变量“Transform data new”,并将循环生成的变换“ADD”在这个变量里。之后我们可以通过之间创建的“Transform data old”与”Transform data new“进行一个插值动画。


  2. 返回节点

           这时就要用到返回节点,来确保只有等函数循环完成后才可进行后续的程序。


F.1.2.c.3.Set Sphere New Transform

       “Set Sphere New Transform”函数与“Set build model New Transform”的功能相同,也是生成一个新的变换“Sphere_new”变量。同时也要注意需要使用返回节点。


F.1.2.c.4.Data Over Animation

       “Data Over Animation”函数是用来将数据进行动画过度的函数。这里一共运行2段动画,分别是针对生成的模型与Sphere模型。思路一样我就讲解其中一个。


  1. 函数输入

           讲解函数之前我说过,函数不能使用时间轴节点。那么我就需要在调用时为其传送一个时间轴信息。那么我就需要在函数输入创建一个浮点接口“animation”。


  2. 根据Number of Columns创建For循环

           同样我们需要创建一个循环执行,让所有生成的模型来执行通一条命令,但是所执行的参数各不相同。


  3. 设置动画

           这里我们可以将For循环的次数当做索引值,来获取各类数组中的对应内容。然后通过之前我们创建的“Transform data old”插值变化至“Transform data new”这个变换从而得到移动过度动画。这里可以看到插值的输入我只使用了变换的缩放,而其位置则是采纳的“Transform data Basics”变换的参数,这样做的好处就是必变计算错误导致模型位置错乱,毕竟这个基础位置是不变的,我们只需要调整模型的缩放即可。


F.1.2.c.5.Change Transform

       当我们的过度动画执行完毕后,我们需要更换新老变换数据,从而得到一个持续连贯下去的动画循环。

       “Change Transform”函数就是这个功能的核心。当动画执行完毕,首先我们要“CLEAR”清除掉“Transform Data Old”变换数组内的所有内容。之后将“Transform data new”变换数组的内容设置为“Transform data old”。最后在将“Transform data new”清除。这样当下次动画开始时,就会已当前动画结束的位置为基础重新开始。


F.1.2.c.6.Replace Row Index

       在我们完成新老变换更换之后,我们需要重新获取新的数据参数,那么就需要对5个“Row Index”变量进行更改。在更改的同时还要考虑到如果“Row Index”运行到最后一个索引值时需要让其该更改第一个索引“0”。这样才能做到无限循环。


  1. 函数输入

           首先我们需要创建一个字符串数组输入接口“Return Value”用来获取列数据。


  2. 判断并设置索引

           接下来我们通过获取到的字符串数组来获取到“LASTINDEX”最后一个索引。在用“Row Index”与最后一个索引做等于布尔。如果“Row Index”等于最后一个索引,那么设置“Row Index”为“0”第一个索引。如果“Row Index”不等于最后索引,那么“Row Index”当前数值加“1”运算后再次设置。

    这样一来我们就可以确保,当动画循环到最后一个数据后重新重头开始,也可以让其正常的加“1”循环下去。


  3. 返回节点

           为了避免报错跳过我们需要在最后加上一个返回节点。


F.1.2.d.构建脚本

       所有函数都完成后,我们需要开始构建脚本了。

       这里我使用了一个“序列”节点,避免那个函数出问题后不在往后进行。

       首先我们需要先构建自动生成的模型与“Sphere”的位置,也就是“Build Chart ”和“Build Chart Sphere”。然后我们需要构建样条切线“Tangent”。最后同样为了避免错误我们需要将“Row Index”变量也构建一下(不知道为什么UE5的默认值有的时候总有问题)。


F.1.3. 图表事件


       在我们将所有函数构建完成后,就是要将其串联起来最终得到我们想要的效果。


F.1.3.a.Load data 

       当开始运行时,我们需要开始加载数据表里的数据,并且让以动画过度的形式循环加载。


  1. 将数据表列获取为字符串

           首先我们创建一个数据表变量“Spline_Points”与命名变量“Property Name”,并且对“Property Name”进行公开。这样我们就可以在不同的子蓝图里通过修改这个变量来调用不同的列数据。


  2. 加载数据设置生成模型与Sphere的新老变换之后就用到我们之前创建好的几个函数了。将获取的数据列字符串传输给“Start data”函数设置样条点位置,之后通过“Set build model New Transform”函数循环获取每个生成模型的新的变换数组,循环完成当前函数后,执行“Set Sphere New Transform”循环获取“Sphere”的新的变换数组,循环完成后执行后续动画内容。


  3. 从头开始播放动画

           开始从头播放时间轴动画(事件长度根据自己喜好自行设置,保证浮点时从0到1即可)。动画所执行的内容既是“Data Over Animation”,我们要将时间轴的浮点值传送给“Data Over Animation”的输入接口,从而达到插值动画。


  4. 动画播放完成执行

           动画播放完成执行“Change Transform”对新老变换进行清除和设置,设置完成后运行“Replace Row Index”根据数据表类字符串设置“Row Index”,设置完成后再次返回到事件开始位置再次循环。


  5. 注意事项

           这个事件中还有一个“Mouse_hover”与2个布尔判断,这2个位置会在后续的内容中说明作用。在当前事件没有这2处内容是可以完美循环获取数据的。


F.1.3.b.事件开始运行

       在开始运行时我们就让程序开始执行“Load data ”从而达到一个可控的Tick事件。


F.1.3.c.mouse_hover

       “mouse_hover”事件是为了当用户在与图表进行交互时,停止图表的数据加载让用户查看当前数据而存在的事件。

       首先我们需要创建一个“自定义事件”并设置一个布尔输入接口“Hover”。之后创建在时间轴节点前后各增加一个分支节点,将“Hover”参数赋予它们。

       现在来说一下这个看似简单的事件的功能逻辑。当鼠标悬停在图表时,触发“mouse_hover”事件,并且传输“Hover”变量为"False",这时动画会播放到最后一针,但不会触发动画的完成事件。这样做可以让图表停止在正确的标注线上,而不是直接停止,直接停止则会出现显示数据与图表标注数据不符的现象。而当鼠标离开图表时,触发“mouse_hover”事件,并且传输“Hover”变量为"True",则会根据当前时间轴停止的位置继续播放,而停止的位置是最后一针,那么时间轴则会触发完成事件之后后续事件,然后开始循环。


F.1.3.d.鼠标悬停事件

       创建好动画停止与继续的事件后,我们就可以通过UE蓝图的鼠标开始悬停与鼠标结束悬停事件来调用“mouse_hover”事件。

       因为我们后续是需要调用1+N个子集实例蓝图,所以当用户进行操作时是需要停止多个子集。为了避免发生错误,我们需要先创建一个布尔变量“Hover”。之后我们就需要通过“获取类的所有actor”节点来获取到所有的“Histogram_Columnar”蓝图,之后通过“For Each Loop”节点循环执行设置“Hover”变了并赋予执行“mouse_hover”事件。


F.1.3.e.小结

       最后剩下“mouse_hover_Sphere”里的种自定义事件“Columnar_Hidden”“Columnar_Show”因为是跨蓝图事件,暂时先不在这里说明。待我们将主蓝图创建完成后再来详细说明。


F.2. Histogram_Basics

“Histogram_Basics”蓝图将作为我们在场景中调用的主蓝图。我们通过这个蓝图可以添加1+N个“Histogram_Columnar”蓝图。在配合其他组件从而得到一个完整的图表。


F.2.1. 添加蓝图基础组件

首先我们可以看出,这次的组件结构非常的多。因为所有图表均由时间线、数据值标线、数据名称标注与数据图表构成。这样一来我们可以将其分成“Numerical line(数据值标线)”、“Name line(名称标线)”、“tagging(数据名称标注)”、“Time line(时间标线)”这4大类,其中所使用到的组件类型主要是“静态网格体组件”与“文本渲染组件”。下面我会挨个分开先把这些组件的具体作用讲解透彻。


  • 静态网格体组件

  1. 线

    就一个细长的立方体组件,主要用来当做线来时使用为用户划清边界与进行数据参考。


  2. 标注

    标注类一个静态网格组件,由一个平面模型构成。这里我命名为了“Plane”主要用于显示各类数据的颜色便于用户区分数据,其次拥有一个点击显示或隐藏数据的功能。

    创建好这个组件后,我们就需要将之前准备的“Name_tagging”材质创建一个子集实例材质赋予给这个静态网格体组件,供我们之后动态调用对应数据颜色使用。


  • 文本渲染组件

    文本渲染组件是用来将文本专为一种可视模型的组件。这个组件需要配合之前准备的“Oswald_material”文本材质来使用。

    首先设置材质的“元素0”与“文本材质”,之后选择对应的我们之前所使用的字体。剩下的就是一个基础的排版格式就不多说了。


  • Numerical line

    “Numerical line”是数据参数标线,我们需要让用户知道图表当前所在的对应数值位置。


  • Time line

    对于折线型图表,我们不仅需要数据参数的标线。还需要一个横向的时间标线。“Time Line”就是用于循环更新时间的一组功能组件。


  • tagging

    “Tagging” 是由数个“文本渲染组件”+"Plane"组件组合而成一个数据标注组件。其用途就是对数据折线进行颜色与文本标注的区分。其次为了可以使用户单独查阅某一组数据还增加了点击显示与隐藏的功能。


  • Name line

    当我们将图表旋转到一定角度,使图表变换成柱状图表时,那么我们将不在需要时间线的组件,将与之替代的是每组数据对应的名称。


  • Name Year

    当图表位于柱状图表模式的时候,虽然我们不需要时间线的显示方式了。但是数据还是需要进行更新,而更新这就需要向用户提供当前更新数据的具体时间时间。而“Name Year”这组组件就是用于想用户提示当前数据的时间的组件。


  • Histogram_Columnar_Child

    “Histogram_Columnar_Child”是一个子Actor组件,通过这个组件分别调用了5个“Histogram_Columnar”5个子集实例蓝图。从而实现一个图表中加载5组不同的数据。我们可以通过蓝图的子Actor组件细节面板分别设置每个“Histogram_Columnar”子集实例蓝图的一些基础参数。如“Number Of Columns”、"Property Name"、"Model Z-axis Scaling"等一些公开的参数。切记一定要在蓝图中设置,场景的世界大纲内是不能设置的。


  • Data panel

    “Data panel”这组组件是用于当用户与图表进行交互操作时,向用户展示具体参数点的当前实际参数的。这组组件分别会根据用户所选择的点渲染当前数据的“名称”、“时间”、“具体数值”。


  • Data marking

    在传统的二维图表中,当用户进行交互时会有一个当前数据标记的系统行为,用来提示用户当前查看的数据节点位置。但是这个标记并不是一定要有的。

    但是当图表从二维转变到三维时,因为透视关系有时用户并不能很直观的知道具体查看的是那组数据的数据节点。所以就需要制作一个三维坐标标记。


F.2.2. 创建“构建图表”函数

在图表构建时就需要对每个子Actor组件调用的”Histogram_Columnar“子集实例蓝图进行颜色构建。”tagging“下的各个标注的颜色与数据名称进行构建。同时还需要编写一些功能逻辑,方便我们在后续的事件中调用,这样看起来会更清晰。



F.2.2.a.Initialize color and name


  1. 通过“Property Name”变量获取设置数据名称

    首先需要读取子Actor的变量,并将其转换成一个Actor,然后将其转换成对应的“Histogram_Columnar”子集实例。这时我们就可以获取到“Histogram_Columnar_Child”中的“Property Name”变量,当拿到“Property Name”值后我们可以将其转换成文本并用来设置“文本渲染组件”的文本内容。


  2. 设置“tagging”组件内的动态材质

    首先创建5个线性变量并命名为“Name Color”,这5个变量用来控制5个图表的颜色用以数据区分。之后就是对“tagging”组件组里的“文本渲染组件”与“Plane”组件进行材质实例化然后修改其颜色。


F.2.2.b.Child_actor

5个“Histogram_Columnar_Child”子Actor组件肯定不能重叠的,所以为了在运行时出现错误,我们在就需要对其位置进行一个初始的设置。

这里我在设置组件相对位置时使用了一个浮点变量,为了就是我们可以方便的编辑。


F.2.2.c.Child Actor Color“Child Actor Color”函数时用来初始化5个“Histogram_Columnar_Child”组件的,这时有人就要问,在创建“Histogram_Columnar”时不就已经初始化过了吗?首先我们要分别初始化5个“Histogram_Columnar”的子集实例蓝图,当然我们可以手动通过调整“子Actor组件”的“子Actor模板”项来初始化我们所想要的内容,但是这样我们分别调整5次而且后续调试修改也不方便。所以我们直接通过程序在“Histogram_Basics”蓝图里进行一次统一传值统一设置。


  1. 函数输入

    首先为函数创建6个线性颜色输入接口,其中5个命名为“Name Color”对应我们创建的“Name Color”变量,剩下一个命名为“Color Quotient”对应我们在“Histogram_Columnar”中创建的“Color Quotient”变量。之后在创建一个浮点与布尔输入接口,分别命名并对应“Histogram_Columnar”中的”Color Coefficient“与"New Visibility"变量。


  2. 类型转换并执行每个子集实例蓝图中的“Initalize Color”

    通过类型转换将每个“子Actor组件”转换成对应的“Histogram_Columnar”子集实例蓝图,然后执行每个“Histogram_Columnar”子集实例蓝图内的“Initalize Color”函数。执行时我们将当前的函数的输入接口对应链接到每个对应的函数上,这时我们就可以通过当前蓝图初始化“子Actor组件”所调用的子集实例蓝图。


F.2.2.d.Line

当用户在旋转图表时,相对的一些数据标线与标注也需要移动,已满足用户在任何角度都可以轻松的查看到标注线与标注内容。而“Line”函数就是满足这个功能的函数。


  1. 创建枚举

    首先创建一个枚举并命名为“Angle_enumeration”,这个枚举在之后的函数中将用来判断角度区域,依次来执行不同的程序。


  2. 角度区域


  3. 通过“Angle”判断所在区域并按照区域执行不同的程序

    创建一个整数变量“Angle_enumeration_index”,这边来会作为枚举选择的索引值来使用。

    通过“Angle”变量(这个里的“Angle”是我在当前蓝图中再次新建的)进行范围浮点判断,如果为“True”最会设置“Angle_enumeration_index”为对应索引并向后判断执行不同的程序。


  4. 标线与标注移动

    如果设置移动这个就不多说了,主要来看下方的浮点计算。首先我们知道标线的开始点与结束点。那么我可以通过插件让其在这2个点之间来回移动。但是我们需要"Alpha"来对其进行控制。而这个“Alpha”就是,通过“Angle”在进行限制后进行一次浮点除法除以“90”来获得。如果当前角度在180°-270°那么我们仅需要在除法前增加一个减法运算减去“90”。这样一来用户在旋转图表时,标线与标注就会实时移动。


F.2.2.e.Name Hidden

“Name Hidden”函数为用户提供了数据过滤功能,可以通过点击对应的数据标点对数据进行显示与隐藏的操作。


  1. 函数输入

    这里需要“子Actor组件”、“文本渲染组件”、“静态网格体组件”接口,分别命名为“Child”、“Name"、"Plane"。这3个接口时用来获取我们需要隐藏与显示的组件的。

    然后还需要2个线性颜色接口“Original Color”与“Hover color”这2个接口是负责控制当组件隐藏与显示时标注组件所需显示的颜色。

    最后我们还需要一个布尔接口“Hidden”,后续我们会通过点击事件触发切换节点,而我们则需要获取到切换节点的布尔值,通过这个布尔值来控制显示与隐藏。


  2. 切换可视性

    如何切换颜色这里就不做说明了。这里主要说下怎么切换显示。

    后续我们通过“Flip Flop”切换节点的布尔值“Is A”若果是“A”则返回“Ture”。那么我们的所有模型在运行时可视性均是“Ture”,那么我们需要在点击“Plane”是让其更换为"False"。但是在我们点击时肯定触发的是A,所以返回的是“Ture”这时就出现一个小BUG,所以我们在输出"Hidden"是需要先增加一个“NOT”布尔节点。这个点击就是一个反转节点,如果输出是“Ture”那么会将其反转成“False”,这时当我们点击“Plane”时就可以隐藏,再次点击时就是显示。



F.2.2.f.marking

为了可以让用户更准确的得知所交互的数据点,我们需要为其增加一个三维定位功能。而“marking”函数就是控制“Data marking”组件来做三维定位的功能函数。


  1. 函数输入

    我们需要3个浮点接口分别命名为“X”、“Y”、“Z”用来获取所需定位的位置来设置“Data marking”各个组件的位置。还需要一个布尔接口命名为“Hidden”来控制其隐藏与显示。


  2. 减量运算

    这里重点说下这个减法运算,其余的节点都很好理解。

    当我们获取所需定位的位置后,为了确保“Data marking”组件不会遮挡我们的图表,我们需要做一个减量运算让其避开图表交互模型“Sphere”。之后我们在用经过减量的浮点值去设置对应的“Data Marking”组件的所需定位的轴向值。


F.2.2.g.Mouse Hover Sphere

当用户鼠标指向某个“Sphere”时,既是用户明确需要知道当前数据的时候。所以我们需要对“Data panel”组件内的“文本渲染组件”进行数据渲染,还要对“Data Marking”组件内的组件进行三维定位。最后为了减少其他干扰元素,我们需要将其他图表进行隐藏。所以这套函数是数个小函数并结合跨多蓝图功能实现的一个函数。


  1. 函数输入

    首先我们先需要一个布尔接口用来控制“Data panel”显示具体数据显示并将接口命名为“Mouse Hover Sphere Hidden”。接下来我们就需要几个文本接口和一个线性颜色接口分别命名为“Name”、“Name Pane Color”、“Year”、“Month”、“Day”、“Data”这些接口将会为"Data Panel"进行数据的渲染。之后我们需要三个浮点接口分别是“X”、“Y”、“Z”用来控制“Data Panel”与“”Data Marking"组件组的显示位置。

    最后我们还需要一个整数接口与一个布尔接口,分别是“Other Hiden”与"Hover"。这组接口是用来控制当用户与数据交互时,那些图表将会被隐藏。


  2. 渲染Data Panel数据

    首先我们通过“Mouse Hover Sphere Hidden”接口控制“Data Panel”的父级隐藏与显示,然后通过“Name”、“Name Plane Color”、“Year”、“Month”、“Day”、“Data”从数据表获取到数据后为“Data Panel”下对应子集进行渲染赋值。这里要注意下“Data Panel”设置隐藏时,勾选了”Propagate to Children“不然子集不会一起被隐藏。



  3. 设置Data Panel与Data Marking组件的相对位置接下来我们通过与数据点交互时获取到的XYZ值来设置“Data Panel”与”Data Marking“组件组的显示位置。


  4. 设置图表的显示与隐藏

    首先创建一个“子Actor组件”数组变量命名为“Child”,之后可以他通过悬停事件查抄到当前“子Actor组件”的索引。然后我们可以通过“不等于”索引布尔来设置其他为悬停的“子Actor组件”为“隐藏”。在执行隐藏前为了避免程序错误,增加了一个布尔判断,用来判断用户是否进行了悬停操作。只有用户悬停时才能进行隐藏。


F.2.2.h.Sphere Angle

“Sphere Angle”是为了能够让用户在旋转图表时,“Data Panel”能够实时的面向用户为用户提供良好的查阅数据体验而创建函数。


F.2.2.i.构建脚本

函数创建完毕后来构建脚本,首先我们需要构建数据标注的文本内容与颜色“Initialize Color and Name”,然后确定每个“Histogram_Columnar_Child”组件的位置“Child Actor”。之后我们需要设置每组图表的颜色等基础信息。最后我们需要将“Histogram_Columnar_Child”5个“子Actor组件”创建为“Child"变量供我们在”Mouse Hover Sphere“函数中调用。


F.2.3. 图表事件

现在我们要将函数串联成事件。这次有一部分事件会涉及跨蓝图或多蓝图多含糊一同调用。


F.2.3.a.事件开始运行

首先启用输入,这样才可以对图表进行控制。之后需要让图表进行运行加载数据图表,我们需要通过“获取类的所有Actor”节点来获取“Histogram_Columnar”蓝图的所有子集实例,然后循环设置他的“Hover”值并执行“Mouse Hover”事件(其实从逻辑上来说并不需要执行这个事件,但是不知道为什么“Hover”变量设置默认值为“Ture”后并没有起到作用)。


F.2.3.b.Time

接下来需要创建一个新的自定义事件“Time”,这是用来为每个数据节点进行事件标注的事件。

首先需要将任意一个“子Actor组件”进行转换后获取到“Histogram_Columnar_Child”子集实例蓝图的所有“Row Index”变量。之后可以通过“Row Index”来获取到“Spline Points”数据表对应行的行名称,最后我们在通过行名称来获取数据表行的内容。

当找到行后,我们将数据表里的时间数据进行拆分,然后将对应的日期数据设置给对应的“文本渲染组件”。

因为“Row Index”变量是会自动更换的,所以咱们没一个数据节点的日期也是动态自动变更的。


F.2.3.c.Time/Name_Show / not show/Rotate

“Time/Name_Show / not show/Rotate”事件是为用户在旋转图表时因为图表展示模式的切换,而对折线标注时间与柱状标注时间进行切换显示的事件。

在创建事件时,需要为事件创建一个浮点输入接口“Show / not show/rotate”,通过这接口获取到Actor的旋转角度。

结合下方的旋转示意图,我们至需要将其分成2个部分“0°至-180°”与“0°至180°”(绿圈部分)。当旋转到“-45°至-135°”与“45°值135°”时我需要让“曲线事件标注”隐藏“柱状时间标注”显示,其他角度反之。

首先我们需要一个“范围内浮点”节点,通过Actor旋转角度判断是否在“0°至-180°”,这样我们就将旋转分成了两个部分。

然后我们在分别创建两个“范围内浮点”并分别设置Min为“-135°”与“135°”Max为“-45°”与“45°”。

最后我们在通过“选择”节点,判断角度位于那个部分,然后进行输入对应的布尔值,用于执行不同的设置。

最后需要对“Numerical line”组件组的数据值标注进行旋转设置,让其一直正对用户。因为我们获取到的Actor旋转并不是“360°”而是2个“180°”,所以我们同样需要一个“范围内浮点”节点对齐区域进行判读然后再执行对应的设置。

而我们要设置“Numerical line”旋转角度为“0°至360°”均为正值,而我们接收到的值是有负值的存在,所以我们需要使用"ABS"绝对节点,将其转换为一个绝对值。然后当角度在“0°至-180°”是,我们将角度专为绝对值后直接设置相对旋转。若果不在“0°值-180°”那需要用180减去绝对值,在用这个值加上180(当角度到180时,如果继续旋转则是从180到0,而我们需要让其继续增量到360,所以我需要先用180减去当前绝对值得到一个增量插值,在这个值加180就是继续做增量从180到360)。


  • 旋转示例图


F.2.3.d.事件Tick

首先创建设置“Angle”变量,供后续事件调用。然后实时执行“Line”函数这只标注线的移动,“Time”与“Time/Name_Show / not show/Rotate”实时设置时间标注与控制显示隐藏,“Sphere Angle”设置“Data Panel”实时面对用户。

下方还有一个“Hover”布尔时间,这个是与鼠标左键事件(旋转Actor)配合使用,当我们鼠标悬停时“Hover”为“True”才可执行鼠标左键事件。


F.2.3.e.鼠标左键通过鼠标左键事件来控制Actor的旋转。

首先创建一个向量2D变量“Mouse position”,当按下鼠标左键时将获取玩家控制器鼠标位置并创建成向量2D设置给“Mouse position”。之后需要配合“Gate”节点,当按下左键开启,松开左键关闭。当我们按下左键并且鼠标必须在Actor上时开始Tick事件。之后实时循环设置“Histogram_Columnar”所有类的“Left mouse button”变量为“True”,这样当旋转时就会执行“Angle Display”函数(根据角度隐藏或显示模型)。循环完成后,用移动后的用户鼠标位置减去之前的“Mouse position”变量,获得到一个插件,我们可以利用这个插件创建一个旋转体,在用这个旋转体去设置Actor的场景旋转。最后在我们再将移动后的鼠标位置重新设置为“Mouse position”即可得到旋转Actor的功能。在创建旋转体之前我们也可以进行一次乘法运算,来提高旋转的角度倍数。

最后在松开鼠标左键时,我们需要循环设置“Histogram_Columnar”所有类的“Left mouse button”变量为“false”,不让其执行“Angle Display”函数。


F.2.3.f.Color_hover

当用户在图表上进行悬停时,应为用户提供出数据关键点的具体位置,好让用户清除的知道那些地方是可进行操作的。这个事件会分别在“Histogram_Columnar”与“Histogram_Basics”蓝图内分别调用。

首先当用户光标悬停时,有高亮的动画。那么在光标停止悬停时肯定就会有一个反向的动画。所以我们在创建事件时,需要创建一个布尔接口,用来接收”Hover“的参数。通过这个布尔值在集合时间轴节点的从头开始播放与从末尾开始播放来实现次功能。

然后时间轴我们需要分辨创建一个浮点时间轴与颜色时间轴。

在动画开始后我们仅需要执行之前制作的“Child Actor Color”函数并将2个时间轴分别赋予对应的函数接口。最后我们通过浮点值是否等于“1”来控制“Sphere”的显示与隐藏。


F.2.3.g.开始/结束光标悬停


  1. Histogram_Basics悬停事件

    当用户悬停时首先我们需要循环设置“Histogram_Columnar”类中的“mouse_hover”事件,让其数据加载动画暂停或者播放。然后再来设置“Color Hover”让其播放还是倒退。


  2. Histogram_Columnar悬停事件

    同样在用于与“Histogram_Columnar”蓝图交互时,需要循环设置并调用“Color Hover”事件。


F.2.3.h.点击时(Plane)

首先我们需要在每个“Histogram_Columnar_Child”子集实例蓝图中创建一个布尔变量“Name Hidden”。通过这边变量控制“Sphere”的交互。

首先我们通过“Flip Flop”切换节点来设置每个“Histogram_Columnar_Child”子集实例蓝图中创建一个布尔变量“Name Hidden”。之后利用切换节点的“Is A”布尔来控制“Name Hidden”函数执行那段程序。从而得到点击“Plane”时让图表隐藏,对应的数据标注颜色变成灰色。


F.2.3.i.用户界面事件


rotate_right与rotate_Left


1.1开启隐藏模型

首先在执行事件时,我们需要将所有的“Histogram_Columnar”类的“Left Mouse Button”变量设置为“Ture”,这样Actor旋转时图表模型则会自动隐藏或显示。

1.2判断角度

当循环设置完成后。根据“Angle”来判断执行执行那个旋转角度。这里运用到“AND”与“OR”的布尔节点。"AND"节点是两个输入均是“Ture”输出则是“Ture”,如果其中一个是“False”则输出“False”。"OR"节点则是其中任意输入点为“Ture”则输出“Ture”,如果所有输入点为“False”则输出“False”。这里至简单说一下这2个几点,具体详情可以百度下很多详细解释。


1.3执行动画

首先获取到Actor的当前旋转变换,由此创建一个旋转体变量“Return Value Rotation”(其实这个变量可有可无为了不出问题加了一个)。只有用当前旋转进行插值动画到指定角度。


1.4关闭隐藏模型

动画执行完毕,需要将“Histogram_Columnar”类的“Left Mouse Button”变量设置为“False”。

reset 

“ Reset”是用来让图表进行复位的事件。首先需要将所有的“Histogram_Columnar”类的“Left Mouse Button”变量设置为“Ture”,让模型自动根据角度显示。然后执行插值动画,让Actor旋转复位到“0”。动画结束后,因为Tick事件有时会导致标注线无法完全自动复位到初始位置,因为Tick事件并不是帧事件具体的详情请自行百度。所以我们需在要增加一组动画,让标注线在最后自动复位到初始位置。当标注线复位动画完成后,我们还需要将所有的“Histogram_Columnar”类的“Left Mouse Button”变量设置为“false”。


F.3. Histogram_Columnar_Child

“Histogram_Columnar_Child”蓝图是“Histogram_Columnar”的子集实例蓝图。之所以将其单独拿出来说,是因为在这个子集实例蓝图中还需要创建几个事件,而且这些事件是“Histogram_Columnar”、“Histogram_Columnar”与“Histogram_Columnar_Child”相互关联的。

这里的事件主要用于当用户对指定图表交互时,为了减少其他图表的干扰,需要将其他图表进行暂时性的隐藏。之后让数据标注点高亮并且停止数据动画,可以与其进行交互显示标注点的具体数据内容。当用户取消其交互行为时,则会复位并重新开始数据动画。


之前我们一共创建了5个“Histogram_Columnar”子蓝图,我们需要分别为这5个子蓝图编写一下功能功能,功能相同编写一个直接复制就行,唯独需要注意的是子蓝图内的类型转换节点与一些获取的变量节点需要手动调整。


F.3.1. 创建隐藏与显示公共事件

首先我们需要返回到“Histogram_Columnar”主蓝图内。创建一个公共的显示事件“Columnar_Show”。因为咱们有5个数据标注点,还需要创建5个隐藏其他图表显示当前图表并渲染显示数据的事件“Columnar_Hidden”。


F.3.1.a.Columnar_Show

当用户光标离开指向图表时,让其所有图表进行显示。首先获取所有的“Histogram_Basics”循环执行“Mouse Hover Sphere”。当然也可以获取一个类再去执行“Mouse Hover Sphere”,但是这样必须选择在场景内的类。直接索取所有类相对别叫省事但是比较消耗资源,自行根据情况可进行修改。


F.3.1.b.Columnar_Hidden


  1. 事件输入

    首先需要创建几个输入。

    “Child”用来输入当前子Actor组件。

    "Name"用来输入数据的名称。

    “Y”用来输入子Actor组件的Y轴用于“Data panel”组件组的定位。

    “Name Color”用来输入数据颜色。

    “Data”用来输入数据的具体数值。


  2. 获取Child索引

    通过循环获取“Histogram_Basics”蓝图内的“Child”变量,后续可以通过输入接口的“Child”来获取当前“子Actor”的索引,用来“Mouse Hover Sphere”函数判断是否需要进行隐藏。


  3. 获取数据表时间

    接下来通过“Row Index”变量来获取每个数据标注点的时间,这个在之前说到过。这里所获取到的时间内容是用来对“Data Panel”组件组内容渲染的。


  4. 时间整数转文本获取到数据表时间后,需要对整数进行一次文本转换处理,这里需要注意的是“Minimum Integral Digits”,这个是最小整数位。年份我们肯定是4位,月份与日期为了能够有良好的排版我使用了2位。之后将其复制给“Mouse Hover Sphere”函数用于对“Data Panel”组件的文本渲染。


  5. 设置Data Panel位置与是否执行隐藏

    最后通过输入接口“Y”获取到“子Actor组件”的Y轴位置并用起设置“Data Panel”的Y轴数值。然后通过数据动画函数中的“Sphere New”获取到第几个“Sphere”的Z轴缩放值,经过乘以200运行后我们就能得到当前“Sphere”的所在Z轴位置,但是我们不能让“Data Panel”与其重叠所以还需进行一次加10的运算。这里我已经知道了所有“Sphere”的X轴的位置所以偷懒直接给了一个数值。最后我们通过“Histogram_Columnar”的“hover”值进行“NOT”以后来控制“Mouse Hover Sphere”函数是否执行隐藏。

    这里为各位补充一下怎么才能让系统自动设置"Data Panel"的X轴与Z轴。各位可以自行尝试。

    首先我们需要在“Histogram_Columnar”子蓝图内将“Sphere”创建为数组,通过命中获取到当前“Sphere”在数组中的索引。

    然后再“Columnar_Hidden”事件创建一个整数输入接口用来传输这个整数。

    之后在“Histogram_Columnar”构建脚本时可以创建一个浮点变量,并将“Spline”的样条长度设置给这个变量。然后我们通过输入的整数索引获取到“Sphere Basice”变量的指定数据。接下来我们将样条长度的变量进行除以“2”的计算。最后我们用“Sphere Basice”变量的指定数据减去样条长度的变量进行除以“2”的数值,这样就能得到没一个“Sphere”的实际X轴位置。最后我们在将输入的整数索引赋予“Sphere_new”这样即可自动获取到指定的Z轴数据。


F.3.2. 为子蓝图创建交互事件

接下来要为每一个“Histogram_Columnar”子蓝图“Histogram_Columnar_Child”创建交互事件。


F.3.2.a.事件开始运行

当每一个“Histogram_Columnar_Child”蓝图开始运行时我们都需要先执行这段内容,用来获取我们所需的数据参数。

  1. “Histogram_Columnar_Child”用来获取Y轴位置(非常要注意的是,循环获取的这个“子Actor组件”所调用的子蓝图一定要与当前编译蓝图一致)

  2. “Property Name”通过“Histogram_Columnar_Child”在进行类型转换获得到这变量,用来获取数据名称参数(这里的类型转换也要注意一定要转换成与当前编译蓝图一致的类型)

  3. “Name Color”用来获取数据图表颜色参数(这里获取是确保图表标注与图表颜色都在使用同一个变量即可)。


F.3.2.b.结束光标悬停时(Sphere)

接下来为”Histogram_Columnar_Child“蓝图里的”Sphere“创建一个结束光标悬停时事件并执行”Columnar_Show“。因为是父级事件,所以直接可以进行调用。这样来一来,用户离开任意一个”Histogram_Columnar_Child“蓝图时,其他蓝图均会显示。



F.3.2.c.开始光标悬停时(Sphere)

最后为每一个”Histogram_Columnar_Child“蓝图的“Sphere”添加开始光标悬停时事件来完成光标悬停时隐藏其他”Histogram_Columnar_Child“并获取数据进行渲染。

首先需要一个布尔变量“Name Hidden”,这个变量在之前的“Histogram_Basics”蓝图中的“点击时(Plane)”又所说道,这里再次重新说明下。当用户点击“Plane”时会将对应的“Histogram_Columnar_Child”蓝图进行隐藏。而为了避免在“Histogram_Columnar_Child”隐藏时还执行显示功能,就需要一个变量来对齐进行判断。“Name Hidden”就是这个判断变量,所以这个变量在我们编写“点击时(Plane)”之前就需要在每一个“Histogram_Columnar_Child”蓝图中提前创建好供其调用。

之后通过“Property Name”将指定的数据表列获取到并转换为数组,然后再通过“Row Index”从数组中查找到所需的数据。之后执行“Columnar Hidden”并将对应参数赋予输入接口。


G.UMG


G.1.Histogram_ui


UMG这里这次没有什么过于复杂的功能,具体怎么使用UE的UMG蓝图可以查看我上期教程,这里就不占用各位时间了。


G.1.1.设计器


注意看下“层级”所应用的组件。


G.1.2.图表

分别为“Button_rest”、“Button_left”、"Button_right"调用“Histogram_Basics”蓝图内的“reset”、“rotate_Left”、“rotate_right”事件。以为所有动画效果均在“Actor蓝图内”,所以"UMG蓝图"无需任何动画仅需调用。


H.总结

这次的重点主要如何将复杂并重复的事件拆分并封装成函数,简化事件的同时可重复调用函数。不同蓝图之间如何调用事件。父子蓝图的使用与功能管理逻辑。数据表数据的获取方式。


Powered by Froala Editor

全部评论:0

更多作品

发表评论

取消

点击右上角
分享给朋友吧

分享到

取消

每人每天仅限5票,快给你心仪的作品鼓励的一票。

投票