要求

大作业+各课程课后小作业
自愿完成提交
大作业:基于UE5 FPS模板,
缺勤超过了两次无法获得,每次上课不小于30min
QA问答通过
鼓励分享笔记

UE入门

了解和熟悉UE的基本知识和方法论

UE学习途径和方法的介绍
UE编辑器使用和编程技巧
UE引擎工具了解
源码编译UE5,新建一个C++工程,进行简单场景编辑和工程设置
编译并构建安装包,能够在安卓平台游戏安装包

程序:游戏性、周边系统、工具、性能分析、引擎
美术:原画、建模、地编、动画、特效
策划:数值、关卡、系统、剧情、战斗
其余:音频、安全、运营、发行、账号

游戏引擎简介

什么是游戏引擎?
游戏引擎:专门为游戏而设计的工具及科技的集合
游戏由数据驱动、可重用、不包含游戏内容
特性:通用性与偏向性、可扩展性、完善工具链
游戏引擎架构:
游戏子系统(动画、渲染引擎、游戏基础引擎、物理引擎、资源管理)|世界编辑器|工具
核心系统
平台独立层
第三方SDK
OS
驱动
硬件
常见的游戏引擎有哪些?
UE:
渲染品质高,电影级别PBR渲染,先进的着色模型;美术制作有成熟的美术资产制作管线
C++与蓝图:性能与可视化编程并重
开发周期友好:例如有基于射击类的GamePlay框架
跨平台:移动、主机、PC、VR
开源:有利于技术提升和定制化改造
Unity:
一些手游
CryEngine:
户外的森林、植被有优势
开源
德国引擎
孤岛惊魂
Open 3D 引擎:
较新的开源引擎
Source2:
2015年起源2,从Quake发展而来,未开源
寒霜引擎:
EA内部引擎,战地、星球大战、FIFA
顽皮狗、R星、育碧各自自研引擎
IW Engine
动态面光、布娃娃
游戏引擎渲染:
Deferred和Forward
书籍:Real-Time Rendering
GAMES101 + 202
Mobile游戏渲染:
手机端的GPU和CPU共享主内存,但GPU上仍然有少量紧张的片上内存,但片上内存处理速度快
主要在于芯片和带宽差距大,必须分片(Tile)
分成一格格地进行渲染
Immediate Mode Rendering
注意利用片上内存(显存),而非主存和片上内存(显存)交换
Tile Based Rendering
Tile Based Deferred Rendering
游戏引擎物理:
Havok,被Intel、微软收购,CPU友好
PhysX: 被NVIDIA收购,GPU友好
Bullet:最早开源,用于GTA5,荒野大镖客
物理引擎包含的内容:碰撞检测、动态约束、刚体物理、车辆物理、布娃娃系统
UE内部有Chaos物理引擎,用于实时电影视效级的破坏,破坏都是预处理好的

UE介绍

UE引擎是什么样子?
学习UE该如何入手?
2.1 背景介绍
1998年UE1
03UE2
06UE3
2012腾讯投资
14UE4
21UE5
每次更新伴随着游戏的推出
Tim Sweeney
学习资料:UE Youtube官方账号和B站
知乎:虚幻引擎
2.2 Launcher
可以从Samples的示例入门,MarketPlace是商城
Library
Windows 3歌
2.3 Editor
不仅是一个世界编辑器、管理整个游戏资产数据
全英文,然后不要写test
MyProject.uproject工程文件
Target.cs游戏设置,编辑器跑的设置
Build.cs一个DLL
Play In Editor
Platform上打包
游戏世界编辑器的典型功能:
地图关卡的创建和分层
可视化游戏世界
File new level创建地图
QE升高或降低视角,选中物体按F聚焦在所选物体上
调整相机速度 Camera speed
下拉小三角,书签功能,记录相机视角朝向
Game View隐藏线框
ctrl多选和Show中,每个地图也能单独隐藏
物体都能在面板上搜索,加号或减号排除?
片选,顶视图
透视视图,ctrl+alt区域框选
选中物件后,物件有属性,坐标位置、材质、模型等
世界坐标系和局部坐标系的切换,地球图标和小Cube图标
End:中心贴地,alt+end:轴心贴地
shirt+end:碰撞盒贴地

快速迭代:
世界编辑器在游戏子系统的上层,所以可以直接Play in Editor
Volume
空气墙或触发器?
光源
直接光、点光源、面光源
Content Browser:
资源管理
Content目录下文件结构与Windows资源管理器磁盘结构一一对应
非UE资源不要放入
使用资源迁移工具来保证内部资源之间的相互引用关系不丢失
Asset Actions

Derived Data Cache
导入数据的二次加工,压缩贴图、Shader code、Optimized meshes
DDC转化为不同平台的表示
资产命名规范,什么类型资源加
ue4-style-guide命名规范文档
Project项目结构:
Project-Levels-Sub-Levels-Actors-Component
了解哪些是临时文件夹
World:
主关卡
Level:
关卡是用户定义的游戏区域

Actor:
可放入关卡中的对象都是Actor
Actor是支持三维转换的泛型类,C++AActor基类
Actor里真正有功能的是Component,

Project工程设置:
World Settings:游戏地图,GamePlay相关设置
Project Settings:在哪里打包,什么输入
工程每一项都要慢慢看,看明白
打包成安卓包,Android和Android SDK版本
Android Studio安装即可

UE源码:
Epic和Github绑定,选UE5.4版本
首先搞清楚UE的启动,pre_init,post_init
感兴趣哪个模块就看哪个模块
运行Setup.bat下载依赖文件
运行GenerateProjectFiles.bat生成工程文件
生成项目文件后,编译通过UBT完成
UBT调用UHT预处理头文件,解析头文件中引擎相关类元数据,产生胶水代码
调用特定平台普通C++编译器,正式开始编译
工程目录结构:
最重要的是Templates
/Engine和/MyProject
/DDC和/Intermediate可删除
/Plugin扩展
build.cs里修改配置
模块:
Developer
Editor
Runtime
ThirdParty
Plugins
Programs
Module依赖关系:
Runtime不能依赖于Editor和Developer
Plugin之间最好不要互相依赖
Engine模块游戏类和引擎框架类(Game Mode)
UMG:UE UI模块
Slate和SlateCore底层UI模块
Core模块:基础功能
UE的main loop在LaunchEngineLoop.cpp

UE编程技巧

开发新游戏从0开始吗?
UE用什么语言来编程

3.1 游戏框架
Game中定义GameMode和GameState,游戏模式类负责正在进行的游戏规则
游戏状态:全局,关于游戏进行到哪里了
玩家状态:
PlayerController和AIController
Pawn为占用的角色,是Actor的一个子类,充当游戏中的生命体
Character是Pawn Actor的子类,用作玩家角色
Controller、Camera、Character
3.2 蓝图与Lua
蓝图为UE写的一个可视化编程,UE蓝图交给虚拟机执行
Level Blueprint
自动创建,每个Level一个
生命周期是整个关卡存在的时间
监听Level级别的事件
BLuePrint Class
自己可以随意添加,也可以继承C++类
蓝图里有一系列事件
Blueprint与C++之间的成员变量反射系统,蓝图打勾Use Offset
C++和蓝图之间可以相互函数调用
BluePrint容易形成蜘蛛网
使用原则:
用于数值配置
用于简单的效果展示
用于特别简单的逻辑,比如代码不超过简单的范围
Lua
slua和unlua,通过unreal的反射能力,导出蓝图接口和静态C++接口给lua语言
支持Lua到c++
3.3 C++
在UE里通过C++类向导创建
T-模板类的前缀
U-继承自UObject的类前缀
A-
不建议使用C++原生类型,基本能用UE提供的类型,就用UE提供的类型
例如UObject
C++调试,正常Debug:该配置在调试配置中同时构建引擎和游戏代码, DebugGame,Development, Shipping
要有一些define宏
OptimizeCode = CodeOptimization.Never
#ifdef clang
Android平台机调试
可以直接用AGDE插件

引擎工具

了解和学习资料
日志
UE_LOG()
可视化日志
UE_VLOG
游戏运行~键打开控制台输入窗口,Mobile使用四指同时滑屏操作
可以输入
Stat FPS
Stat Engine

学习资料:
Youtube B站 知乎
官网主页 论坛 WIKI 问答中心(UDN为公司支持)
官方文档 资源文档 AIP
GitHub 商城, Launcher

-----------------编译源码
绑定账号
git clone
git checkout
运行setup.bat
运行generate生成工程文件,2022编译运行

游戏模式

好游戏和精品游戏

精品游戏 = 仿真 + 抽象

什么是游戏模式?
游戏世界里组织数据和运作规则的方式
即考虑这些物体有什么共同点?什么不同点?如何抽象?
世间万物以什么规则运行?
数据如何组织、描述?

UE模式框架

万物之源:UObject
元数据、反射生成、GC垃圾回收、序列化、通用的属性和接口
A开头,U开头,F开头等,都是虚幻C++规定的前缀

物体的表达:Actor + ActorComponent
EC架构(Entity-Component Framework)
一个实体和多种能力组合的设计模式

  • SceneComponent赋予Actor空间变化信息

FTransform:Location、Rotation、Scale
即Actor,身怀其Component,为玩家上演精彩的游戏

世界的表达:UWorld + ULevel
平行世界:GameWorld、PIEWorld、PreviewWorld
关卡构成:主干卡PersistentLevel + 子关卡
关卡加载:LevelStreaming流式异步加载

  • WorldPartition(UE5)
  • WorldComposition
  • LoadByLogic
    关卡大小和加载距离:LevelBounds和StreamingDistance分层
    关卡蓝图LevelScriptActor:定义关卡规则

世界之上:UGameInstance + UEngine
UGameInstance:信息存在于整个游戏生命周期,不随着地图的切换和销毁,非常适合非业务逻辑的全局管理操作,如全局UI、设置、预加载
UEngine:管理UGameInstance,拉起游戏重要流程<-有一些重要函数

UE游戏模式中的重要对象

AActor:游戏中最重要的实体
根组件RootComponent提供世界变化信息
Actor作为网络同步的基本单位
标志所有权的Owner指针
标志本地权限的Role枚举

Actor生命周期:
关卡内摆放的静态Actor
SpawnActor创建的动态Actor:本地Spawn;网络序列化
可查阅UE文档的生命周期示意图

重要生命周期函数
BeginPlay,EndPlay,Tick(时间滴答,即帧),每一帧都要处理相应的逻辑,但也不能过多的放在Tick中处理导致处理时间延长而反映出卡顿的情况?

EndPlay后有PendingKill标记,GC完成收尾工作,注意有效性的判断

APawn:可操控的棋子
APawn继承自AActor,最重要的是可以被Controller控制,基础的输入、移动框架支持

APawn常用派生类:
ADefaultPawn:简单球形碰撞、简单外显、简单移动组件、基础的键盘手柄映射
ASpectatorPawn:去掉外显,移动组件替换成忽略时间缩放的USpectatorPawnMovement

ACharacter:人形角色
近似仿真人形的胶囊体碰撞盒UCapsuleComponent,在保证一定真实性的同时,节约性能
骨骼模型:动画蓝图赋予人物生动表现
人物移动组件:配合胶囊体完成多种仿真移动计算;提供Custom自定义移动模式供扩展;网络游戏移动同步架构-主控端预表现,服务器端校验,模拟端预测

AController和APawn双向奔赴
Possess和PossessedBy,从此你就是个有主的Pawn了
Controller、PlayerState指针赋值
网络游戏中Role的改变

APlayerController:操控APawn
UInputComponent绑定输入映射
APlayerCameraManager:通过ViewTarget上相机臂作用后的UCameraComponent计算相机位置
AHUD(heads-up display,头显):和UI的区别是不可交互,逐渐被更灵活的UMG取代
网络连接所有权:注意仅在主控端以及服务器端存在PlayerController

AGameMode:游戏模式
仅服务器拥有,掌控整体游戏流程
定义游戏模式用的基础类型
纯服务器逻辑的运作
AGameModeBase是所有GameMode的基类
AGameMode是AGameModeBase的子类,更适用于标准对抗类游戏,如多人射击游戏

AGameState游戏状态
所有端都共享的游戏数据
也存在一个AGameStateBase

APlayerState
所有端都共享同步的游戏数据,PlayerState(所有本地玩家的数据)、Character、Controller的职责区别

官方FPS示例Demo缺陷:部分没有存在网络同步
PlayerController只做了输入映射配置

Character输入绑定行为有跳跃,移动,看
Character创建默认组件

拾取物Overlap交互

武器组件

UE的C++规范

通用代码规范

代码规范:

  • 一系列该语言编写的指导方针
  • 覆盖缩进、注释、命名、空格使用、换行等等方面
  • 由团队/组织/公司制定

作用:

  • 代码需要长期维护,无论是交给自己或是别人
  • 一致的风格降低团队其他成员阅读成本
  • 降低复杂度

命名例子:

格式:
缩进 4空格
换行,用空行将代码片段分开
if
endif 宏

UE5的C++代码规范

可以查阅UE官方开发文档
命名:

  • 变量名通常大驼峰式,bool类型须加b前缀
    开头字母:
  • T:模板类
  • U:继承自UObject
  • A:继承自AActor
  • S:继承自SWidget
  • I:抽象接口类
  • E:枚举
  • b:布尔变量
  • F:其他类

引用传入可能修改的函数变量:加Out前缀
bool
TCHAR
int8~64及uint64
float
double
PTRINT

UE中的uint8 bNetTemporary:1,冒号1代表只用一个bit

基础类型:uint64等
字符串类:使用UE定义的FString/FText/FName/TCHAR等
容器类:避免使用STL,使用UE定义的TArray/TMap等

命名空间

  • UnrealHeaderTool仅支持全局命名空间的类型
  • 尽量不要在命名中使用

C++11:

  • 使用nullptr表示空指针
  • Lambda函数须明确指出返回类型
  • 不要使用auto,除了在Lambda函数、迭代器声明、模板中类型推导(即IDE不一定能解析出auto类型)

可以借助辅助工具,标注出不符合规范的代码

UE5中的标识符

Metadata Specifiers:如UCLASS、USTRUCT
大钊视频
https://github.com/fjz13/UnrealSpecifiers/blob/main/Doc/zh/Main.md

UMG系统

UE中的UI实现

UI是用户界面的缩写,指的是用户与设备、软件或应用系统进行互动的界面。UI设计的目的是让用户能够直观、便捷地使用系统和功能。
UI不仅包括了屏幕上的按钮、图标、文字、菜单、颜色、布局等视觉元素,还涵盖了用户与系统之间的交互方式

游戏中的UI更注重沉浸感和视觉冲击力,传递信息的同时要增强玩家的游戏体验。且游戏UI更侧重于动态性和交互性。同时,UI要与游戏整体美术风格匹配,以更有沉浸感。

SlateUI是虚幻引擎底层的UI框架,用于构建和管理用户界面,是虚幻引擎中所有UI的基础,使用相对复杂,需要编写大量的C++代码。

SlateUI很麻烦,所以产生虚幻的UMG系统

Unreal Motion Graphics,虚幻引擎的可视化UI工具,基于Slate构建。
它通过可视化的蓝图系统让开发者和设计师可以不用编写C++代码
所以UMG相当于对Slate作了易用性封装

UMG功能简介

UMG编辑器有一个画布

动画轨道:编辑控件动画

使用按钮,滑动条,输入框等交互元素获取玩家输入以达到交互目的

布局调整及适配:通过合理的布局以美化UI整体效果

C++绑定蓝图控件

创建HUD类并在GameMode中设置以展示UI

Slot概念

骨骼动画

2D动画就是一帧一帧的图片,精灵动画

3D模型动画,有顶点动画,驱动顶点

而现阶段主角的一个网格体,顶点数量大,每次驱动无数顶点,数据量大,迭代缓慢,不可接受

所以出现了骨骼动画:
把网格体抽象出一层骨骼层

骨骼:互相连接的骨骼组成骨架结构,通过改变骨骼的朝向和位置来生成动画

蒙皮:将网格的顶点附着/绑定在骨骼是,每个顶点可以被多个骨骼控制(实际上就是随着骨骼变化,顶点变化)

UE基础资产类型

Skeleton:骨架,定义了骨骼的层级结构。骨架资源关联动画数据,骨架资源把骨骼数据关联到动画轨迹,从而驱动动画
SkeletonMesh:骨骼网格体,主要的渲染资源
PhysicsAsset:物理资产,关联各骨骼和物理世界的交互

顶层到底层

动画蓝图

分为Event Graph和Anim Graph

Event Graph:与普通蓝图的Event Graph类似,可以在BeginPlay、Tick中添加逻辑
Anim Graph:用于逐帧生成动画Pose,可以进行AnimSequence的采样、混合、骨骼变形等操作,最终产生想要的Pose

常用动画资产

Animation Sequence:
动画序列。由一系列关键帧组成的动画序列,也是最基本的动画类型,当动画执行到某个时间点时会由相邻两个关键帧融合出当前Pose

有动画叠加属性、AnimNotify(GamePlay通知)、动画曲线、AnimFrame

AnimAdditive:输出的Pose为此动画当前帧的Pose与设置的BasePose的差,AdditiveAnimType决定了此结果的Pose中骨骼变换的数据属于哪个空间。

Local Space及Mesh Space
Local Space下,Pose中保存的每个骨骼的变换数据为相对父骨骼的变换
Mesh Space下,Pose中保存的每个骨骼的变换数据为相对骨骼模型组建的变换

BlendSpace其实是由若干个Anim Sequences构成。提供了很便捷的多动画融合功能,通过传入参数值动态计算各个动画的权重输出融合后的结果,可以省去程序或者美术编写复杂的动画融合节点

Montage:蒙太奇动画。在编辑器中创建的动画资源,也由Anim Sequences组成,通过其设置的Section和Slot,可以实现一些特殊的动画控制,包括动画的智能循环、基于逻辑的动画切换等等
一个Montage可以设置若干个Slot,具体哪个slot生效,由运行时刻AnimGraph的情况决定。每个Slot可以拖入若干个AnimSequence,顺序可以按需更改。如果AnimSequence为叠加型动画,则这个Montage也为叠加型Montage
Montage可以有若干个Section,Section把整个Montage拆分成若干块,这些块之间可以自由的衔接和跳转
Montage的属性页可以设置播放时的淡入和淡出融合,使动作不会显得很突兀
如果Montage使用的AnimSequence勾选了RootMotion,则这个动画在播放过程中根骨骼的位移会使角色产生移动。这个功能要与CharacterMovement组件配合。移动组件在更新速度时会优先使用根骨骼位移来作为移动的值。
注意根骨骼动画需要客户端和服务器同时播,如果服务器不播或者时间差太多,客户端会被拉扯?

动画混合节点:
ApplyAdditive:在LocalSpace下把一个动画叠加到另一个动画上
ApplyMeshSpaceAdditive:在MeshSpace下执行叠加
Blend:把两个Pose根据Alpha参数作为权重进行混合
BlendBoneByChannel:
BlendMulti:
BlendPosesByBool和BlendPosesByInt:类似Switch case,根据参数选择哪个Pose
LayeredBlendPerBone:BlendPose可以由指定某个骨骼开始对BasePose进行覆盖,可以Local或Mesh
MakeDynamicAdditive:动态生成叠加型Pose,ApplyAdditive的反向操作,输出为两个输入Pose的差

Space Controls:空间转换,会把输入的Pose中存储的每个骨骼的变换信息全部按新的空间进行重新计算

状态机:提供了图形化方法控制动画切换,比如姿态切换、武器、跳跃等等。状态之间可以设置转换条件以及转换的融合相关数据。频繁的快速转换不适合设置太长的转换融合

IK Inverse Kinematics (逆运动学)
踩台阶或斜面
Two Bone IK UE封装好
FootIK

FABRIK:forward and backward reaching inverse kinematics

资源获取

官网商城,学习页面下载资源
adobe mixamo
www.mixamo.com

新技术:motion matching?

渲染基础

什么是渲染?
三维的东西渲染成二维的东西在图像上表现出来?
模型+纹理+光照-Shader->Picture

怎么渲染?
需要GPU管线

图形管线

传统渲染——GPU管线(光栅化管线)——实时渲染
光追:光线追踪管线,离线渲染等方面。

GPU管线如何工作:
几何处理、光栅化、像素处理

几何处理中:
顶点着色器 (细分着色器-几何着色器 可选) 投影 (坐标转换) 剪裁 屏幕映射

从模型空间转换到世界空间
还有相机空间的处理,让相机顶点作为中心,往z轴

转换矩阵:平移、旋转、缩放

细分着色器:细分三角形,增加更多顶点,增加模型的复杂度和光滑度
几何着色器:顶点变换为不同的图元、生成和删除顶点
投影:MVP的P,正交投影和透射投影
裁剪和屏幕映射

投影会导致非线性,顶点坐标不一致

光栅化:固定管线。三角形建立和三角形遍历

像素处理:像素着色器+Merger

Merger:深度测试、模板测试、像素混合、

CPU准备并绑定资源、切换渲染状态开关、传达绘制/计算命令

GPU硬件

NVIDIA Fermi架构
GPC(Graphics Processing Cluster)
每个GPC包含多个SM(Streaming Multiprocessor)
Raster Engine

一个SM里面有32个CUDA Core,16个LDST、4个SFU执行特殊
128Kb寄存器

纹理读取缓存器

移动端硬件特性:
Tile Based Rendering:
减少对内存的访问带宽,将屏幕切块,每个块先完整渲染到Tier Buffer上,再整体传回主存。
一个Render pass的所有drawcall的几何处理完全结束后,tiling处理器进行切块,再对每一块执行pixel shader process
Dual-pass Vertex Shading
两遍Vertex Shading,尽量减少不可见vertex的计算。
第一遍只处理位置,作剪裁和culling
第二遍再做完整的shader

IMR:VS->PS->Draw->混合
手机TBR:Drawcall->VS->做Tiling放到Frame Data,再作Binning Pass和Tile Buffer。

模型和纹理

模型:有序排列的点集,组成的图元(三角形)
纹理:物理空间作投影到投影空间坐标,根据对应关系函数(寻址模式),转到纹理空间坐标、再次取值可能再做转换输出

纹理放大和纹理缩小

贴图生成、SAT
LOD
虚拟几何体 Nanite

光照和阴影

PBR
BRDF
法线分布函数
菲涅尔方程
几何函数
Shadow Map
全局光照

后处理

渲染调试方法

SIGGRAPH
SIGGRAPH Course
GDC

游戏AI

从游戏角度,能模拟玩家行为和玩家进行交互的都可以算是AI

动画,是游戏AI角色的表现载体,让怪物看起来更真实

动画技术:

骨骼动画、帧动画、程序动画、Morph动画(表情等)、Curve动画、VertexShader动画

物理:提供真实世界的感知反馈,为游戏AI角色的增强效果,让AI有更丰富的感知和交互

物理引擎:场景查询、AI感知、碰撞检测、事件触发、物理约束模拟、头发模拟、流体模拟等
/p/660201778

渲染引擎:渲染画面

交互系统

玩法GamePlay:涉及游戏涉及的所有方面,包括战斗、3C、AI、玩家能力

游戏AI

AI目的:提升玩家游戏代入感和情感;
有趣,强度适中,满足玩家心理体验行为合理;
行为合理

游戏AI四大主题:
环境感知、知识管理、行为模型、寻路

结合、感知环境进行记忆然后做出行为(决策)

环境感知:视觉(SceneQuery)、听觉(Navmesh或其他数据)、将复杂环境数据转化为便于AI系统理解的简单中间数据

知识管理:通过黑板来作为数据共享(储存)、消耗大的感应结果、寻路结果、分帧Plan的部分Plan结果都可以储存?

行为模型:通过感知和记忆,利用一些逻辑来辅助决策
简单脚本——行为树——机器学习/深度学习
不同AI需求都有不同的最佳应用方案

有限状态机FA
随着项目复杂度变高,状态机越来越复杂,越来越难管理

引入分层有限状态机:在FA的基础上增加层次结构
如RPG顶层有战斗和非战斗状态,然后战斗状态下可能有攻击、防御等子状态

行为树:从根节点开始,从上到下从左到右,根据节点类型和条件来决定如何遍历树结构。当一个节点被执行时,它会根据自身的功能和返回值来影响行为树的后续执行。行为树侧重于通过组合不同类型的节点来构建行为序列
核心为选择节点和序列节点

寻路系统:DFS BFS A*
A*:把搜索拆分为H值和G值,搜索优先值为H+G
G值为耗费值,H值为预测值

Navmesh数据:体素化、点面组成的凸多边形数据

创建游戏项目

复制一个角色改名为敌兵角色,然后创建一个新的蓝图继承自AIController,命名为EnemyController。把Character和Controller关联起来。然后创建敌人的行为树,在敌人AI控制器的Being Play蓝图脚本时,执行Run Behavior Tree节点。
然后将NavmeshBoundsVolume拖到场景,调整Scale以套住关卡。一般会自动构建NavMesh,用起来很简单。
然后创建敌人AI大脑的记忆,黑板

结构问题:不要为了实现一个玩法而不计代价,不要粗暴的只管实现,不管制作流程和技术架构。

UE网络同步

计网基础

Socket:在应用层和传输层之间的一个抽象层,用Socket提供的接口(原语)做相关编程

TCP/UDP
P2P、C/S架构

C/S架构:主从式架构、所有客户端只和服务器对连,客户端之间的通信必须通过服务器。服务器性能压力大。

数据同步基础

RPC:远程过程调用。本地调用远端提供的函数/方法,因为不是一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。

远程调用,执行的函数体在远程的机器上,在另一个进程中,另一端不知道函数指针和堆栈数据
带来的新问题:
Call ID映射
序列化和反序列化
网络传输

对象序列化

类似函数ID映射,本地用到对象实例想要在另一端也能够直接使用,从而简化上层业务逻辑开发。

对象序列化将对象转换成一系列字节,这样对象容易被保存到持久存储中,或者通过通信链路传输

属性同步:我们希望对象A的某个属性修改后,其他端的镜像A对象对应的属性也需要更改。但在引擎可以让我们忽略底层细节,通过对象序列化?会自动同步,实现服务器更改,同步到其他所有客户端

游戏网络同步

同步,即多个客户端表现效果一致。对于大多数游戏,不仅客户端的表现要一致,而且需要客户端和服务端的数据是一致的。

目前同步框架主要分为帧同步和状态同步

帧同步技术:早期RTS常用的同步技术。帧同步只同步操作,其大部分游戏逻辑都在客户端上实现,服务器主要负责广播和验证操作。逻辑直观易实现、数据量少、可重播、一致性好等优点。

状态同步:同步的是游戏中的各种状态。客户端上传操作到服务器,服务器收到后计算游戏行为的结果,然后以广播的方式下发游戏中各种状态,客户端收到状态后再根据状态显示内容。状态同步实际上是不严谨的一种同步,不同玩家屏幕上表现的不一致性并不是重要指标,只要每次操作的结果相同即可。
UE本身是一个状态同步

帧同步主要写客户端逻辑

UE网络同步使用

UE网络架构:
以客户端-服务器模型为基础
实现面向对象式封装
实现网络代码和游戏逻辑完全分离
网络同步支持可视化编程
网络协议使用UDP通讯

UE网络模式:
NM_Standalone:单机游戏
DedicatedServer(DS):即服务器(状态同步,执行所有玩家的输入)
ListenServer:监听服务器,即一个本地玩家,他既是服务器,也是客户端(早年)
Client:客户端

Play as Client,会默认启动一个服务器(DS)

Actor的复制:Actor是UE网络同步核心,所有的数据同步都是围绕Actor展开的。服务器保留一份Actor列表并定期更新客户端,以便客户端保留每个Actor的近似副本

Actor提供的同步能力:
创建和销毁
移动
属性(最复杂的就是数组)
组件
子对象
远程程序调用

可以在蓝图或者通过C++代码设置Actor可以被复制
代码实现,在构造函数里,将bReplicates=true,
角色移动同步,则将CharacterMovement->SetlsReplicated(true)(将移动设置同步)

蓝图在引擎里相应勾选

Actor有Role之分
Role_None、SimulatedProxy(模拟)、Role_AutonomousProxy(主控)、Role_Authority(权威)

服务器一般里面Role是权威,但可能受客户端某个Actor控制,该Actor就是主控。而模拟只能接收来自服务器的数据

相当于我本地运行一个,我自己控制的角色就是主控,其他模拟同步的AI就是模拟

Actor属性同步,在UPROPERTY(Replicated),还有想要回调,则使用UPROPERTY(ReplicatedUsing = my_function)

Replicating Object References 指针也能借助UE同步

RPC
UFUNCTION(Server|Client|NetMulticast,Reliable|Unreliable,WithValidation)(函数声明)
函数实现后面加Implementation | Validate (进阶概念)

支持服务器和客户端双向复制,函数复制是没有返回值的,也不支持输出型参数。

UE网络同步实现

网络结构和主要功能类

网络相关性

常用分析工具

UE为何使用UDP协议实现网络同步:游戏追求的是最终一致性,没有那么高的可靠性要求。TCP为了时序性,牺牲了时效性。

UE网络同步主要的类
NetDriver:网络管理类
NetConnection:抽象的网络连接
Packet:数据包
Channel:数据传输的管道
Bunch:管道中传输的数据串

服务器多个NetConnection,每一个对应一个客户端连接
客户端有一个ServerConnection
Connection中创建和管理Channel
Channel有ActorChannel、ControlChannel、FileChannel、VoiceChannel

每个通信包是一个Packet

Bunch是数据流通的基本单元,位流,充分利用每一个Bit。

Channel打开即发送的第一个Bunch,头部带上Open标志位,以及Channel的类型和序号。

网络分析工具:Network Profier
查看网络相关的统计数据、检索网络同步的属性和RPC、游戏运行时动态开关

还有Network Insights

FPS游戏开发基础

开端:1992年德军总部3D
CF|逆战 UE3

基础框架

FPS游戏重要元素:

  • 武器(枪械)
  • 角色
  • 玩法(模式/地图)

Weapon、3C、Gameplay
Game System(管理游戏内部模块,例如网络、商业系统)
GameCore、Third Party Library
Game Engine
OS

武器系统

具体例子,具体分析。
以CF手游背包为例,分为主武器、副武器、近战、投掷物

但技术内部,还是按功能/种类划分。
如按种类划分为步枪、狙击枪、手枪、手雷等

按程序逻辑分可能还有InstantHit和Projectile等

关键基础组件:

  • 物理引擎:PhysX(开源)、HavoK(商业)、Bullet(开源)。使用物理引擎一部分是为了命中,还有场景的移动、碰撞、命中检测、受击检测、布料模拟等。
  • 弹道模型:射一梭子,然后根据时序划线分析。影响弹道的因素主要有主视角角度、后坐力、连发数、精准度、散发度(运动姿态)

后坐力第一枪有一个基准值,然后随着连发数可以线性增加,直至稳定(设计)
AK和MP5弹道表现不同,可以通过更改基准值、后坐力最值、多少连发数收敛

主弹道子弹射出方向=主视角角度+后坐力+精准度+散发度
后坐力、精准度、散发度与具体武器相关,通过配置参数与公式计算得出

例如某一散发度公式:散发方向=随机数*散发度*水平/垂直方向

如果去掉垂直后坐力最大限制:弹道不断上抬上天

InstantHit Weapon开火流程:
射程内是否击中物体:未击中则根据连发数计算新的后坐力角度,进入下一次射击。击中的话则根据相应规则计算伤害,再判断是否穿透该物体,穿透则穿透数+1继续判断还有没有击中物体,否则根据连发数计算新的后坐力角度,进入下一次射击。

武器系统框架:
继承或组合
继承示例:
Inventory->Weapon->
组合:
WeaponFireComponent:分为Instant、Melee、Placing、Projectile等不同开火组件

通过状态机控制武器的状态:
枪械可能有闲置、开火、换弹、检视等

3C System

最早由育碧提出的游戏设计概念
Camera(相机):玩家通过它观察游戏世界,获得体验感和沉浸感
Character:具有一定的能力和行为,玩家可以扮演或观察
Control:控制,为玩家提供不同方式、不同体验的交互

Character技术要点:

  • 表现方面(外观):Mesh、贴图、材质、动画、物理
  • 逻辑方面:走跑跳
  • 角色状态的设计与转换
  • 细节问题

Camera技术要点:

  • 渲染顺序(避免穿模等)
  • FOV(UE只有)
  • 碰撞、位置控制
  • 屏幕效果

Control技术要点:

  • 设备与手感
  • 手游适配问题:同样代码iOS与Android灵敏度不同、不同Android手机,灵敏度不同;
  • 辅助瞄准
  • 硬件功能

其他技术点:
网络同步:帧同步、状态同步

FPS:状态同步

选择:客户端预表现 还是 等服务器确认

例如投掷手雷:
客户端预表现:客户端手雷直接扔出去
等服务器确认:两个延时,上行和下行,要求网络环境

客户端预表现:一次延时

Peeker’s Advantage:
移动还是静止

移动先看到静止的

A移动,B静止,世界状态一致。
A移动,移动的过程存在延时,要先发给服务器,服务器再发给B,告诉B,A移动了。所以两次延时后,A移动的情况才会发生在B玩家的客户端中。
但A玩家移动时,因为B玩家是静止的,本身已经在世界状态中,所以移动出去就看到了。主要是两次延时的问题。

关键开火要等服务器确认。
但不是所有情况都是客户端预表现或者服务器确认。例如换弹,没必要等服务器确认。而手雷爆炸,预表现的性能也不是很好。

反外挂:
外挂分类:

  • 定制外挂:专用插件类
  • 通用工具:内存修改器、变速器、抓包工具
  • 辅助类:按键精灵、模拟器、虚拟机
  • 破解版:脱机挂、破解版客户端

外挂原理:
应用层:游戏逻辑部分读取逻辑坐标、修改渲染参数等,游戏引擎中读取引擎坐标、修改可见性判定(更通用)
系统层:图像渲染(修改渲染指令及过程)、声音效果(还原声源坐标)
硬件层:显卡驱动(增删显示内容)、网络通信(解密坐标协议)、内存读取

反外挂方式:

  • 服务器校验(解决位置不正确、伤害等)
  • 服务器数据下发:UE默认对所有客户端做同步
  • 客户端数据加密:
  • 客户端动态检测:

性能优化:
总览:
CPU性能优化:物理性能优化、动画优化、流程逻辑优化、Pool的使用
渲染性能优化:UI/场景优化、制定制作规范
内存优化:合理合图、资源压缩、资源分包
流量优化:减少网络总类、合并网络包
游戏卡顿优化:预加载、分帧处理

物理:主要是CPU的开销,但对于PhysiX,可能还有GPU的部分。
物理射线检测开销大,我们可以仅仅通过包围盒数据和射线数据判断是否相交,减少开销

动画:计算角色骨骼投影大小、更新LOD、更新动画,主要就是通过LOD,Tick频率随距离远近变化。遮挡也可以停止Tick

GPU Skinning:UE5渲染管线完全改成了GPU Driver的方式

渲染:CPU分发给GPU,还是剪枝。例如视锥裁剪、距离裁剪、LOD、遮挡剔除等