参考《Unreal Engine 4 学习总动员》,按照里面的录制的视频一步一步的操作,并将操作的流程和关键截图保存下来,方便后面的再次复习和回顾,如果想详细的了解UE4,请自行购买《Unreal Engine 4 学习总动员》
虽然已经将相关书籍全部看完,也对主要的技术都有了初步的了解,但是仍然缺乏系统化的认识,包括对UE4引擎的整体的设计结构的认知,主要的功能模块,模块中的类及其关系等。
后面希望逐渐通过实战项目对UE4的API和整体的架构有更深入的认识。
从官方下载虚幻4,目前学习采用的版本号是4.20
课堂疑问
增加光照亮度?
答:光照属性:Intensity(强度)
快速赋予多个物体、多个面相同的材质?
如何设置游戏的默认开始关卡?
答:在项目设置里,地图&模式,选择对应的地图和模式即可,开始编译的时候会编译Shader,可能会失败,再次尝试就会成功。
在世界视图中能不能新增加文件夹?
答:可以
记录操作步骤
导入1-5章初学者内容
存盘,创建材质文件
双击打开材质编辑器
记录操作步骤
创建和使用点光源
改变颜色和范围
创建一个通道
给FirstPersonCharacter新增加一个聚光灯,并将聚光灯绑定到枪上,修改聚光灯的颜色、内角、外角、范围
给通道增加机构天花洞,增加一个天光。设置天光属性Moveable,让天光显示在枪口上。
在墙的最后增加一个灯光,并添加一个灯罩。
打开引擎自带资源(View Options->Show Engine Content),修改灯光使用灯光贴图IES 纹理。
记录操作步骤
点击地形,创建一个地形,使用画笔画出初步的地形
创建三个文件夹 Meterials、Resources、Textures,并导入5张材质 T_ForestGround_D、……
创建一个纹理,并开始编辑纹理
创建地形纹理
回到地形绘制工具,选择paint,选择每个层,创建层信息文件
使用画刷画每一个层的范围
设置每次跳跃的时候,体力减少0.1
![在这里插入图片描述](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 感知器
记录操作步骤
创建一个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上创建组件,并运行
最终效果:跳动的小球
记录操作步骤
创建Side Scroller 人物侧滚项目
创建Actor,在Actor中添加一个Cube和一个Box Collision(用于碰撞检测)
选择这个Actor,在属性面板中选择创建蓝图
在蓝图中,选择box,为其添加事件。
记录操作步骤
创建第三人称游戏
向场景中添加Box Trigger,并创建蓝图
创建变量 Target Actor,将属性公开
选择Trigger Base => CollisionComponent,添加碰撞开始事件
添加一个Cube,并设置对象属性:Movable
绑定到对应对象
记录操作步骤
创建第三人称游戏
创建一个宏
展示最终效果。
按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创建引用。
编辑最终蓝图
记录操作步骤
记录操作步骤
创建材质实例,修改金属和光滑度
使用材质,最终效果
记录操作步骤
创建材质
记录操作步骤
记录操作步骤
记录操作步骤
记录操作步骤
将配套的模型文件导入到项目中:T_MeshDecalDemage_XXX
修改模式
记录操作步骤
该项目因没有原始文件,因此无法实际操控,可以自己从网上下载其他人物模型实践。
记录操作步骤
创建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("RootComponent");
//创建相机和可见项目
UCameraComponent* OurCamera = CreateDefaultSubobject("OurCamera");
OurVisibleComponent = CreateDefaultSubobject("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("RootComponent");
//创建相机和可见项目
UCameraComponent* OurCamera = CreateDefaultSubobject("OurCamera");
OurVisibleComponent = CreateDefaultSubobject("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;
}
远程调用包括3中类型
创建第三人称游戏,人物蓝图中添加如下,先设置成广播级别
可以看到,服务器上的人物能分发到客户端上,而客户端上的没有向服务器发送
在修改成Run On Server,修改火焰的选择复制属性,此时客户端和服务器都能看到
原因时无论客户端运行还是服务器运行,都会将消息发送给客户端,而在客户端运行,客户端运行后,会将状态复制到各个服务端上,如果没有选择复制属性,则只会在服务器上显示。
最后选择Run On owning Client,则只会在自己的端上运行
另外Replicated会分发给所有端,并执行与其相关的事件