本周工作总结:

1. 编译环境的搭建visual studio2017安装unrealengine安装:

引擎源码安装:github源码

解压之后,可以看到

ue 编译执行java_UE4

首先点击Setup.bat,这个需要代理才能把资源下载下来。如何设置全局代理KM有人提供了较好的解决方案。大概需要下载5g左右的文件,然后点击GenerateProjectFiles.bat,等待一两分钟后,文件内会生成UE4.sln。用vs2017打开,选择DEVELOPMENT EDITOR ,然后选择UE4,并且生成解决方案。由于是第一次生成,所以耗时非常大,大概花了半个小时才部署好,接着编译,生成了UE4。

ue 编译执行java_虚幻引擎_02

2.开始虚幻引擎4之旅

首先进行的是编程快速入门

ue 编译执行java_UE4_03

通过这个小小的快速入门,让我学会了在虚幻引擎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

ue 编译执行java_ue 编译执行java_04

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可以移动,可以变大变小的控制。

ue 编译执行java_虚幻引擎_05

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的行为。

ue 编译执行java_虚幻引擎_06

// 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。
然后就是学变量、定时器的行为。

ue 编译执行java_虚幻引擎_07

创建一个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分为四个板块。

由于在第4步官方的动画资源问题,导致没办法实现最终的结果。

在这个FPSdemo中,我学会了:

  • 设置新项目
  • 在 Visual Studio 中打开项目
  • 为项目添加日志消息
  • 编译首个 C++ 类
  • 设置默认游戏模式
  • 制作新角色
  • 设置轴映射
  • 实现角色移动函数
  • 实现鼠标摄像机控制
  • 实现角色跳跃
  • 为角色添加模型
  • 更改摄像机视图
  • 为角色添加第一人称模型
  • 在游戏中添加发射物
  • 实现射击
  • 设置发射物碰撞和生命周期
  • 使发射物和世界场景形成交互
  • 在视口中添加准星
  • 设置角色动画
  • 设置事件图表
  • 添加动画状态机
  • 为动画添加转换状态
  • 将动画蓝图和角色蓝图关联起来

不足的是:在项目的构建过程中遇到非常多问题,有一些是由于官方教程的缺陷,还有一些是由于缺少某些头文件的添加,导致在这个项目的构建过程中花费了很多的时间。

查看UE4的C++编程的介绍
  • 了解了 UObjectAActorUActorComponentUStruct 的关系。
  • 了解虚幻引擎的一些标记
  • 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编辑器,但是很不幸的是我出现了以下这个问题。

ue 编译执行java_右键_08


ue 编译执行java_虚幻引擎_09

上网查询也没有得到结果。用vs编译和用启动器打开都没办法。于是只好重新再处理一遍。

  • 了解RPC

看了几篇博客,大概列举三篇,但是还是未能实际应用,所以只是大概了解了一些概念。

ue 编译执行java_带符号_10

下周工作计划 :

  • [ ] 熟悉RPC和了解同步的过程。
  • [ ] 把服务器的demo跑通并且了解代码的架构
  • [ ] 入门蓝图(blueprint)和熟悉事件图表和动画图表。
  • [ ] 加深巩固对UE4编辑器的使用方法
  • [ ] 熟悉UE4提供的API和使用方法和使用场景
  • [ ] 尝试自己脱离教程制作一个小小的demo。