UE4学习途径
- 官方文档
https://docs.unrealengine.com/4.27/zh-CN/
- 官方在线学习平台视频教程(注意视频下方的cc,点击会有中文字幕)
- 哔哩哔哩
- 相关书籍:完全学习教程,UE4游戏开发入门经典,UE4技术基础
- 系统培训班
- 中国官方公众号
- CSDN技术文章
- 官方论坛
- Reddit论坛网,基本都是英文的
- 谷歌,百度搜索引擎
- Youtube
- QQ群
- UE4百度贴吧
- 知乎(大钊老师)
UE4安装注意事项
- 注意安装前检查Windows常用运行库安装(360软件管家)和DX版本安装
- 再启动器中,可以使用选项配置安装,使用验证确定引擎完整性
- 启动器打开失败很可能是网络问题,打不开就要重复关掉重启实验;
- 最好使用Win10
- 安装根目录下启动是UE4Editor,来自于安装根目录-Engine-二进制-win64目录
- 更改虚幻引擎缓存路径,扩大C盘:类似于着色器等文件都是系统编译放在C盘,久而久之占用C盘,修改后放在工程系统路径中,不仅可以节约C盘,拷贝给他人时别人也不需要重新编译
默认的缓存路径:
C:\Users\admin(计算机用户)\AppData\Local\UnrealEngine\Common\DerivedDataCache
修改方法:
打开目录:E:\UE4\UE_4.25\Engine\Config\BaseEngine.ini文件
将%ENGINEVERSIONAGNOSTICUSERDIR%DerivedDataCache更改为%GAMEDIR%DerivedDataCache
UE4闪退原因汇总
运行虚幻引擎先决条件:
- 最好用Win10系统,如果是Win7,要保证是Service pack1以上;
- 微软运行库合集;
- DX修复工具;
导致闪退的原因:
- 验证完整性,在启动器引擎下拉验证选项中(注意先关闭引擎);
- 检查显卡驱动;
- 微软运行库合集安装,包含一些框架;
- 更改首选图形处理器,最好使用N卡;
- 电脑配置不高,比如独显都没有,笔记本要插电源(避免默认使用集显)
- 注意电脑操作系统;
- 切换输入法为英文;
- 关闭防火墙;
- 停止电脑超频;
- 检查代码,删除素材;
- 关闭全屏模式。
随手笔记
再次添加初学者内容包:AddNew-AddFeatureorContantPack-ContantPack-StartContant
以上Feature表示功能,实际就是新增一个关卡,在一个游戏里边可以有多个关卡,在AddFeatureorContantPack之后选择蓝图或者C++对应的feature就可以;
视图窗口左上角一排红色字体LightingNeedToBeRebulit,是因为如图被移动了,他的阴影等需要重新构建,可以直接点击构建或者展开选择仅构建光照;
对于特别想保存的镜头设置书签的方式进行定位,后边可使用跳转到书签进行操作
- 切换世界坐标系和局部坐标系:
- 虚幻引擎单位是cm;
- 网格对齐,实现精确移动:如精确旋转单次角度,移动距离等。座椅后边还定义了旋转与缩放,注意使用的时候把对应开关打开(高亮黄色)。最右侧为摄像机移动速度。
- 枢轴点:模型的坐标定位源点,当与模型产生位置偏移,可回到3DMax重新设置000,或者使用鼠标中键点击原点进行移动到模型上,再鼠标左键-支点(pivot)-设置支点偏移量(set as pivot offset)
- Crtl+Alt+鼠标左键框选对象;
- 快速复制:Alt+拖动,旋转进行复制
导入资源
- 导入内容:3d模型,纹理,音频;
- 导入方式:导入按键import ;直接把要导入的文件拖到内容浏览器(简单粗暴);
- 引用查看器:大多数资源依赖于一个或多个其他资源,通过对内容浏览器中资源右键引用查看器可以获得其关联资源情况;
项目迁移
- 在内容浏览器选择待迁移项目资源,右键选择迁移(Migrate),在弹出的对话框中决定要迁移的项目,点击确定后指定迁移到的目标位置(必须是Contant文件下的一级目录);
- 只能一个一个文件夹迁移,不能多个文件夹一起迁移;
- 多个资源文件可以一起迁移,但是此时迁移按钮在资源操作的二级目录下;
- 也可进行复制粘贴,但是要注意路径保持高度一致,即复制Contant文件夹下文件夹到我方Contant文件夹下,否则导致材质等关联性缺失。
免费素材获取
- 启动器虚幻商城免费栏目查看免费项目;
- 启动器学习栏:Engine Feature Sampler引擎特性模板也是免费获取的;
- YouTube上搜索Unreal free download/UE4 free project download;
- Bilibili的墨鱼驴肉汤UP主,会转载相关资源;
- 启动器社区论坛中有汇总留言。
主流三维软件模型导入虚幻引擎
1.需要的插件:
C4D与3dMax对应的插件叫做DataSmith
Maya对应的插件:MayaLiveLink,可以实现同步更改
2.传统做法:将模型导出为通用格式,如.fbx .obj .abc
- 网格体分类:静态网格体(不带动画)&骨骼网格体(带动画)
BSP画刷的概述和使用方法
- 什么是BSP画刷:BSP(Binary Space Partitioning(二进制空间分区)),用来搭建基本场景
编辑场景中的几何体。通常意义下,相对于直接创建几何体而言,使用静态网格体是比较好的做法(性能上较优秀)。同时,由于静态网格体要求在引擎外部的3D建模软件中创建,因此可以使用引擎的几何体编辑工具快速的为游戏原型来搭建场景。
从理论上说,最好将 BSP想象为可以在关卡中进行填充并切除空间体积的东西。很久之前,BSP被用来作为关卡设计中的主要构建模块。但是现在,这个角色由静态网格物体来承担,相较而言,静态网格物体远为高效。不过,作为关卡和物体的快速原型化产品的前期应用,以及对于那些无法使用3D建模工具而需要进行关卡构建的人来说,BSP依然很有用。
- BSP使用
在哪里?模式下边的几何体,一些立方体,球体,楼梯等,相当于静态网格;
BSP的模式:存在添加与挖空两种模式,据此可进行布尔运算
注意添加顺序:旧的挖空型不能减去新的添加型,这是层级关系,还要注意不同的几何体不能相减;
有关挖空型与添加型可以进行样式和顺序设置:
为BSP创建对象赋材质:可以创建完成后对单个面一一赋材质;也可以一开始就先选中某个材质,再拖动BSP几何体,则每个面都附上该材质
对于已经创建的BSP,要为所有面赋统一材质,可以选择BSP后在选择中选择匹配对应BSP选中所有面;
模式下的Brush Edit仅对BSP画刷物体生效,对静态网格不生效;
碰撞的设置
- 选中所有的Brush可以在设置栏CreateStaticMesh部分创建静态网格体;
- 双击打开创建的网格体,在细节面板部分找到碰撞,选最使用复杂碰撞(为每个Brush面创建的碰撞)
合并Actor
选中所有静态网格体——窗口——开发者工具——合并Actor——选择生成路径——确定保存
创建地形
1.创建地形面板解析:
填充世界会把组件数放到最大,使用做多的网格数,点击创建即可创建初始地形;
- 初始地形创建完成后即可进行雕刻和描画;
- 雕刻:改变地形顶点位置,可以选择斜坡等进行拾取拉伸,最常用的为:直接鼠标按住向上拉伸,按住Shift向下凹陷;参数面板有更改强度(控制改变率),笔刷大小(控制精雕细雕),衰减值控制缓和过渡(1.0表示所有覆盖顶点同等强度变化,0.x则存在过渡)
- 注意场景要添加方向光等光源开启光照;
- 网上下载灰度图,在PS中设置为灰度并修改为16位通道,保存为raw和png。之后从创建地形栏目选择从文件导入进行创建,设置参数,点击创建。对于细节使用平滑等工具处理。
植被编辑
拖动植被到画刷添加栏目,可以设置一次性刷的数量,大小等参数,然后就能在场景中防止;此时没有碰撞要进行两步设置:首先在植被画刷参数中设置碰撞,然后打开植被的蓝图,添加碰撞体。
光束制作
核心:开启指数级高度雾的体积雾效果;在光源中设置体积散射强度,通过调整光的强度,屋的密度达到要求;
天空球的使用
最为关键的,要在天空球细节面板Default部分,选择上方向光进行关联,然后调整方向光就能变更太阳位置,此处还有云移动速度,光照颜色随太阳高度角度变化等;
获得角色控制权两种方法
- 将角色拖入场景,只点一次(两次选中模型Mesh;一次选中蓝图类),在细节面板输入possess,选择player确定控制权;
- (与第一种冲突,删除角色蓝图对象)窗口——世界场景设置——GameMode——选择准备好的游戏模式(如第三人称)——放置玩家出生点(只能有一个,不然玩家会随机出现)
游戏打包
- 确定操作角色生成位置;
- 确定运行的默认地图是哪一个:关卡编辑器设置——项目设置——地图和模式
- 打包必须软件:VS2017(安装就好)
- 文件——打包工程——可选择开发版还是发布版,选择平台一键式打包;
开门互动
- 给门添加碰撞体,更改为可移动;
- 使用Trigger盒体,选中后进入关卡蓝图添加重叠与离开事件;
- 利用AddActorLocalRotation设置旋转,这里要注意SetActorRotation与之区别;
- 为了避免生硬使用时间轴节点:点击函数fx,右键添加关键帧设置时间与数值,需要几个关键帧就设置几次;选中关键帧节点右键使用自动进行平滑;注意:上方长度要改为我们设置的时间长度;
- 时间轴的使用存在正向play和反向reverse,注意进行连接,同时展开设置目标,将新建轨迹每帧数据连入进行更新,实现缓慢过渡;
创建门的蓝图类
Actor和组件区别、门的轴心点修改
- 创建一个蓝图类,在添加组件栏目添加静态网格,并对其赋予对应的网格体组件进行组合;
- 此处的碰撞触发器叫做BoxCollision合体碰撞;并将其与门放到同一级,避免随门一起动,并且若不和门同一级,开关门也可能检测到重叠事件,产生bug;
- 选中触发器,在细节面板添加事件处理;
- 辨析:setactorrotation表示actor内所有组件都旋转;setrelativerotation设置局部坐标系下的相对位置旋转;setworldrotation设置世界坐标系下的旋转;
- 使用Gate节点:open相当于插入钥匙,close相当于拔出钥匙决定Gate是否有后续执行;当有了钥匙状态之后通过操作Enter往后执行(处于open);有关对Enter的操作可以使用键盘,此时会用到节点Enable Input或者Disable Input,有关玩家控制使用playercontroller;
- 注意与组件有关的事件,可通过这些事件来进行性逻辑操作:
- 使用类型转换cast to,选择对应的选择结果,只有转换成功才向下执行,是一个if语句,可检测判断是否为我们希望的对象来操作;
拾取钥匙
- 制作要是Actor,添加触发盒子生成触发事件;
- 不通蓝图之间通信:比如一个定义在door里边的bool变量,如何在key蓝图里边修改他的值:GetAllActorsOfClass,传出某个类的数组,使用数组操作Get设置index获得对应Actor,再设置Actor下的变量;可以用来做点名系统等;注意使用顺序,先要选择好类型,再使用数组操作的Get节点,有点预编译的味道了;
- Actor消失:Destory;
蓝图通信
用于蓝图数据之间的通信,比如从一个类获取另一个类的变量,并进行一些设置;
- Cast to选择转换的目的,转换成功从As...获得对象,可以对该对象Actor的变量等进行设置,这可以用于蓝图通信;同时Cast to有针对性,只有转换成功才有下一步
- 自定义事件:AddCustomEvent
- 判断一个变量是否有效:Is Valid是一个执行节点,input Object连接待判断变量值是否正确,是否为空等;
- 通过新建变量,选择为蓝图类引用类型建立场景中某个Actor的引用,可使用带问号的IsValid判断是否有效;要使这个变量有效:1.开启睁眼;2.选中建立变量的蓝图开启细节面板;3.选中变量对用吸管,在场景中赋予变量具体值;
- 控制台命令执行Execute Console Command:ce+空格+自定义事件名可以直接进行蓝图通信(比如从蓝图Actor通信到关卡蓝图,在关卡蓝图创建自定义事件,在蓝图Actor调用);
- ForEachLoopWithBreak,使用条件中断循环,比如触发某个事件,或者直接将后继连上break传输到Complete;
- 设置可见性Set Visibility:设置是否可见bool,但是不管是否可见碰撞依然存在;
部分快捷键
- WER切换位移,旋转和缩放;
- Ctrl+Alt+左键框选;
- 视图Front模式下使用中键测距;
- Ctrl+E打开对应Actor或者模型编辑器视窗;
- Ctrl+B找到模型在内容浏览器中的路径;
- 游戏鼠标侧边按键是快捷键;
蓝图的概念汇总
- 函数:一段可以直接或间接被调用的功能模块;可能使用return节点来做输出设置;注意纯函数,对于创建的函数节点可以在细节面板设置,纯函数没有执行流;
- 宏:用于计算,传入对应数值,套入宏进行计算;宏一般在别的蓝图里边没办法获得,是一个局部使用的,还有一种办法是新建蓝图宏库,可以实现全局调用;
- 函数内不能加流程控制;
- 放入到场景中的是类的对象,修改对象参数不会影响类本身,修改类会影响后续放入的对象;因此也就能理解变量类型部分对于对象引用和类引用的区别;
- 层级关系:Object(对象)>actor(演员,可以放到场景中的,有组件,而Object没有,因此actor中有Scene组件,表示位置坐标)>pawn(可控制角色,响应鼠标键盘可被操控,这是与actor的区别)>character(人形角色模板,行走跳跃,飞行等,有角色移动组件)
- 由于actor没有控制权,因此才有了额外采用Enable Input的开关控制,这在Pawn和Character中不是必要的,自带输入控制
- 关卡蓝图实际是actor的子类;
多个角色控制权的切换
- 如何让角色获得控制权:角色细节面板possess选中pawn下设置player;
- 使用游戏模式,利用玩家出生点方式获得控制权;
- 在场景中放入多个角色,并在世界大纲中选中所有角色,将他们拖入关卡蓝图自动创建其应用;
- MultiGate:多个通道的随机,顺序执行等;
- 利用playercontroler作为目标创建possess节点,InPawn连接待控制角色,以此切换控制权,并可以使用setviewtargetwithblend切换摄像机视角(注意连接playercontroller),有一个镜头混合过程;
角色上下车
- 人物蓝图:新建汽车对象引用类型变量,检查有效性之后调用在汽车中的自定义事件上车;
- 汽车蓝图中:给汽车添加触发盒子,重叠时给人物蓝图中的汽车对象引用设置值self,此时通信可使用重叠事件的对象来cast to
- 从上边两个蓝图得知:当人物移动到汽车触发盒子,给汽车变量赋值,此时按键F,调用上车自定义事件。
- 如图,调用上车事件,配合gate节点开始操作,在消息盒子内就是open,离开关闭,防止很远的位置还能操作:
- 此时操控权转移给汽车,但是人物并没有上车:通过给驾驶位置设置组件获得该组件的位置,将人物设置上去,注意使用Transform,但是不要使用到缩放;
- 有可能出现车辆抖动等状况,可能是由于此时人物与车辆之间的碰撞一直在作用导致,可关闭此时人物的碰撞(因为控制权交给了车):Set actor Enable Collision
- 此时任务上车,但不会随着车辆一起动,因为关闭了碰撞,所以要把人物附加到车上才行:AttachActortoComponent(将人物Actor附加到车辆组件:如驾驶位置上定位的组件),注意设置为参考世界坐标
- 下车逻辑就是反过来:1.解除附加:DetachFromActor;2.改变位置;3.恢复碰撞;4.恢复控制权
- 角色下车后,汽车减速功能实现:选择汽车蓝图组件,开启手刹节点(set hand break input),油门输入设置为0.0;
加速,瞬移,多段跳
- 按键改变组件最大移动速度;
- 快速按键瞬移(>=2):使用GetactorForwardVector获取向前向量*瞬移长度+当前位置=瞬移位置
- Actor的摄像机组件视场修改可以获得不同广角下的视野;
- 多段跳:在人物蓝图类中细节面板搜索jump,修改最大跳跃数即可;
使用蓝图接口(相当于自建函数库,事件库)
- 接口实际就是一种函数的函数名,通过蓝图——蓝图接口创建,双击打开给函数命名;
- 所创建的函数interface输入输出可自行创建,只有同时具有输入输出才能当做函数来使用,没有输入,只有输出(或者也没有输出)只能当做事件来使用
- 切换到一个具体的蓝图类,在Classseting右边细节面板可以看到一个Interface,可添加我们创建的Interface,此时左边组件部分Interface部分只有可作为函数使用的部分,其他看作事件的只能输入搜索获得;
- 蓝图接口主要用于实现通信:因为接口可以作为一种库被不同的类包含,只要包含了就可以进行调用,实现通信,类似于一种公共函数库来使用,并且被不同对象包含之后可以产生不同的效果;
拾取物品-射线检测
- 射线检测:LineTraceByChannel 起始点(玩家摄像机世界坐标)getforwardvector获得向前向量*距离+当前位置=终点位置。注意Draw Debug Type表示是否可以看到射出的射线(可选项为None无,For One Farme一帧一条,For During 持续时间保留,在展开位置设置时间)。所谓Channel,在节点中有Visibility和Camare两种,要让射线检测能识别到这个碰撞到的物体,则在待检测物体细节面板碰撞部分开启对应通道,因此要把对应待检测物体相关通道设置为阻挡与射线检测通道一致,就可以进行射线检测识别了;
- 对待检测物体添加自定义响应通道Channel,并把射线检测调整到该通道就能实现阻挡检测了:在关卡编辑器界面Setting——ProjectSetting——Collision——TraceChannel添加追踪通道,默认响应设置为ignore(因为场景中所有的模型,触发盒子都会添加这个通道,只有设置为ignore才不会影响全部,只把对应待检测物体开启即可);
- 创建可以拾取的物体蓝图类:创建蓝图类Actor并赋予对应的Mesh(先选中对应的Mesh,再到蓝图AddComponent中点选,可以看到我们选中的Mesh(尤其是添加骨骼网格,就不是之前使用StaticMesh的方式)),修改其Collision中碰撞预设,选择Custom自定义,在碰撞是否开启选择第四个能够碰撞,通道追踪为阻挡开启检测;
- 骨骼网格(带动画的,洋红色)和静态网格(天青色)
- 新建蓝图接口,建立拾取,开启描边,关闭描边三个函数,不添加输出作为事件来使用;
- 在蓝图类中添加蓝图接口,事件图表调出对应事件;
- LineTraceByChannel输出部分Out Hit可以用break节点分解开获得碰撞到的各种信息,例如被碰撞到的蓝图类Actor,对于这个蓝图类发送消息,即触发Interface中定义的事件,此时就会给我们碰到的Actor发送这个蓝图接口定义的事件消息,该蓝图类若要响应这个消息,前提是自身插入了这个Interface,并以事件方式实现了这个消息的逻辑;
- 骨骼网格设置碰撞:在内容浏览器点击骨骼网格文件,右键选择创建——物理资源——创建,按照默认创建出现橙色图标文件,双击点开可看到对应胶囊体,调整包围整个模型。之后双击打开骨骼网格体文件,将橙色文件对应的胶囊体物理资产附着上(physical部分physical asset添加)
- 蓝图接口的多功能性:同一个蓝图接口事件,在不同蓝图中可以实现不同的逻辑
AI的使用
- 导航网格:AI的移动范围,在放置模式下体积中有一个导航网格边界体积,把他拉到场景中形成一个线框,对其缩放形成AI移动范围,快捷键P可以切换导航网格是否显示;
- 导航网格的静态和动态设置:关卡编辑器中设置——项目设置——导航网格体——运行时——运行时生成(默认静态),采用动态的方式则实时计算,更加符合智能调整;
- AI的随机移动:复制人物蓝图重命名,打开该蓝图删除所有蓝图节点并删除摄像机(AI不需要摄像机,也不需要控制);核心蓝图节点AI Move To:pawn设置AI对象;两种目标,一个是直接的位置,一个是跟踪的目标(playercharater),两者选其一就好;接触半径,靠近多近会停止打钩;输出部分有成功与失败两个出口;可以使用一个事件来驱动这个过程
- GetRandom...获取可导航半径内随机点:以Ai位置为圆心,输入一个半径;
- 以事件设置定时器:连接设置好事件,修改时间,打钩循环,则事件将会在时间内循环驱动,实现连续随机移动;
AI行为树
- 内容浏览器,右键选择人工智能创建一个黑板,一个行为树,右键创建蓝图类在所有类中搜索AIController,并配合之前建立的AI_BP(带AI人物的蓝图Actor)
AIController是AI的灵魂,指导AI操作,是一个控制器;
行为树:AI的功能,行为的逻辑;
黑板:存储变量的地方;
AI_BP:一个执行者;
- 双击黑板打开:创建变量;
- 双击AIController:添加组件(AI感知组件AIPerception,用来感知AI周边),编译后可以在细节面板找到感知配置,添加感官的配置,如视力配置,里边有视线半径决定距离,按归属检测则要勾选中立方等。选择感知组件,在细节面板中下方添加事件:目标感知更新时。这个事件会传入当前视野中感知到的actor(类型是pawn和character的),对这个actor使用castto节点进行判断以进行后续操作,还有一个输出是刺激物,对其使用break进行展开,可以看到很多信息,比如是否成功感知到等;
- 让AI使用AI控制器,或者就是将AI的灵魂赋予AI:打开AI蓝图,选择类的默认值,在Pawn下,修改AI控制器;
- 双击打开Ai行为树:有个Root节点,表示起始出发点,拽住下方放开可以看到一个复合节点用来创建分支的规则:选择表示判断,序列表示执行顺序,则行为的基本规则如下:AI进来是否能感知到,进行选择,感知到了走左边,没感知到走右边
右键Sequence——添加装饰器——黑板,将黑板里边的变量弄过来,对其进行设置,选择下边一侧为已设置一侧为未设置,表示一真一假,修改Observer aborts为Both表示优先级一致,则左侧走了右侧就不能走,互斥;(行为树像是一个大脑中枢的做事逻辑)
- 回到AIController,将感知成功与否的真假传入黑板,供行为树获取:
- 此时是否看到已经在黑板中设置,则根据此在行为树中新建对应的任务,在左侧函数重载中选择接收执行AI(Receive Execute AI),则当这个任务被触发的时候就会执行这个事件,事件执行完成注意使用finish execute节点告知完成执行,才能开始下一次执行,否则就会一直停在那里;
- 此时随机找点任务做好了,把他附加到没有看到玩家的序列节点上。为什么叫做序列呢,因为这里实际可以添加多个任务,依次执行,直到最后一个结束,才会从Root开始重新来一遍,所以一定要有finish:
- 此时最后一步,将行为树与AI_BP通过Controller进行关联,在Controller中:
到目前为止的基本逻辑是:
- 设置AIController,添加感知组件进行感知;
- 将Controller给到对应的AI_BP赋予AI灵魂;
- AIController将感知结果传入黑板;
- 黑板作为行为树所需数据与行为树通信;
- 行为树中根据规则,执行任务;
- 在AIController中使用BeginPlay节点运行我们对应的行为树,则把行为树与AI_BP关联了起来
AI挥拳
- 给AI_BP添加球形触发盒子,使用重叠与结束重叠执行打拳和结束;
- 打拳实际是一个动画播放,也就是说当触发盒子触发就播动画