妄想的咸鱼吧 关注:151贴子:2,416
虚幻4蓝图快速入门(一)


IP属地:安徽16楼2017-03-18 16:11
回复
    序言
    本文依据官方教程总结而来,只是带你对蓝图有一个快速的认识,如果想对蓝图有一个比较深入的了解,那么可以看官方的视频或者是做一些小项目练手,如果你有编程经验的话,上手还是很容易的。
    蓝图快速入门
    什么是蓝图
    虚幻引擎中的蓝图可视化系统是一个完整的游戏脚本系统,其理念是使用基于节点的界面从虚幻编辑器中创建游戏可玩性元素,该系统非常灵活且非常强大,因为它为设计人员提供了一般仅供程序员使用的所有概念及工具。它是一种特殊类型的资源,为关卡设计师和游戏开发人员提供了一种在编辑器中快速创建及迭代游戏可玩性的工具。
    通过使用蓝图,设计人员几乎可以创作任何游戏元素的原型,以及实现或修改这些元素。
    Games(游戏)创建游戏规则,调整游戏条件等。
    Players (玩家)使用不同的网格物体、材质或角色自定义来创建变种
    Cameras (相机)创建新相机视角的原型或者在游戏运行过程中动态地改变相机。
    Input(输入)修改玩家操作,或允许玩家向道具传入输入
    Items (道具)武器、法术、掉落物、触发器等。
    Environments (环境)创建随机的装置或者程序化地生成道具。
    为了对蓝图有一个基本的印象,你可以查看:
    官方快速入门指南
    虚幻引擎快速入门视频教程
    对于程序员来说,我们可以把它理解为一种可视化的高级语言(C#等),它有基本的变量、函数、类型转换,支持继承、多态等。
    蓝图的工作原理
    从蓝图的基本形式上讲,蓝图是针对您游戏添加的可视化脚本。通过使用连线把节点、事件、函数及变量连接到一起,这样就可以创建复杂的游戏性元素。蓝图通过各种用途的节点构成图来进行工作,这些节点包括针对蓝图每个实例的对象构建、独立的函数、一般的游戏性事件,从而实现各种行为及其它功能。


    IP属地:安徽17楼2017-03-18 16:11
    回复
      对比
      UnrealScript vs Blueprints vs C++
      UnrealScript (UE3):
      一种面向对象的脚本语言
      跟C,C++,Java的语法相似,但是也有些不同
      编译成虚拟机字节码
      添加了一些有趣的功能,比如状态(States),定时器(Timer)委托等(Delegates)
      蓝图 (UE4):
      一种面向美术人员和设计师友好的可视化脚本系统
      跟UnrealScript使用的相同的虚拟机
      几乎跟UnrealScript一样强,在某些方面甚至更强
      C++:
      一直是UE游戏编程中的一部分
      跟虚拟机相互紧密地结合在一起
      在UE4里面得到巨大的改进用来让编程人员替代UnrealScript

      蓝图跟c++对比
      蓝图适合快速迭代
      蓝图比原生C++消耗更多的CPU性能
      运行在虚拟机上
      大约比原生C++代码慢8~10倍
      对于大多数简单的事件驱动的任务,你可能并不会发现性能有什么大的消耗
      许多发行的AAA游戏都在使用蓝图(包括Epic自己)
      每帧需要更新的(tick)应用使用原生C++(物理模拟)
      但是,蓝图仍然很合适做原型开发
      可以让设计师在蓝图快速得创建他们所需的原型,然后让程序员把它转换成代码
      这是Epic公司如何使用蓝图的


      IP属地:安徽18楼2017-03-18 16:12
      回复
        总结
        蓝图可以让设计师快速简单得实现想法
        图状结构可以让程序员快速简单得用C++代码实现并优化
        代码可以在编辑器中添加到任意工程中
        快速协作、畅通沟通,不会出现模糊不清的玩法设计。
        个人理解,蓝图系统非常强大,可用于快速原型设计、简单事件驱动玩法的开发,但是如果玩法复杂需要耗费非常多的CPU性能,那么最好把设计师使用蓝图设计的玩法翻译成原生的C++代码,如果本身一些像物理模拟等需要每帧更新又特别耗时的那么需要使用C++来进行开发。
        蓝图类型
        关卡蓝图(Level Blueprint)
        关卡蓝图是一种特殊类型的蓝图,是作用于整个关卡的全局事件图表。关卡事件或者关卡中的Actor的特定实例,用于激活以函数调用或者流程控制操作的形式呈现的动作序列。熟悉虚幻引擎3的人应该非常熟悉这个概念,因为这和虚幻引擎3中的Kismet的工作原理非常相似。
        关卡蓝图提供了针对关卡动态载入、Matinee以及给放置到关卡中的Actor绑定事件的机制。
        类蓝图 (Blueprint Class)
        类蓝图是一种允许内容创建者轻松地基于现有游戏性类添加功能的资源。它是在编辑器中可视化地创建的,不需要书写代码,会被作为类保存在包中。实际上,这种类蓝图定义了一种新类别或类型的Actor,这些Actor可以作为实例放置到地图中,就和其它类型的Actor的行为一样。
        父类
        你可以创建多种不同类型的蓝图,当然在你做这些之前,你需要指定该蓝图的**Parent Class(父类)** 选择继承父类,允许你在自己的蓝图里面调用父类创建的属性。
        下面是你创建蓝图是最常见的父类:
        Actor 一个可以在世界中摆放,或者生成的Actor。
        Pawn Pawn是一个可以从控制器获得输入信息处理的Actor.
        Character 角色是一个包含了行走,跑步,跳跃以及更多动作的Pawn.
        PlayerController 角色控制器
        Game Mode 一个Game Mode 定义了游戏是如何被执行的,游戏规则,如何的分以及其他方面的内容。
        仅包含数据的蓝图(Data-Only Blueprint)
        仅包含数据的蓝图是指仅包含代码(以节点图表的形式)、变量及从父类继承的组件的类的蓝图。仅包含数据的蓝图允许你调整及修改继承的属性,但是不能添加新元素。从本质上讲,这些蓝图是原型的替代物,设计人员可以使用它们来调整属性或者设置具有变种的项目。可以通过添加代码、变量或者组件来将它转换成完整的类蓝图。
        蓝图接口(Blueprint Interface)
        蓝图接口是一个函数或多个函数的集合,它相当于C++中的一个纯虚基类,仅有函数名称,没有实现,该接口可以添加到其它蓝图中。使用具有该接口的蓝图,都一定会具备这些函数。在每个添加了接口的蓝图中,都可以提供接口的这些函数功能。从本质上讲这各一般编程中的接口概念一样,允许通过一个公共接口来共享及访问多种不同类型的对象。简单地讲,蓝图接口允许不同的类蓝图间彼此共享及发送数据。
        蓝图接口的创建和其他类似,可以通过编辑器中的内容创建器进行创建,但它们有一些局限性,因为它们不能:
        添加新变量
        编辑图表
        添加组件
        蓝图宏库(Blueprint Macro Library)
        蓝图宏库是一个存放了一组宏的容器,或者是可以像节点那样放置到其他蓝图中的自包含图表。这些蓝图宏库非常节约时间,因为它们存放了常用的节点序列、及针对执行和数据变换的输入和输出。
        宏会在所有引用它们的图表间共享,但是如果它们在编译过程中是合并的节点,那么它们会自动地展开为图表。这意味着蓝图宏库不需要进行编译,但是对宏所做的修改,仅当重新编译了包含引用该图表的蓝图时,这些修改才会反应在图表中。
        参考:
        https://docs.unrealengine.com/latest/CHN/Engine/Blueprints/QuickStart/index.html
        http://blog.csdn.net/neil3d/article/details/49070135
        http://www.slideshare.net/GerkeMaxPreussner/east-coast-devcon-2014-game-framework
        http://www.slideshare.net/GerkeMaxPreussner/gdce-2015-blueprint-components-to-c


        IP属地:安徽19楼2017-03-18 16:12
        回复
          虚幻4蓝图快速入门(二)


          IP属地:安徽20楼2017-03-18 16:12
          回复
            蓝图用户指南
            由于蓝图就是个可视化的脚本系统,那么一个程序语言中的基本概念也就都存在。下面我们简单来介绍下蓝图中的一些基本概念。
            变量
            概述
            Variables(变量) 是存放一个值或引用世界中的一个Object或Actor的属性。这些用户界面 内部访问,或者通过设置使得可以在外部进行访问, 以便应用放置在关卡中的蓝图实例的设计人员可以修改它们的 值。
            变量显示为圆角方框,方框内包含了变量的名称:

            变量类型
            您可以创建各种类型的变量,包括数据类型的变量(比如布尔型、整型及浮点型)及用于存放类似于Object、Actor及特定类的引用型变量。 您还可以创建每种变量类型的数组。每种变量类型都进行了颜色编码,以方便识别。
            蓝图数组

            和变量值一样,蓝图也可以在数组中存储数据。如果您不熟悉编程术语,您可以把数组想象成为存在于一个单元中的一组变量。
            数组仅能存放一种类型的值。比如,布尔型数组仅可以存放布尔值。
            数组变量包含一个3x3 的带颜色网格,表明它们是数组,不是正常的变量。在没有连接的数组中,其网格的中心是黑的。一旦连接后,整个网格将会可见,如下所示。

            数组索引
            同时需要注意的一点是,数组中的值的索引值是 从0开始的 ,这意味着第一个索引是 0 而不是1。
            流程控制
            概述
            Flow Control (流程控制)使得能在蓝图中清楚地控制执行的流程。 此种控制可以多种形式进行,基于某些值为真的情况来选择图表的某个分支来执行,多次执行某个特定分支,以特定顺序执行多个分支,等等。 默认的流程控制操作包括了分支(if语句),循环(for和while语句),门,及序列。
            开关节点
            开关节点读取数据输入,并会基于该输入值来从匹配的(或可选的默认)执行输出中发送执行流程。 可用的开关有以下几种类型: Int (整型),String (字符串型), Name (名称型),以及 Enum (枚举型)。
            一般而言,开关节点会根据其估算的数据类型拥有执行输入以及数据输入。 输出均为执行输出。 Enum 开关会自动从 Enum 属性中生成输出执行引脚,而 Int, String 及 Name 开关拥有可自定义的输出执行引脚。
            程序中的switch关键字,但是它支持更多的类型。


            IP属地:安徽21楼2017-03-18 16:12
            回复
              标准流程控制节点
              这些节点提供了一系列方法来控制执行的流程

              Branch

              在面对单个 True/False 判定的情况下,Branch(分支)节点是一种创建基于判断的流程的简单方式。 在执行后,分支节点会查找附加的布尔变量的输入值,并在合适的输出节点下方来输出执行脉冲值。其实就是if-else分支。
              DoN

              DoN节点将会 N 次触发执行脉冲。 在达到限制后,它将会停止所有的输出执行,直到脉冲被传入其 Reset (重置)输入。
              例如,您可以启动车辆20次,然后在绑定到 Reset (重置)输入的加油事件被激活前,无法再次启动车辆。
              DoOnce

              DoOnce节点-正如名称所显示的-将会仅仅触发执行脉冲一次。 在之后,它将会停止所有的输出执行,直到脉冲被传入其 Reset (重置)输入。 该节点等同于DoN节点中 N = 1 的情况。
              我们举例来说,您可以对一扇开启的门的节点网络设置DoOnce,这样这扇门将仅仅开启一次。 不过您可以绑定一个触发事件到Reset(重置)输入,这样会导致在触发器被激活时,门会再次打开。
              FlipFlop

              FlipFlop节点取入执行输出并在两个执行输出间切换。 其第一次被调用时,将会输出A。 第二次被调用时,将会输出B,然后再是A,然后又是B,循环往复。 该节点同时有布尔变量输出,使您可以追溯输出A何时被调用。


              IP属地:安徽22楼2017-03-18 16:13
              回复
                ForLoop


                IP属地:安徽23楼2017-03-18 16:13
                回复
                  ForLoop

                  ForLoop节点的工作原理等同于标准的代码循环,将会在开始和结束之间的每个索引触发执行脉冲。就是C++中的for循环可视化版本。
                  ForLoopWithBreak

                  ForLoopWithBreak节点包含了能中断循环的输入引脚,除此之外,它运行的方式与ForLoop节点非常相似。
                  Gate

                  Gate(门)节点用来开启和关闭执行流。 简单来说,Enter输入取入执行脉冲,同时门的当前状态(开启或关闭)将会决定这些脉冲是否从Exit输出中传出。
                  MultiGate

                  MultiGate取入单个数据脉冲并将其传送到任意数量的潜在输出。 这个过程随机按顺序发生,可能会循环
                  Sequence

                  Sequence (序列)节点使得单个执行脉冲能按顺序触发一系列事件。 节点可能有任意数量的输出,所有的输出引脚都会在序列节点一获得输入时就被调用。 它们将总是按顺序被调用,但不会有任何延迟。 对一般用户来说,输出引脚看起来好像被同时触发了一样。
                  WhileLoop

                  只要特定值为 true ,则WhileLoop节点将会输出一个结果。 在循环的每个迭代中,它会查看其输入布尔值的当前状态。 一旦它读取到 false ,该循环中断。
                  函数
                  Functions(函数) 是属于特定 蓝图 的节点图表,该节点图表可以执行或者从 蓝图 中的另一个 图表中进行调用。函数具有一个单一的入口点,由和该函数具有相同名称的一个节点指定, 该节点包含了一个单一的执行输出引脚。当从另一个图表调用函数时,会激活该输出执行引脚, 促使执行连接网络。
                  访问修饰符
                  当创建函数时,您可以指定可以访问及不能访问这些函数的其他对象。这可以通过设置 Access Specifier(访问修饰符) 属性来完成,该属性可以在选中函数的 详细信息 面板中找到。跟C++中一样,有Public Protected Private三种类型。
                  纯函数和非纯函数
                  函数可以是 纯函数 也可以是 非纯函数 。主要的区别是纯函数不会以任何方式修改状态或者类的成员, 而非纯函数可以自由地修改状态。纯函数一般用于 getter 函数 或者仅输出一个数据值的操作符。
                  非纯函数必须通过在事件图表中将执行线连接到函数调用节点来显式地执行。 非纯函数通过使用以下这些方式之一进行指定:
                  在代码中定义的函数的函数声明中指定 BlueprintCallable 关键字。
                  将通过 蓝图编辑器 添加的函数的 Pure(纯函数) 复选框保留为未选中状态。


                  IP属地:安徽24楼2017-03-18 16:13
                  回复
                    纯函数连接到数据引脚上,当需要依赖于纯函数的数据时,编译器会自动地执行这些函数。这意味着 对于每个连接到纯函数上的节点,都会调用一次纯函数 。纯函数通过使用以下这些方式之一进行指定:
                    在代码中定义的函数的函数声明中指定 BlueprintPure 关键字。
                    选中通过 蓝图编辑器 添加的函数的 Pure(纯函数) 复选框。
                    创建函数
                    在蓝图中创建函数
                    在 Graph(图表) 模式,从 My Blueprint(我的蓝图) 选卡下,点击New Function (新建函数)按钮。

                    在蓝图接口中创建函数
                    在 Blueprint Interface(蓝图接口) 中创建函数同在 Class Blueprint(类蓝图) 或 Level Blueprint(关卡蓝图) 中创建函数一样,但是实现是有很大差别的。
                    在 Graph(图表) 模式,从 My Blueprint(我的蓝图) 选卡下,点击New Function (新建函数)按钮。

                    编辑函数
                    一旦创建了函数,您就需要定义其功能。这个过程需要两步:
                    创建必要的输入和输出参数
                    在您的输入和输出之间创建节点网络来定义函数行为。
                    调用函数
                    一旦您创建并定义了您的函数后,就可以在您的事件图表中调用它。要想创建一个调用您的函数的节点:
                    从 我的蓝图 选卡中拖拽您的函数到事件图表内的空白处
                    在事件图表中右击,或者从适当的执行引脚或数据引脚拖拽鼠标来打开关联菜单。在关联菜单中搜索您的函数,然后选中它来添加函数调用节点。
                    https://docs.unrealengine.com/latest/CHN/Engine/Blueprints/UserGuide/index.html


                    IP属地:安徽25楼2017-03-18 16:14
                    回复
                      虚幻4蓝图快速入门(三)


                      IP属地:安徽26楼2017-03-18 16:14
                      回复
                        数学表达式节点
                        概述
                        要想创建一个数学表达式节点,请右击图表并从关联菜单中选择 Add Math Expression(添加数学表达式)... 。

                        数学表达式节点就像一个合并的图表。它是一个独立的节点,您可以双击它来打开构成其功能的子图表。 最初,该名称/表达式是空的。任何时候,当您重命名该节点时,都将会解析新表达式并生成新的子图表。
                        变量
                        变量命名非常灵活,但是记住以下几点非常重要:
                        变量名称本身可以包含数字,但是不能以数字开头。
                        变量名称不能和隐藏的蓝图变量名称一样。
                        确保您正在使用正确的变量类型。比如, boolVar+1.5 就不是一个有效的表达式。
                        运算顺序
                        运算顺序如下所示(按照优先级从高到底的顺序):
                        括号内的表达式
                        阶乘
                        指数
                        乘除法
                        加减法
                        可用的蓝图函数
                        注:可能根据UE版本的不同,支持的函数可能不一样。
                        三角函数 (sin/cos/tan、asin、acos, 等)
                        区间限定函数 (min, max, clamp,等)
                        四舍五入函数 (floor, fceil, round等)
                        指数函数(square, power, sqrt, loge, e/exp等)


                        IP属地:安徽27楼2017-03-18 16:15
                        回复
                          其它
                          因为支持的结构体类型、操作符可能会改变,请以官方文档为准。
                          注释
                          注释 可被直接添加到单个 蓝图 节点上,也可以注释框的形式添加到组相关节点上并提供其功能的描述信息。 它们可以单独以其管理用途来让 图表 更易读懂,但它们也可以用来提供信息,正如添加注释到节点一样,使用注释或注释框可以把文本描述内容添加到节点上。
                          创建节点注释
                          如需直接在 蓝图 图表中添加注释:
                          在节点上右键点击。
                          在出现的菜单中,在 Node Comment (节点注释)文本框位置处输入注释,然后按下 回车 。

                          创建注释框
                          创建注释框很容易:
                          选择一个您想要进行注释的节点组。 您也可以先创建一个空白的注释框,并在稍后对节点附近的注释框进行排列,或者将其作为悬浮注释放置于指定区域。
                          右键点击并选择 Create Comment from Selection (从选择项中创建注释) (如果未选中任何节点则选择 Add Comment... (添加注释...) )。 此时将出现新的注释框。
                          类型转换(Casting)
                          跟C++中一样,可以给一个类型进行类型转换,类似于C++中dynamic_cast的功能。

                          事件
                          Events(事件) 是从游戏性代码中调用的节点,用于启动执行 事件图表 中的一个独立的节点网络 。这允许 蓝图 执行一系列的动作来对游戏中发生的 某些事件做出响应,比如游戏启动、关卡重置、受到伤害 等。您可以在 蓝图 中访问这些事件,以便实现新功能、覆盖或扩展默认功能 。在一个 事件图表 中,可以使用多个 事件 ;但是每种类型的事件仅能使用一个。

                          注意:
                          每个事件仅能执行一个单独的对象。如果你想从一个事件触发多个动作, 您需要线性地把它们连接到一起。
                          示例
                          LevelReset(关卡重置)


                          IP属地:安徽28楼2017-03-18 16:15
                          回复
                            当关卡重新启动时,LevelReset(关卡重置)会发出一个执行信号。当您在重新加载关卡后需要立即触发一些动作时,这是有用的, 比如,玩家已死但不需要重新加载关卡 的游戏情形。

                            自定义事件
                            Custom Events(自定义事件) 为您提供了一种创建您自己的事件的方法,您可以在您的 蓝图 序列 的任何地方处调用这些事件。当您正在把多个输出执行线连接到一个特定节点的输入执行引脚时, 使用 自定义事件 可以简化您图表的节点连线网络。您甚至可以在一个 蓝图 的图表中创建 自定义事件 ,而在另一个图表中调用该事件。
                            创建自定义事件的简单流程:
                            创建并命名 Custom Event(自定义事件) 。
                            设置这个事件应该具有的任何输入参数及其默认值。
                            创建一个调用该自定义事件的特殊函数。
                            输入任何需要的输入参数。
                            创建自定义事件
                            通过右击并从关联菜单中选择 Add Custom Event(添加自定义事件)... 来创建一个 Custom Event(自定义事件) 节点。

                            给这个新事件赋予一个名称

                            在您的新事件的 Details(详细信息) 面板中,您可以设置当在服务器上调用该事件并添加输入参数时,是否将该事件复制到所有客户端上。

                            可以通过New来添加参数,要想改变节点边缘上的这个参数的引脚的位置,请使用展开的 详细信息 面板项的向下和向上箭头。
                            现在,和其他 事件 或执行节点一样,您可以把其他节点附加到您的 自定义事件 的输出执行引脚上,这样当触发了您的 自定义事件 时将会开始执行那个节点网络。 这个 自定义事件 向屏幕输出了一个字符串。


                            IP属地:安徽29楼2017-03-18 16:15
                            回复
                              调用自定义事件
                              您已经创了 自定义事件 及其相关的节点网络,但是和常规的 Events(事件) 不同,没有触发 自定义事件 的预制条件。要想调用您的 自定义事件 ,请右击并从关联菜单中选择 Call Function(调用函数) > [自定义事件名称] 。


                              自定义事件 上设置的任何输入参数在新的节点中都将呈现为输入数据引脚,以便它们可以传入到 自定义事件 中。您可以根据需要使用数据连线把任何数据引脚连接到变量或其他数据引脚上。
                              和常规的 Events(事件) 不同,常规事件在每个图表中每种 事件 类型仅能调用一次;但是您可以在图表中多次调用一个 自定义事件 。这样, 自定义事件 就可以把多个执行输出分支连入到 一个单独的执行输入上,而不需要直接连线。

                              在这个示例中,如果 IsSuccess 布尔变量为 false ,那么将打印一个错误信息。这个图表的功能,和在序列中的 Branch 节点后面连接 Print String 节点的功能一样, 但是它有个附加功能是图表中的其他部分可以使用 Print String 节点,且图表中两个网络部分的彼此位置不必太近。
                              事件图表
                              蓝图中的 EventGraph(事件图表) 包含一个节点图表,该图表使用事件和函数调用来执行动作, 以便对和该蓝图相关的游戏事件做出反应。 事件图表通常用于给蓝图的所有实例添加功能。 这里也是设置交互性和动态反应的地方。 比如,一个光照蓝图可以通过关闭其 LightComponent 及改变其网格物体使用的材质来对于伤害事件做出反应。 这将会自动地为该光照蓝图的所有实例提供这种行为。
                              关卡蓝图 中的 EventGraph(事件图表) 包含一个节点图表,该图表使用事件和函数调用来之行动作,以便对 游戏事件做出反应。这个事件图表用于从总体上处理关卡中的事件,及给世界中特定的 Actor 和 蓝图 实例 添加功能。
                              无论哪种情况,应用 EventGraph(事件图表) 都要通过添加一个或多个事件来作为入口点,然后连接 Function Calls(函数调用) 、 Flow Control(流程控制) 节点及 变量 来执行期望的动作。

                              组件
                              Components(组件) 面板允许组件一创建就添加到 蓝图 上。这提供了一种方法,使得可以通过 CapsuleComponents 、 BoxComponents 或 SphereComponents 来添加 碰撞几何体, 可以通过 StaticMeshComponents 或 SkeletalMeshComponents 的形式添加渲染几何体, 通过使用 MovementComponents 控制运动等。您还可以将添加到 Components(组件) 列表中的组件, 分配给这个蓝图或其他 蓝图 中用于访问这些组件的实例变量。
                              添加组件
                              要想在 组件 列表中向 蓝图 添加一个组件:
                              从该下拉列表中选择您想添加的组件类型,比如一个 **CameraComponent(相机组件)** 。

                              要想通过拖拽并放置方式来添加一个组件:
                              组件也可以这样进行添加,即通过从内容浏览器中拖拽 StaticMesh 、 SoundCue 、 SkeletalMesh 和 ParticleSystem 资源并将其放置到 组件列表中。

                              删除组件
                              要想从 Components(组件) 列表中删除一个组件,仅需简单地右击该组件的名称并选择 Delete(删除) 即可。
                              组件资源
                              要想把一个资源分配给 组件列表 中的一个组件:
                              在内容浏览器中,选择要分配的资源。该资源类型必须和组件类型 相兼容。

                              在 组件 面板中,选择您想将该资源赋予的组件。该组件的详细信息将会出现在 详细信息 面板中。按下 详细信息 面板的 [Asset(资源)] 部分中的 按钮。这样该资源就分配给了该组件。


                              IP属地:安徽30楼2017-03-18 16:16
                              回复