本周工作总结:
1. 编译环境的搭建
visual studio2017安装
unrealengine安装:
引擎源码安装:github源码
解压之后,可以看到
首先点击Setup.bat,这个需要代理才能把资源下载下来。如何设置全局代理KM有人提供了较好的解决方案。大概需要下载5g左右的文件,然后点击GenerateProjectFiles.bat,等待一两分钟后,文件内会生成UE4.sln。用vs2017打开,选择DEVELOPMENT EDITOR ,然后选择UE4,并且生成解决方案。由于是第一次生成,所以耗时非常大,大概花了半个小时才部署好,接着编译,生成了UE4。
2.开始虚幻引擎4之旅
首先进行的是编程快速入门
通过这个小小的快速入门,让我学会了在虚幻引擎4中创建C++类的Actor并且在UE4编辑器使用Actor作用在地图中。
重写Tick(float)实现Actor沿着Z轴(也就是上下)浮动的效果
// Called every frame void AFloatingActor::Tick(float DeltaTime) { Super::Tick(DeltaTime); FVector NewLocation = GetActorLocation(); float DeltaHeight = (FMath::Sin(RunningTime + DeltaTime) - FMath::Sin(RunningTime)); NewLocation.Z += DeltaHeight * 20.0f; //把高度以20的系数进行缩放 RunningTime += DeltaTime; SetActorLocation(NewLocation); }
接着进行的是玩家输入和Pawns
UPROPERTY(EditAnywhere) //使OurVisibleComponent在UE编辑器中可以编辑。 USceneComponent* OurVisibleComponent; // 输入函数 void Move_XAxis(float AxisValue); void Move_YAxis(float AxisValue); void StartGrowing(); void StopGrowing();
// 调用以绑定功能到输入 void AMyPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent) { Super::SetupPlayerInputComponent(InputComponent); // 在按下或松开"Grow"键时进行响应。 InputComponent->BindAction("Grow", IE_Pressed, this, &AMyPawn::StartGrowing); InputComponent->BindAction("Grow", IE_Released, this, &AMyPawn::StopGrowing); // 在每一帧都对两个移动坐标轴的值进行响应,它们分别是"MoveX"和"MoveY"。 InputComponent->BindAxis("MoveX", this, &AMyPawn::Move_XAxis); InputComponent->BindAxis("MoveY", this, &AMyPawn::Move_YAxis); } //实现了pawn可以移动,可以变大变小的控制。
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; // Set this pawn to be controlled by the lowest-numbered player AutoPossessPlayer = EAutoReceiveInput::Player0; // Create a dummy root component we can attach things to. RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent")); // Create a camera and a visible object UCameraComponent* OurCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("OurCamera")); OurVisibleComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("OurVisibleComponent")); //Attach our camera and visible object to our root component. Offset and rotate the camera. OurCamera->AttachTo(RootComponent); OurCamera->SetRelativeLocation(FVector(-250.0f, 0.0f, 250.0f)); OurCamera->SetRelativeRotation(FRotator(-45.0f, 0.0f, 0.0f)); OurVisibleComponent->AttachTo(RootComponent); } //在构造函数中加入camera,使camera绑定场景,记录pawn的动作。
最后实现了,pawn可以按空格随之变大,wasd控制方向。
接着就是进行控制camera的行为。
// Called every frame void ACameraDirector::Tick( float DeltaTime ) { Super::Tick( DeltaTime ); const float TimeBetweenCameraChanges = 2.0f; const float SmoothBlendTime = 0.75f; TimeToNextCameraChange -= DeltaTime; if (TimeToNextCameraChange <= 0.0f) { TimeToNextCameraChange += TimeBetweenCameraChanges; //Find the actor that handles control for the local player. APlayerController* OurPlayerController = UGameplayStatics::GetPlayerController(this, 0); if (OurPlayerController) { if ((OurPlayerController->GetViewTarget() != CameraOne) && (CameraOne != nullptr)) { //Cut instantly to camera one. OurPlayerController->SetViewTarget(CameraOne); } else if ((OurPlayerController->GetViewTarget() != CameraTwo) && (CameraTwo != nullptr)) { //Blend smoothly to camera two. OurPlayerController->SetViewTargetWithBlend(CameraTwo, SmoothBlendTime); } } } }//设置每两秒跳转一个camera。
然后就是学变量、定时器的行为。
创建一个chutdown的Actor
//倒计时运行时长,按秒计 int32 CountdownTime; UTextRenderComponent* CountdownText; void UpdateTimerDisplay(); void AdvanceTimer(); void CountdownHasFinished(); FTimerHandle CountdownTimerHandle; ///添加类和函数
// 设置默认值 ACountdown::ACountdown() { // 将此 actor 设为每帧调用 Tick()。不需要时可将此关闭,以提高性能。 PrimaryActorTick.bCanEverTick = false; CountdownText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("CountdownNumber")); CountdownText->SetHorizontalAlignment(EHTA_Center); CountdownText->SetWorldSize(150.0f); RootComponent = CountdownText; CountdownTime = 3; } // 游戏开始时或生成时调用 void ACountdown::BeginPlay() { Super::BeginPlay(); UpdateTimerDisplay(); GetWorldTimerManager().SetTimer(CountdownTimerHandle, this, &ACountdown::AdvanceTimer, 1.0f, true); } void ACountdown::UpdateTimerDisplay() { CountdownText->SetText(FString::FromInt(FMath::Max(CountdownTime, 0))); } void ACountdown::AdvanceTimer() { --CountdownTime; UpdateTimerDisplay(); if (CountdownTime < 1) { // 倒计时结束,停止运行定时器。 GetWorldTimerManager().ClearTimer(CountdownTimerHandle); //在定时器结束时按需要执行特殊操作。 CountdownHasFinished(); } } void ACountdown::CountdownHasFinished() { //改为一个特殊的读出 CountdownText->SetText(TEXT("GO!")); } //由于不需要tick,所以在构造函数处把PrimaryActorTick.bCanEverTick置为false。然后设置定时器的长度和结束的时候输出GO!
根据教程制作一个小的FPSdemo
demo分为四个板块。
- [x] 1 - 设置项目
- [x] 2 - 实现角色
- [x] 3 - 实现发射物
- [ ] 4 - 添加角色动画
由于在第4步官方的动画资源问题,导致没办法实现最终的结果。
在这个FPSdemo中,我学会了:
- 设置新项目
- 在 Visual Studio 中打开项目
- 为项目添加日志消息
- 编译首个 C++ 类
- 设置默认游戏模式
- 制作新角色
- 设置轴映射
- 实现角色移动函数
- 实现鼠标摄像机控制
- 实现角色跳跃
- 为角色添加模型
- 更改摄像机视图
- 为角色添加第一人称模型
- 在游戏中添加发射物
- 实现射击
- 设置发射物碰撞和生命周期
- 使发射物和世界场景形成交互
- 在视口中添加准星
- 设置角色动画
- 设置事件图表
- 添加动画状态机
- 为动画添加转换状态
- 将动画蓝图和角色蓝图关联起来
不足的是:在项目的构建过程中遇到非常多问题,有一些是由于官方教程的缺陷,还有一些是由于缺少某些头文件的添加,导致在这个项目的构建过程中花费了很多的时间。
查看UE4的C++编程的介绍
了解了 UObject、AActor、UActorComponent 和 UStruct 的关系。
了解虚幻引擎的一些标记
- UCLASS() - 告知虚幻引擎生成类的反射数据。类必须派生自 UObject。
- USTRUCT() - 告知虚幻引擎生成结构体的反射数据。
- GENERATED_BODY() - UE4 使用它替代为类型生成的所有必需样板文件代码。
- UPROPERTY() - 使 UCLASS 或 USTRUCT 的成员变量可用作 UPROPERTY。UPROPERTY 用途广泛。它允许变量被复制、被序列化,并可从蓝图中进行访问。垃圾回收器还使用它们来追踪对 UObject 的引用数。
UFUNCTION() - 使 UCLASS 或 USTRUCT 的类方法可用作 UFUNCTION。UFUNCTION 允许类方法从蓝图中被调用,并在其他资源中用作 RPC。
UE4的数据类型
- int8/uint8 :8 位带符号/不带符号 整数
- int16/uint16 :16 位带符号/不带符号 整数
- int32/uint32 :32 位带符号/不带符号 整数
int64/uint64 :64 位带符号/不带符号整数
UE4的容器
C++和蓝图(ps:蓝图部分还不是很了解)
从零开始搭建一个UE4(虚幻引擎)的联网Demo:服务器端和客户端(未完成)
编译失败,构建不了demo。于是选择查看另一篇关于服务器和客户端的构建。
首先创建一个第三人称的C++项目。
从文件资源管理器里面打开以前创建的项目文件夹,会有一个名为source的文件夹。打开这个
在里面你会找到一些visual studio源文件。获取其中一个源文件并复制并粘贴它,然后将其重命名以匹配其他文件。格式是gamenameServer.Target.cs所以在我的情况下,因为我的项目游戏名称被称为测试我将我的文件重命名为testServer.Target.cs,所以
右键单击此新创建的文件,然后单击编辑
using UnrealBuildTool; using System.Collections.Generic; [SupportedPlatforms(UnrealPlatformClass.Server)] public class testServerTarget : TargetRules // Change this line as shown previously { public testServerTarget(TargetInfo Target) : base(Target) // Change this line as shown previously { Type = TargetType.Server; bUsesSteam = true; ExtraModuleNames.Add("test"); // Change this line as shown previously } } //UE4.16后可以用这个版本。
在项目文件夹中右键单击uproject文件,弹出菜单时选择“切换虚幻引擎版本”
如果右键单击uproject文件,则不会显示如下所示的菜单
设置用自己编译的UE版本启动。
打开之后,可以选择创建一个空的c++类,让vs完全加载,准备就绪。
转到下拉框,然后在菜单中选择DEVELOPMENT EDITOR
然后转到解决方案资源管理器,然后右键单击并单击构建
再次取决于你的电脑,这可能需要很长时间才能完成。
完成后,返回菜单,然后在下拉框中选择DEVELOPMENT SERVER
然后转到解决方案资源管理器,然后右键单击并单击构建
再次取决于您的计算机,这可能需要很长时间才能完成。
一旦服务器建成,如果你再次进入你的项目文件夹然后点击二进制文件,win64你应该有像这样的服务器文件
然后重新打开UE编辑器,但是很不幸的是我出现了以下这个问题。
上网查询也没有得到结果。用vs编译和用启动器打开都没办法。于是只好重新再处理一遍。
了解RPC
http://api.unrealengine.com/CHN/Gameplay/Networking/Actors/RPCs/index.html
http://km.oa.com/group/17908/articles/show/320848?kmref=search&from_page=1&no=4
看了几篇博客,大概列举三篇,但是还是未能实际应用,所以只是大概了解了一些概念。
下周工作计划 :
- [ ] 熟悉RPC和了解同步的过程。
- [ ] 把服务器的demo跑通并且了解代码的架构
- [ ] 入门蓝图(blueprint)和熟悉事件图表和动画图表。
- [ ] 加深巩固对UE4编辑器的使用方法
- [ ] 熟悉UE4提供的API和使用方法和使用场景
- [ ] 尝试自己脱离教程制作一个小小的demo。