当前位置:   article > 正文

UE4入门以及用源码编译_ue4 源码编译

ue4 源码编译

本周工作总结:

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);
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 接着进行的是玩家输入和Pawns

    这里写图片描述

    UPROPERTY(EditAnywhere)   //使OurVisibleComponent在UE编辑器中可以编辑。
    USceneComponent* OurVisibleComponent;
    
    // 输入函数
    void Move_XAxis(float AxisValue);
    void Move_YAxis(float AxisValue);
    void StartGrowing();
    void StopGrowing();
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    // 调用以绑定功能到输入
    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可以移动,可以变大变小的控制。
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    这里写图片描述

    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的动作。
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    最后实现了,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。
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
  • 然后就是学变量、定时器的行为。

    这里写图片描述

    创建一个chutdown的Actor

    //倒计时运行时长,按秒计
      int32 CountdownTime;
    
      UTextRenderComponent* CountdownText;
    
      void UpdateTimerDisplay();
    
      void AdvanceTimer();
    
      void CountdownHasFinished();
    
      FTimerHandle CountdownTimerHandle;
    ///添加类和函数
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    // 设置默认值
    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!
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
  • 根据教程制作一个小的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的文件夹。打开这个

    Sourcefolder.png

    在里面你会找到一些visual studio源文件。获取其中一个源文件并复制并粘贴它,然后将其重命名以匹配其他文件。格式是gamenameServer.Target.cs所以在我的情况下,因为我的项目游戏名称被称为测试我将我的文件重命名为testServer.Target.cs,所以

    Testserver.png

    右键单击此新创建的文件,然后单击编辑

    Editfile.png

    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后可以用这个版本。
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在项目文件夹中右键单击uproject文件,弹出菜单时选择“切换虚幻引擎版本”

    如果右键单击uproject文件,则不会显示如下所示的菜单

    Build server.png

    设置用自己编译的UE版本启动。

    打开之后,可以选择创建一个空的c++类,让vs完全加载,准备就绪。

    转到下拉框,然后在菜单中选择DEVELOPMENT EDITOR

    Developmenteditor.png

    然后转到解决方案资源管理器,然后右键单击并单击构建

    Buildserver.png

    再次取决于你的电脑,这可能需要很长时间才能完成。

    完成后,返回菜单,然后在下拉框中选择DEVELOPMENT SERVER

    Development server.png

    然后转到解决方案资源管理器,然后右键单击并单击构建

    Buildserver.png

    再次取决于您的计算机,这可能需要很长时间才能完成。

    一旦服务器建成,如果你再次进入你的项目文件夹然后点击二进制文件,win64你应该有像这样的服务器文件

    Serverfiles.png

    然后重新打开UE编辑器,但是很不幸的是我出现了以下这个问题。

    这里写图片描述
    这里写图片描述

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

  • 了解RPC

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

    这里写图片描述

下周工作计划 :

  • [ ] 熟悉RPC和了解同步的过程。
  • [ ] 把服务器的demo跑通并且了解代码的架构
  • [ ] 入门蓝图(blueprint)和熟悉事件图表和动画图表。
  • [ ] 加深巩固对UE4编辑器的使用方法
  • [ ] 熟悉UE4提供的API和使用方法和使用场景
  • [ ] 尝试自己脱离教程制作一个小小的demo。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/91329
推荐阅读
相关标签
  

闽ICP备14008679号