Unreal Engine 4 学习总动员读书笔记
参考《Unreal Engine 4 学习总动员》,按照里面的录制的视频一步一步的操作,并将操作的流程和关键截图保存下来,方便后面的再次复习和回顾,如果想详细的了解UE4,请自行购买《Unreal Engine 4 学习总动员》
虽然已经将相关书籍全部看完,也对主要的技术都有了初步的了解,但是仍然缺乏系统化的认识,包括对UE4引擎的整体的设计结构的认知,主要的功能模块,模块中的类及其关系等。
后面希望逐渐通过实战项目对UE4的API和整体的架构有更深入的认识。
《快捷入门》
一、获取软件
从官方下载虚幻4,目前学习采用的版本号是4.20
二、界面介绍
- 界面划分
- 中心:视口
- 左边:模型
- 右边:世界大纲
- 底部:内容浏览器
- 右下角:细节面板
- 界面消失了怎么恢复
- Window里面回复
- 如何重置布局
- Windows->Reset Layout
三、试图操作
- 快捷键
- 标准操作
- 鼠标左键+拖动:前后左右移动
- 鼠标右键+拖动:旋转视口相机
- 鼠标左键+鼠标右键+拖动:上下移动
- F:聚焦
- WASD飞行
- W:前
- S:后
- A:左
- D:右
- E:上
- Q:下
- Z:远
- C:进
- 环绕、移动和跟踪
- Alt + 鼠标左键 + 拖动:围绕兴趣点翻转视口
- Alt + 鼠标右键 + 拖动:围绕兴趣的靠近
- Alt + 鼠标中键 + 拖动:上、下、左、右
- 进入游戏模式:Alt+P
- 标准操作
四、关卡设计
- 记录操作步骤
- 创建一个第一人称射击关卡,并创建一个空白关卡
- 创建一个小房子
- 光源
- DirectLight:Fog Sun Light
- 雾
- Atomspheric Fog
- 门窗
- Brush Type: Subtractive
- 物体碰撞
- Simple Physics
- 光源
- 创建游戏开始玩家
- 灵活使用W、E、R快捷键
- 使用不同的视图模式,避免光照对编辑的影响。
- Visibility Collision:碰撞区域
- Light Only和Detail Lighting的区别:有没有材质
- Unlit:无光照的材质模式
-
课堂疑问
-
增加光照亮度?
答:光照属性:Intensity(强度)
-
快速赋予多个物体、多个面相同的材质?
-
如何设置游戏的默认开始关卡?
答:在项目设置里,地图&模式,选择对应的地图和模式即可,开始编译的时候会编译Shader,可能会失败,再次尝试就会成功。
-
在世界视图中能不能新增加文件夹?
答:可以
-
五、材质入门
-
记录操作步骤
-
导入1-5章初学者内容
-
存盘,创建材质文件
-
双击打开材质编辑器
- Shading Model: Subsurface(次表面:光线能够穿透透明&半透明物体的)
- 创建材质,并设置材质
- 创建1个变量的常量和3个变量的常量
- Base Color(材质基础颜色&纹理)
- Specular:镜面反射
- Roughness:粗糙度
- Opacity:透明度
- Normal:法线
- Subsurface Color:次表面颜色(内部的颜色材质)
- 将材质赋予到物体上
-
六、光照入门
-
记录操作步骤
-
创建和使用点光源
-
改变颜色和范围
-
创建一个通道
-
给FirstPersonCharacter新增加一个聚光灯,并将聚光灯绑定到枪上,修改聚光灯的颜色、内角、外角、范围
-
给通道增加机构天花洞,增加一个天光。设置天光属性Moveable,让天光显示在枪口上。
-
在墙的最后增加一个灯光,并添加一个灯罩。
-
打开引擎自带资源(View Options->Show Engine Content),修改灯光使用灯光贴图IES 纹理。
-
七、地质地貌
-
记录操作步骤
-
点击地形,创建一个地形,使用画笔画出初步的地形
-
创建三个文件夹 Meterials、Resources、Textures,并导入5张材质 T_ForestGround_D、……
-
创建一个纹理,并开始编辑纹理
-
创建地形纹理
- LandscapeCoords:材质纹理坐标
- Layer Blend:材质融合
- 组合注释:快捷键C
- 常量:快捷键S
- Add:右键搜索
- 自定义白色材质:3
- 注意,Base Color和Normal的层的名字要保持一致
-
回到地形绘制工具,选择paint,选择每个层,创建层信息文件
-
使用画刷画每一个层的范围
-
八、UMG_UI设计
- 记录操作步骤
-
创建文件夹UMG
-
创建用户界面蓝图控件 HUD
-
在设计界面中设计游戏图表,找到布局控件、文本控件和进度条控件,设置好位置以及属性。
-
在构造函数中获取第三人称角色
-
-
增加人物蓝图的两个属性Energy、Hearth
-
将进度条绑定到属性中
- 在人物蓝图中将控件添加到视图中
-
设置每次跳跃的时候,体力减少0.1
- 使用Alt拖拽,创建一个Set
- 使用Control键,创建一个变量名称
- 最终效果
![在这里插入图片描述](https://img-blog.csdnimg.cn/c72a148fa60e4535beecf9a0ee9ea1c8.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pZb25naGVuZw==,size_16,color_FFFFFF,t_70#pic_center)
九、人工智能角色
-
记录操作步骤
-
创建第三人称模板
-
创建寻路网格体(Nav Mesh Bounds Volume),将虚拟框包住网格体,按P键查看是否包裹。
-
复制一个角色,删除蓝图中的逻辑,以及摄像头相关的组件。
-
创建Pawn Sensing 感知器
- 添加事件逻辑,首先必须要先点击PawnSetting组件。
- 最终效果
-
十、编程入门
-
记录操作步骤
-
创建一个C++项目
-
创建C++类,FloatingAction
-
编写代码
public: float RunningTime = 0.0f;//运行时间
void AFloatingActor::Tick(float DeltaTime) { Super::Tick(DeltaTime); FVector NewLocation = GetActorLocation(); float DeltaHeight = (FMath::Sin(RunningTime + DeltaTime) - FMath::Sin(RunningTime)); NewLocation.Z += DeltaTime * 50.0f; RunningTime += DeltaTime; SetActorLocation(NewLocation); }
-
将Actor拖拽进来
-
在Actor上创建组件,并运行
-
最终效果:跳动的小球
-
《蓝图应用》
一、折叠节点图标
- 记录操作步骤
- 在Event Graph视图中,框选一些内容,右键 Collapse Nodes,折叠节点
- Expand Node 扩展节点
- 使用Collapse To Function 可以折叠到函数
- 使用Collapse To Macro 折叠到宏
- 按C键,给图表添加注释
二、触发器蓝图应用
-
记录操作步骤
-
创建Side Scroller 人物侧滚项目
-
创建Actor,在Actor中添加一个Cube和一个Box Collision(用于碰撞检测)
-
选择这个Actor,在属性面板中选择创建蓝图
-
在蓝图中,选择box,为其添加事件。
- 按B+鼠标左键,创建分支。
-
- 再次运行,小人跳到盒子上面就会自动弹跳。
三、设置和获取Actor引用
-
记录操作步骤
-
创建第三人称游戏
-
向场景中添加Box Trigger,并创建蓝图
-
创建变量 Target Actor,将属性公开
-
- 在My Blueprint选项卡中,选择显示所有继承的对象
-
选择Trigger Base => CollisionComponent,添加碰撞开始事件
-
添加一个Cube,并设置对象属性:Movable
-
绑定到对应对象
- 最终效果,当任务进入碰撞体后,立方体向上移动100个单位
四、创建蓝图宏
-
记录操作步骤
-
创建第三人称游戏
-
创建一个宏
-
- 编辑宏
- 在跳跃的时候添加使用宏
- 最终效果
五、使用蓝图宏库
- 记录操作步骤
-
创建第三人称游戏。
-
创建蓝图宏库,父级类是Actor
-
创建输入输出。
-
创建宏的定义
-
- 使用宏库
-
展示最终效果。
按Q键增加人物能量。
当人物能量增加超过250之后,带E键可以使人物放大。
六、创建蓝图函数
-
记录操作步骤
- 创建蓝图,并在蓝图内创建函数。
- 在当前蓝图使用函数。
![在这里插入图片描述](https://img-blog.csdnimg.cn/1937d3a7be5b4be5999679da088f8194.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pZb25naGVuZw==,size_16,color_FFFFFF,t_70#pic_center)
-
将蓝图拖入到场景中。
-
展示最终效果。
七、使用蓝图接口
-
记录操作步骤
-
创建包含初学者内容的第一人称射击游戏。
-
添加插件。
-
- 选中玻璃,右键选择创建破损网格体。
-
点击破损
-
为破损体创建蓝图。
- 创建蓝图接口。
- 添加要引用的接口。
- 添加接口的事件回调函数。
- 为吊灯蓝图添加事件回调函数。
- 在第一人称射击蓝图中添加调用。
-
将蓝图将蓝图拖拽到场景内。
-
最终的运行效果。
八、蓝图事件调度
-
记录操作步骤
- 创建第三人称蓝图。
- 向场景内拖拽一个灌木丛,并打开关卡蓝图。
- 创建灌木丛对象。
- 创建蓝图。
- 最终效果
九、蓝图通信
-
记录操作步骤
-
创建第三人称游戏。
-
向场景中拖拽离子火焰,创建立方体蓝图。
-
关闭离子火焰特效,关关闭立方体碰撞。
-
-
实现立方体碰撞后激活火焰:
- 创建火焰变量,设置变量类型为火焰特效。
- 设置变量的可见性。
- 最后指定该变量对应场景中的物体。
- 最终效果
十、使用蓝图阵列
-
记录操作步骤
-
看见第三人称游戏。
-
往场景中添加目标点。
-
多少目标点,打开当前蓝图。右键,选择为当前的7个选中的Actor创建引用。
-
编辑最终蓝图
-
- 运行结果。
《材质渲染》
一、使用主材质节点
-
记录操作步骤
- 创建一个红色金属材质
- 了解混合模式
- 应用材质及最终效果
二、构造材质参数
- 记录操作步骤
- 创建材质,并创建一个常量
- 右键,将常量转变为变量,或者直接按S键创建变量
- 在已经创建好的材质上,右键,创建材质Instance。
三、使用有光泽材质
-
记录操作步骤
- 创建塑料材质
-
创建材质实例,修改金属和光滑度
-
使用材质,最终效果
四、UV坐标动画材质
-
记录操作步骤
-
创建材质
- Panner:UV动画
- TexCoord:
- Time:
-
- 最终效果
五、细节纹理材质
- 记录操作步骤
- 应用纹理,修改Scale
六、自发光材质
-
记录操作步骤
- 创建发光立方体材质
- 最终效果
七、透明度材质
-
记录操作步骤
- 创建材质
- 应用材质
八、凹凸贴图偏移材质
-
记录操作步骤
- 使用BumpOffset产生凹凸贴图
- 应用材质
九、模型贴花材质
-
记录操作步骤
- 首先检查项目设置——延迟贴花是否勾选
-
将配套的模型文件导入到项目中:T_MeshDecalDemage_XXX
-
修改模式
- 创建材质
-
创建底色材质
-
最终分别应用及其最终效果
十、制作折射材质
-
记录操作步骤
-
创建材质,修改半透明材质
-
创建材质
-
使用砖墙材质做波纹效果
-
最终效果
-
《动画设计》
一、预览动画
-
记录操作步骤
-
创建第三人称游戏,找到自带的动画
-
熟悉动画编辑器
-
二、重定向动画
-
记录操作步骤
-
创建第三人称游戏,添加动画初学者包到项目中。
-
导入外部模型——士兵
-
选择默认的骨架,选择重定向管理
-
选择人物
-
对士兵做装配
-
装配完成后,选择动画,右键,复制到指定的源
-
如果开始的姿势有问题,可以在骨架菜单中调整初始姿势
-
-
该项目因没有原始文件,因此无法实际操控,可以自己从网上下载其他人物模型实践。
三、编辑动画层
- 记录操作步骤
-
创建第一人称人物射击游戏。将人物端起枪的动画拷贝一份。
-
分辨在第一帧,第15帧,第20帧创建关键帧,并在关键帧处修改人物端枪的状态。
-
定位到45帧处,右键,删除后面的帧。
-
右键,创建动画Montage
-
双击打开Montage,修改默认的组为DefaultGroup.Arms
-
可以在刚才的Reload文件中,选择蓝图,查看动画的状态机。
-
找到人物的蓝图,添加按R键播放Montage
-
四、曲线驱动动画
- 记录操作步骤
-
创建第三人称游戏,选择行走路线,创建姿势资产。
-
在第6帧和第24帧处,修改姿势名字,创建参考姿势。
-
在时间滑块中右键,在结束的地方追加30帧。
-
添加两条曲线。
-
双击其中一个关键帧,按Enter,添加一个关键帧。
-
选择资源预览资源
-
最终效果
-
五、使用子动画实例
- 记录操作步骤
-
该子动画无法在最新的版本中使用。
-
创建第三人称游戏,复制人物动画蓝图
-
修改人物动画蓝图,注意IK手柄链(Alt_AnimBP)
-
选择原有的蓝图修改(ThirdPerson_AnimBP)
-
最终效果
-
六、创建动态动画
- 记录操作步骤
-
创建第三人称游戏,导入模板Infinity Blade: Adversaries
-
先根据人物模型,对人物骨骼做重定向
-
选择骨骼树,在根关节,右键,设置重定向骨骼,并且在b_MF_Pelvis(盆骨)修改为Animation Scaled动画缩放,b_MF_Root修改为Animation。
-
对第三人称动画蓝图做重定向。
-
点击Retrarget执行重定向
-
修改重定向的文件名
-
选择人物蓝图,修改人物
-
设置动态动画
-
设置角度
-
链接好动态动画
-
继续添加第二个动画
-
实际效果
-
七、创建混合空间动画
- 记录操作步骤
-
创建第三人称游戏,添加初学者动画包,修改游戏模式。
-
创建混合空间
-
修改坐标轴的含义和范围
-
设置向前行走的动作为默认动作,并设置其他点
-
打开数据包中的动画蓝图,并替换混合空间
-
修改
-
删除下蹲
拖拽角色移动
设置按键消息
隐藏封套
-
最终效果
-
八、创建分层动画
- 记录操作步骤
-
创建第三人称游戏,导入动画初学者内容,设置人物蓝图
-
选择打枪的动画,创建动画Montage
-
创建新的卡槽
-
打开Ue4ASP_Character,修改事件蓝图
-
打开UE4ASP_HeroTPP_AnimB
-
修改事件图表
-
最终效果
-
九、创建过场动画1
- 记录操作步骤
-
创建关卡序列
-
复制一个
-
大致将视图切换成如此
-
按S设置关键帧,设置焦距
-
设置好后,切换到影片
-
如法炮制,创建第二个分镜头
-
在主镜头中添加轨道
-
十、创建过场动画2
- 记录操作步骤
-
组合镜头
-
把动画拖拽到场景中,选择自动播放。
-
最终效果
-
《C++编程》
一、UE4中的C++
- 记录操作步骤
二、自定义Pawn
-
记录操作步骤
-
创建C++项目
-
创建MyPawn
UPROPERTY(EditAnywhere) UStaticMeshComponent* OurVisibleComponent;
AMyPawn::AMyPawn() { // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; //将这个Pawn设置成玩家控制 AutoPossessPlayer = EAutoReceiveInput::Player0; //创建一个可供添加对象的空根组件 RootComponent = CreateDefaultSubobject<USceneComponent>("RootComponent"); //创建相机和可见项目 UCameraComponent* OurCamera = CreateDefaultSubobject<UCameraComponent>("OurCamera"); OurVisibleComponent = CreateDefaultSubobject<UStaticMeshComponent>("OurVisibleComponent"); //附加的相机和可见对象到根组件。且设置相机的偏移和旋转。 OurCamera->AttachTo(RootComponent); OurCamera->SetRelativeLocation(FVector(-250.0f, 0.0f, 250.0f)); OurCamera->SetRelativeLocation(FVector(-450.0f, 0.0f, 0.0f)); OurVisibleComponent->AttachTo(RootComponent); }
-
三、创建空组件和可见相机
- 记录操作步骤
四、偏移并旋转相机
- 记录操作步骤
五、配置游戏输入
-
记录操作步骤
-
在项目设置中找到Input
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u2LrASK4-1629275589861)(C:\Users\20582\OneDrive\技术文档\Unreal Engine 4 学习总动员学习笔记.assets\image-20210818091244356.png)]
-
设置一个物体
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5aeUvp2I-1629275589861)(C:\Users\20582\OneDrive\技术文档\Unreal Engine 4 学习总动员学习笔记.assets\image-20210818091614499.png)]
-
六、定义函数和变量
- 记录操作步骤
七、队函数进行代码实现
- 记录操作步骤
八、绑定输入函数
- 记录操作步骤
九、实现具体操作控制
- 记录操作步骤
十、处理坐标移动效果
-
记录操作步骤
-
最终代码
// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "GameFramework/Pawn.h" #include "MyPawn.generated.h" UCLASS() class MYPROJECT17_API AMyPawn : public APawn { GENERATED_BODY() public: // Sets default values for this pawn's properties AMyPawn(); protected: // Called when the game starts or when spawned virtual void BeginPlay() override; public: // Called every frame virtual void Tick(float DeltaTime) override; // Called to bind functionality to input virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; UPROPERTY(EditAnywhere) UStaticMeshComponent* OurVisibleComponent; //输入函数 void MoveXAxis(float AxisValue); void MoveYAxis(float AxisValue); void StartGrowing(); void StopGrowing(); //输入变量 FVector CurrentVelocity; bool bGrowing; };
// Fill out your copyright notice in the Description page of Project Settings. #include "MyPawn.h" #include "Camera/CameraComponent.h" #include "Components/InputComponent.h" #include "Components/StaticMeshComponent.h" // Sets default values AMyPawn::AMyPawn() { // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; //将这个Pawn设置成玩家控制 AutoPossessPlayer = EAutoReceiveInput::Player0; //创建一个可供添加对象的空根组件 RootComponent = CreateDefaultSubobject<USceneComponent>("RootComponent"); //创建相机和可见项目 UCameraComponent* OurCamera = CreateDefaultSubobject<UCameraComponent>("OurCamera"); OurVisibleComponent = CreateDefaultSubobject<UStaticMeshComponent>("OurVisibleComponent"); //附加的相机和可见对象到根组件。且设置相机的偏移和旋转。 OurCamera->AttachTo(RootComponent); OurCamera->SetRelativeLocation(FVector(-250.0f, 0.0f, 250.0f)); OurCamera->SetRelativeLocation(FVector(-450.0f, 0.0f, 0.0f)); OurVisibleComponent->AttachTo(RootComponent); } // Called when the game starts or when spawned void AMyPawn::BeginPlay() { Super::BeginPlay(); } // Called every frame void AMyPawn::Tick(float DeltaTime) { Super::Tick(DeltaTime); //给予Grow的操作来处理增大和缩小 float CurrentScale = OurVisibleComponent->GetComponentScale().X; if(bGrowing) { //在一秒的时间内增长到两倍 CurrentScale += DeltaTime; } else { //随着增长缩小到一半 CurrentScale -= (DeltaTime * 0.5f); } //确认不低于起始大小,或增大之前的两倍大小 CurrentScale = FMath::Clamp(CurrentScale, 1.0f, 2.0f); OurVisibleComponent->SetWorldScale3D(FVector(CurrentScale)); if(!CurrentVelocity.IsZero()) { FVector NewLocation = GetActorLocation() + (CurrentVelocity * DeltaTime); SetActorLocation(NewLocation); } } // Called to bind functionality to input void AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { Super::SetupPlayerInputComponent(PlayerInputComponent); //按下或松开Grow有响应 InputComponent->BindAction("Grow", IE_Pressed, this, &AMyPawn::StartGrowing); InputComponent->BindAction("Grow", IE_Released, this, &AMyPawn::StopGrowing); //在每一帧都对两个坐标轴产生响应 InputComponent->BindAxis("MoveX", this, &AMyPawn::MoveXAxis); InputComponent->BindAxis("MoveY", this, &AMyPawn::MoveYAxis); } void AMyPawn::MoveXAxis(float AxisValue) { //每秒100个单位向前或向后移动 CurrentVelocity.X = FMath::Clamp(AxisValue, -1.0f, 1.0f) * 100.0f; } void AMyPawn::MoveYAxis(float AxisValue) { //每秒100个单位向左或向右移动 CurrentVelocity.Y = FMath::Clamp(AxisValue, -1.0f, 1.0f) * 100.0f; } void AMyPawn::StartGrowing() { bGrowing = true; } void AMyPawn::StopGrowing() { bGrowing = false; }
-
《游戏开发》
一、生成和摧毁角色
-
记录操作步骤
-
创建第三人称游戏,点击蓝图-打开关卡蓝图
-
最终效果
-
二、玩家重生设计
-
记录操作步骤
-
选择Blueprint\ThiredPerson进入游戏模式蓝图
-
设置人物蓝图
-
最终效果
-
三、支配角色设置
-
记录操作步骤
-
创建一个侧滚的项目,并复制两个小人。全选小人,打开当前关卡蓝图。
-
最终效果
-
四、使用计时器
- 记录操作步骤
-
创建第三人称游戏,包含初学者内容
-
添加函数FireDemage
-
修改第三人称蓝图
-
向场景中拖拽一个蓝图火焰
并编辑蓝图
-
最终效果
-
五、为Actor添加组件
-
记录操作步骤
-
创建第三人称游戏
-
拖拽一个灌木丛,并创建蓝图
-
添加离子火焰或蓝图
-
设计蓝图
-
最终效果
按F键熄灭火焰
-
六、引用Actor
-
记录操作步骤
-
向场景拖入两个Effice,编写火焰的蓝图
-
在外部制定好Target Blueprint,最终效果是程序执行5s后选择的对象的动画自动停止播放
-
七、使用OnHit事件
-
记录操作步骤
-
创建第一人称,包含初学者内容
-
创建损坏体
-
为损坏体创建蓝图,并勾选物理属性
-
修改打击体蓝图
-
八、同步Actor
- 记录操作步骤
-
创建第三人称,包含初学者内容
-
将离子火焰的特效复制两份,一个是服务器端,一个是客户端端,设置在服务器端不加载,客户端加载,且复制到服务器端。
-
修改玩家数量为2
-
最终效果可以看到在服务器上有两个离子火焰,在客户端上只有一个(按Shift+F1退出鼠标)
-
删除两个火焰,创建两个目标点,修改关卡蓝图
-
最后运行效果,这一次是在服务器上没有显示火焰,在客户端上显示了火焰
-
九、同步变量
- 记录操作步骤
-
创建第三人称游戏
-
找到离子火焰,在上面添加一个textRender
-
设置离子火焰蓝图
注意修改变量的属性
-
再次添加一个变量,标识火焰是否熄灭
-
最终效果,火焰计时器到0时同时熄灭
-
十、远程调用函数
- 记录操作步骤
-
远程调用包括3中类型
- Multicast
- Run On Server
- Run On owning Client
-
创建第三人称游戏,人物蓝图中添加如下,先设置成广播级别
-
可以看到,服务器上的人物能分发到客户端上,而客户端上的没有向服务器发送
-
在修改成Run On Server,修改火焰的选择复制属性,此时客户端和服务器都能看到
原因时无论客户端运行还是服务器运行,都会将消息发送给客户端,而在客户端运行,客户端运行后,会将状态复制到各个服务端上,如果没有选择复制属性,则只会在服务器上显示。
-
最后选择Run On owning Client,则只会在自己的端上运行
-
另外Replicated会分发给所有端,并执行与其相关的事件
-