跳转至

3.2 可视化交互编辑器介绍

交互编辑器概览

为什么你要使用可视化交互编辑器?

使用一个东西前,我们应该先问自己一个问题,为什么我们要用它,它能帮助我们做到什么?

首先我们要明白的是,可视化的交互编辑器其实也需要用户对于事物的基本行逻辑有一定的基础了解,比如理解条件的意义,一般来说,一个条件都会导致两个结果,一个是条件达到,另一个是条件没有达到, 这方面的理解有时会让用户觉得,那不是跟写代码一样吗,为什么我要使用可视化交互编辑器呢

关于为什么用户应该使用它,答案很简单,因为它可以帮助用户非常快捷的做到一些,写脚本(代码)需要很大篇幅才能完成的事情

它能为用户做到什么?

  • 鼠标节点 让你能够快捷的设置鼠标点击指定的区域或者模型,来触发后续事件

  • 空间触发器节点 让你能够在人物模型或者摄像机进入某一区域时,触发事件,比如人物走到自动门附近,自动门进行打开操作(这里需要参考动画制作版块),或者隐藏显示某样东西

  • 多人协同节点 让你能够只拖出一个节点,就可以同步客户端和服务器的操作结果,实际应用场景可以是,老师为学生展示操作过程,也可以是多人交互的场景

  • 具体的节点信息,请参照下方的具体节点说明

界面与常用操作

界面布局

image

创建脚本

脚本是通过挂载在场景树节点上运行的。你可以在一个节点上创建脚本,创建后脚本则默认挂在到该节点上,也可以直接创建不挂载到节点上的脚本,具体方法如下:

  1. 在节点上创建脚本

选择节点后,点击上方的添加脚本按钮:

image

或右键点击节点,选择“添加脚本”:

image

在弹出窗口中选择“IVRScript”,再点击“加载”

image

  1. 直接创建脚本

点击左侧脚本按钮,选择“文件”->“新建脚本”后创建开始脚本

image

使用哪种创建方式,我们都可以在文件面板中找到创建好的脚本,并把它拖到任意想要挂在的节点上:

image

逻辑单元与连线

  • 逻辑单元的创建与删除: 打开创建好的可视化脚本,在左侧的逻辑单元处可以快速拖入常用的逻辑单元到脚本中,拖入后点击右侧的删除按钮可以删除对于滚单元。主任务以及初始化节点的创建和删除如下图所示:

image

  • 逻辑连线: 常规的连线方式演示

image

获取节点和属性

  • 获取节点: 直接从场景树中拖拽节点到交互编辑器中即可获取节点,在拖拽期间按住Ctrl拖入可以搜索并调用该节点类型的相关函数:

image

  • 获取属性 直接从属性面板中拖入属性到交互编辑器中,即可对该属性进行设置;按住Ctrl拖入则可以获取并使用该属性的值: image

  • 右键搜索: 鼠标空白处右键,或使用快捷键Ctrl+F,可以通过搜索快速找到想要的可视化脚本节点:

image

  • 连线智能搜索 连线时按下Ctrl,可以出现自动匹配的函数列表,使用该方法创建节点后可以自动连线

image

注释的使用

善用注释的话,可以帮助你分块管理你的逻辑,让它们看起来更清晰,且注释中的节点会跟随整个注释框一起移动,方便快捷,使用方法如下:

右键或使用快捷键Ctrl+F搜索“注释”,打开注释节点,交互编辑器中出现注释框:

image

点击注释框,在属性面板中可以修改注释内容:

image

复制与粘贴

引擎提供了可视化节点的复制粘贴以及剪切功能,以便用户对可视化逻辑块的复用,具体的使用方法如下:

  1. 菜单操作。有两处提供了复制粘贴的菜单操作,分别为右键点击节点触发: image 和编辑菜单展开: image 当复制了对应的内容后,同样的方式选择粘贴,会将复制的内容进行原位粘贴: image
  2. 快捷键操作:
  3. Ctrl+C:复制
  4. Ctrl+V:粘贴
  5. Ctrl+X:剪切 该方式粘贴时的位置是基于鼠标位置来计算的,并非原位粘贴。

复制粘贴功能同样支持逻辑块的操作,如下图所示: image 框选要复制的内容,执行ctrl+c复制内容,然后移动鼠标,执行ctrl+v粘贴内容,结果如图所示: image

复制粘贴同样支持跨脚本的操作 跨脚本的操作与同脚本操作一致,且增加过滤机制,对于在目标脚本中无法解析的复制内容,在目标脚本中会体现为**未知节点**,如下图所示: image 对于未知节点的处理,请先删除,再重新处理对应的逻辑。

画布与快捷操作

  • 左键:选择、框选
  • 滚轮键按下: 平移视图
  • 滚轮:视图上下平移
  • Shift+滚轮:视图左右平移
  • 空白处右键: 打开函数搜索页面
  • Ctrl+滚轮: 视图缩放 ,视图缩放的锚点根据鼠标悬浮的位置来定

交互调试方法

当你的脚本不能正常工作的时候,你可以参考本段对你的脚本进行调试

  • 首先 在你制作脚本的时候,应该保持较高频率的测试(开启场景看你的脚本是否达到了你想要的效果),而不是一次性制作很大规模的脚本再开始运行找错

  • 其次 如果你忘记了进行中途的测试,已经形成了较大规模脚本,这时要想办法去除一些逻辑流程,断开一些连线,再对简单的逻辑进行测试(这也是为什么推荐使用任务拆分节点,不要把所有逻辑都连成一根线)

  • 最后 当你大体定位了哪一个逻辑流程有问题后,你可以尝试加入Print节点(下图),继续输出打印信息,查找具体的问题节点,比如你的流程节点现在有ABC3个,顺序是A->B->C,如果你不确定问题出在哪里,可以在AB和BC之间都加上Print,随意打印一些信息,再运行场景时,观察你的打印信息是否被输出, 比如这里你加在AB之间的信息打印了出来,但是BC之间却没有打印,那么就说明BC的流程没有走通(很可能是因为条件不满足造成的) ,这时你就应该有针对性的去看节点B为什么没有满足,进一步锁定最后的问题点

image

  • 默认的输出信息为Null,自定义的输出信息则需要用到变量,下面会对变量的创建和使用有介绍

逻辑单元功能介绍

节点端口说明

image

以任意节点为例,整个节点可以按照左右和上下来进行整体的功能区分: + 首先从左右分开的话,左侧是都是输入部分,右侧是输出部分 + 从上下分开的话,上面是流程的控制,下面是变量的控制 + 从图形区分的话,三角端口代表流程的连接,圆圈代表的是各种变量(值)

主任务节点

image

功能 : 主任务节点会在场景运行时,每帧循环调用,一般大部分的功能都需要连接到主任务上

初始化节点

image

功能 :初始化节点每次初始化时仅运行一次,可以将只需执行一次的功能连接到该节点上

任务拆分节点

image image

功能 :将本来的任务线分割为多个子任务,任务数量选中节点后,可以在属性面板中调整,需要注意的是子任务的执行顺序,是从上到下的,0,1,2...,此举的意义在于对用户的操作逻辑进行分流处理,否则都连成一条线的话,后面再看这个脚本就很难理解了,另外从布局的层面来讲,也更加方便

### 任务组合 image

功能 :此功能并不复杂,只是同时判断几个条件是否成功,都成功后,才会触发后续的流程,需要注意的点是,一般组合判断都是放在流程的最后(拆分任务的话),这样可以先得到正确的条件结果后再进行判断。在交互脚本中的使用方法如下:

image

上图中展示了,在鼠标拖动的流程下,检测鼠标是否按下,并结合是否按下了W键,如果两者都满足的话,我们就输出一个”Null“信息,比较常用的用法还有检测是否几个按键都同时按下了,或者配合鼠标拣选的结果可以创作出一些独特的组合模式

流程控制节点

image

功能 :控制该节点(后面)的流程是否执行,如果执行,是否只执行一次,需要注意的一个特别典型的误用就是,把按键接在这个控制节点后,并且只执行一次,因为该节点只控制从这个节点开始之后的流程,所以你即便没有按下键盘,也算是一次执行,所以你应该做的是,把按键的节点放到控制的前面,如果你的本意是只响应一次按键的话,并且将“只执行一次”设置为真

键盘触发器

image

功能 :响应键盘按键输入,点击“键值”并按下键盘上的按键可以选择想要响应的按键。右侧输出节点中,“按下”表示按下按键的第一次响应,“按下保持”响应按键按住的操作,“释放”则响应你按键抬起的瞬间(也只响应一次)

鼠标触发器

image

功能 :处理鼠标按键输入,点击”键位选择“可以选择键位(左键,右键,中键)。拣选节点用于连接网格实例(MeshInstance)类型的节点,连接后只有当鼠标拣选到物体时才相应对应的按键,也可以为空(即只响应鼠标按键,不拣选任何物体)

如何使用鼠标节点实现点击模型或区域触发特定事件

  1. 在一个新的3D场景中从资源库中拖入一个立方体:

image

  1. 选择一个节点创建一个可视化脚本,从逻辑单元拖入主任务和鼠标触发器,从场景树中拖入立方体节点

image

  1. 连接节点:

image

  1. 将”平面“节点的”可见性“属性拖入可视化脚本,勾选”取反“,连接到鼠标触发器的”单击“之后:

image

  1. 运行场景后,可以看到如下效果:点击立方体,平面的可见性发生切换

空间触发器

image

功能 :空间触发器的使用方法比较类似于鼠标拣选的不可见模式,其中最大的不同在于,我们不是用鼠标触发,而且判断一个物体是否进入了该区域(比如摄像机或者人物的角色) image 点击选中空间触发器节点后,右侧属性栏中也可以设置被触发区域的属性,如果在这里设置的话,类型将被限定为Area的节点类型(其他类型的节点都不能选择),这样可以降低用户错误设置节点的可能性,如果同时设置了节点上的可视化参数(Area节点)也设置了右侧的属性(被触发区域),那么将以右侧属性为主,因为右侧属性的设置保证了节点选择的正确性 节点上的可视化参数(Area节点),可以选择Area以外的类型,比如MeshInstance,选择后,我们会为用户自动生成一个匹配的Area(如果节点下的子节点不是Area的话)

在移动了空间触发器指定的节点后不需要重新指定节点,引擎会自动的调整节点路径来保证空间触发器的正常使用。

手柄射线触发器

handle_triger

功能

  • 用于在场景中存在VR相机节点时,定义VR手柄射线和按钮事件的定义。该触发器必须先下载安装“VR相机”插件,支持头盔和大屏模式下用手柄射线触发,也支持PC模式下用鼠标模拟手柄进行射线的交互。

vrhandleRayTrigger

参数介绍

下面按照端口编号来介绍各参数的意义。

  • 1.由前面模块流入到当前模块。

  • 2.手柄键位:下拉选择形式,目前提供扳机键和握持键两个选项。

  • 3.作用节点(请确保添加物理碰撞体):请拖入一个节点,一般为网格类型。使用者需要自己添加碰撞体,程序会根据传入的节点自己去寻找碰撞体。

  • 4.是否在按下时拖动拣选节点。

  • 5.进入:两种情况。在有拣选节点时,射线进入拣选节点会触发;当无拣选节点时,每次进入一个新的碰撞体就会触发。

  • 6.离开:两种情况。在有拣选节点时,射线离开拣选节点会触发;当无拣选节点时,每次离开原来的碰撞体就会触发。

  • 7.按下:两种情况。在有拣选节点时,射线指在拣选节点上按下所选键位会触发;当无拣选节点时,每次按下所选键位就会触发。

  • 8.释放:两种情况。在有拣选节点时,射线在拣选节点上按下所选键位后释放会触发,当无拣选节点时,释放所选键位就会触发。

  • 9.长按:两种情况。在有拣选节点时,射线指在拣选节点上并长按会触发,射线离开拣选节点不会再触发;无拣选节点时,长按会触发。

  • 10.无操作时:在6-10不触发时程序从这往下走。

  • 11:是否按下:指定按钮是否被按下。

  • 12:拾取对象:射线检测到的碰撞体对象。

使用演示

1.首先搭建如下测试场景,节点树如下: imageCover 注意,射线是通过碰撞体来检测的,请将需要与射线交互的物体生成碰撞体。

2.为场景根节点生成一个可视化脚本: imageCover 可以看到,左侧有一个VR手柄触发器的逻辑单元,拖动即可使用。

3.接下来,设置其手柄键位,作用节点,是否按下时拖动的选项,做一个简单的交互。 imageCover

4.运行场景,我们可以使用射线拖动设置的节点。 imageCover

5.使用不同的输出端口来实现复杂一些的交互。 imageCover 这里我们根据手柄的触发不同去实现立方体的颜色变化,射线进入立方体设置为红色,离开设置为白色,按下按钮设置为绿色,松下按钮设置为蓝色。

6.运行场景,可以看到是与我们脚本逻辑一致。 imageCover

7.该逻辑单元演示到此结束,体验更多的交互,请下载插件自行尝试。

VR手柄模型替换

功能

替换手柄模型。该触发器同样需要先下载安装VR相机插件。

参数介绍 imageCover

  • 1.需要替换的手柄模型

  • 2.要替换哪一个手柄,左右手柄可选。

  • 3.需要重置手柄模型时设置为真。注意,一旦此参数设置为真,则设置的新模型不会起作用。

使用演示

1.使用VR手柄触发器的演示场景,在根节点上创建一个可视化脚本。 imageCover 在左侧可以看到其逻辑单元。

2.拖动一个VR手柄触发器和一个VR手柄模型替换的逻辑单元到场景中,并设置新模型。 imageCover 当按下扳机,左手柄模型将被替换。

3.运行场景如下: imageCover 在场景中有一个绿色的长方体,我们按下手柄扳机键,会将左手柄模型替换成绿色长方体。

4.那么如何将模型还原呢?按照下面脚本中的逻辑可以实现将手柄模型还原。 imageCover 在模型替换里设置是否重置为真,按下手柄握持键的时候触发。

5.点击运行结果如下: imageCover

计时器

image

功能 :于指定的时间到期后,触发指定的事件。手动设置计时秒数后,将需要触发的事件连接到”激活“端口后,当计时结束后即可执行之后的功能。如果想要循环计时,则将”循环“的值设置为”True“。在交互脚本中的使用方法如下:

image

上图实现了按下按钮后,延时1s后输出一个”Null“信息的功能。如果将”循环“的值改为”True“,则按下按钮后,每隔一秒就输出一个”Null“信息

重置场景

image

功能 :将场景初始化为刚加载时的状态。注意,如果修改了材质则不会对材质进行重置,因为材质是独立存在的文件(相关内容可参考材质教程部分)

切换场景

切换场景

功能:从当前场景切换到指定场景,在”场景路径“属性中输入场景所在的路径即可指定想要切换到的场景。场景路径可以通过在文件面板中右键场景文件(.scene后缀),点击”复制路径“快速获取,如下图所示:

切换场景

下图所示脚本实现了点击按钮后从当前场景切换到2D场景,并在切换成功时输出一个”Null“信息的功能:

切换场景

多人协同

image

上图展示了一下多人协同的大体功能,触发是使用的鼠标的不可见Area触发,触发后播放了一段位移动画,可看到两端是同步进行的

功能 :对多个客户端(使用了相同脚本和资源的)进行同步显示处理,目前同步的属性包含,空间位置姿态,显隐,albedo颜色和纹理

动画播放

image

功能 :对指定的动画播放器节点(AnimationPlayer节点)中的指定动画进行触发播放,可指定其播放顺序(正向或者逆向播放),也可以指定是否循环播放,也能在动画开始和动画结束的瞬间指定想要进行的后续处理流程。使用方法如下:

  • 点击脚本中的动画播放器节点,在属性面板点击”指定“,然后在弹出的节点列表中选择动画所在的动画播放器节点:

image

image

  • 指定节点后,在可视化脚本中点击”动画名称“,即可指定对应的动画片段:

image

双击观察对象

image

功能 :将想要观察的节点(必须为MeshInstance)连接到”观察对象“,运行场景后双击对指定的对象进行观察,用鼠标中间拖动移动视角。在脚本中的使用方法如下:

image

运行效果如下:

image

函数,变量,信号的用法

变量和函数(中级内容)

除了一般的连线方式使用我们的可视化脚本外,我们还可以将处理的逻辑内容进行封装,这部分一般适合有一些编程基础的人继续学习(也仅仅需要入门级的编程理解就可以了) 所以这里并不是介绍变量和函数是什么,而是介绍如何使用它

变量

我们之前在任务组合节点中用到过变量,它的作用主要是为了记录和中转我们需要用到的一些值。比如有流程A和B,流程B需要对一个变量进行判断,那么这个变量可以在流程A中获取。

变量的添加

image

变量的添加,如上图所示,在左下角的自定义单元的标签页中,可以点击加号添加变量

变量的类型

image

添加后的变量都是无类型的,需要我们鼠标右键进行编辑,可以设置类型和初始值,变量的名字可以通过单击左侧的列表进行修改

变量的获取和设置

直接拖拽出来的节点是获取变量的节点,而要设置的话则需要按住ctrl+拖拽

函数

image

从图中我们可以看到,如果你使用了函数进行封装的话,那么你的逻辑将不用都写在一起,可以分块处理,这样加上注释(comment)以后,看起来就会更加的清晰,也更方便日后的修改和理解

添加函数的细节

image

当你点击了添加函数后,和变量不同,函数的主体节点就已经被自动放置到编辑页面上了,而当你需要调用它的时候,你可以从左侧列表中,拖出,连接到你想要调用的流程位置即可

信号的用法(高级内容)

这里为什么归集到高级内容是因为,上面的变量和函数,稍微接触过程序的人,应该都知道是什么东西,但是信号则不一样,信号的话,应该属于中级的程序才理解比较深刻的东西

这里不会对原理进行详细的解释,但是会大概的说明一下它在引擎中的用法 ,在我们的引擎中,有一些节点类型,比如Area类型,当我们在场景节点树中选中后,我们可以在上面的节点分页里找到此类型支持的信号,比如其中的mouse_entered,顾名思义,这个信号就会在鼠标进入Area时触发

image image image image image image image

从上图我们可以看到,如果选择了连接该信号,那边则会自动在脚本中,加入该信号的节点,我们可以直接在信号后面加入我们想要处理的事件,这里是输出了一些信息, 信号的逻辑流程也是可以作为单独的流程块来处理的,不需要连接到主任务的后面

手动添加自定义信号(进阶内容)

此内容只建议有较好编程经验的用户学习

除了引擎节点自带的信号外,我们还可以自定义一些信号,用于逻辑模块间的跳转处理,这样也有利于逻辑流程的分块,但是分块的同时,也要求用户对于逻辑的理解更加的深入,否则看到四处分散的逻辑可能感觉到更加的不适应

image image image image

图中展示了手动创建自定义信号的流程,运行后,我们按下r就会触发该信号,与该信号关联的函数也会被调用 这里详细拆解一下创建的过程:

  • 首先单击信号旁边的加号,创建我们的自定义信号new_signal(名字可以根据需求更改)

  • 在激活主任务后面(因为只需要绑定一次,不需要在循环中一直绑定),链接connect节点,进行信号的绑定,绑定节点的信号参数是字符串,我们输入new_signal即可,重点是下面两个参数,代表了你要把该信号绑定哪个节点的哪个函数上,我们使用get self函数获取当前脚本的节点(也就是你最开始添加脚本的那个节点,在这里就是场景树的根节点)

  • 接着需要指定函数,函数我们也是自己创建的test_signal函数,创建的函数都属于该脚本的节点,所以和self的节点是匹配的

  • 最后在test_signal中处理我们需要的逻辑就可以了

总结

可视化脚本有很多的创作可能性,上面仅展示了最关键的入门技术,用户还可以多加摸索,就能写出更好更强的脚本