Unreal Engine使用C++入门示例

来源:互联网 发布:公安部网络安全局 编辑:程序博客网 时间:2024/05/17 01:52

转载自52VR 原文章链接http://www.52vr.com/article-639-1.html

epic games宣布ue4免费使用之后,吸引了大批看好VR和AR前景的游戏开发者。

不过国内ue4教程和资料太少,而且一大部分资料都是关于蓝图(Blueprint)的,好在官网放出了guide和demo。更多讨论,可以前往讨论区:http://www.52vr.com/forum-93-1.html


本文先演示一个如何在UnrealEngine上创建一个C++项目,然后实现一个可用按键控制物体的示例:

1. 安装Unreal Engine,在此不做详细说明。从官网上下载安装,然后注册epic games账号。如果要下源码,需要绑定Github账号,等到EpicGames自动邀请之后才能浏览源码。


2. 新建项目:

安装好之后,启动UnrealEngine,选择 新建项目-> c++ -> 基础代码

 

等加载完之后,选择文件->新建c++类,然后在如下界面选择继承Pawn(Pawn是可由玩家控制或者AI控制的物体的基类):


我在创建的时候取类名为CollidingPawn,  创建完之后会自动打开vs2012(如果没装会提示你装一个,其他版本比如vs2015也不行,只能是2012),生成一个CollidingPawn.cpp和CollidingPawn.h。

头文件如下所示, 我按照自己的理解加了注释:

CollidingPawn.h:

  

[代码]:

view source
print?
01#pragma once
02 
03 
04 
05#include "GameFramework/Pawn.h"
06 
07#include "CollidingPawn.generated.h"
08 
09 
10 
11UCLASS()
12 
13class DEMO__API ACollidingPawn : public APawn
14 
15{
16 
17    GENERATED_BODY()
18 
19 
20 
21public:
22 
23    // 构造函数,可在此方法中放置物体和参数
24 
25    ACollidingPawn();
26 
27 
28 
29    // 游戏开始调用此方法
30 
31    virtual void BeginPlay() override;
32 
33     
34 
35    // 如果PrimaryActorTick.bCanEverTick设置为true,则每一帧都会调用此方法。如果处于性能的考虑,可以将其关闭。
36 
37    virtual void Tick( float DeltaSeconds ) override;
38 
39 
40 
41    // 在此函数中绑定按键和方法
42 
43    virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;
44 
45};



接下来,我们在原来的基础上,来实现按键控制物体的小程序

先创建一个可见的球体:

在CollidingPawn.cpp的构造函数ACollidingPawn::ACollidingPawn()中添加一个球体,一个网格组件(mesh),一个弹簧臂和相机,代码如下:


[代码]:

view source
print?
01//创建一个球体
02 
03    USphereComponent* SphereComponent = CreateDefaultSubobject(TEXT("RootComponent"));
04 
05    //设置为根组件
06 
07    RootComponent = SphereComponent;
08 
09    //设置半径
10 
11    SphereComponent->InitSphereRadius(40.0f);
12 
13    SphereComponent->SetCollisionProfileName(TEXT("Pawn"));
14 
15 
16 
17    // 创建并放置网格物体组件,这样我们能看到球体的位置
18 
19    UStaticMeshComponent* SphereVisual = CreateDefaultSubobject(TEXT("VisualRepresentation"));
20 
21    //如果不把网格附加到SphereComponent 就看不到球体
22 
23    SphereVisual->AttachTo(RootComponent);
24 
25    static ConstructorHelpers::FObjectFinder      SphereVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere"));
26 
27    if (SphereVisualAsset.Succeeded()){
28 
29        SphereVisual->SetStaticMesh(SphereVisualAsset.Object);
30 
31        SphereVisual->SetRelativeLocation(FVector(0.0f, 0.0f, -40.0f));
32 
33        SphereVisual->SetWorldScale3D(FVector(0.8f));
34 
35    }
36 
37 
38 
39    //  使用弹簧臂来让相机获得一种平滑、自然的运动。
40 
41    //  弹簧臂的目的是让视角跟SphereComponent保持一定距离,如果不加,效果像fps游戏的第一视角一样
42 
43    USpringArmComponent* SpringArm = CreateDefaultSubobject(TEXT("CameraAttachmentArm"));
44 
45    SpringArm->AttachTo(RootComponent);
46 
47    SpringArm->RelativeRotation = FRotator(-45.f, 0.f, 0.f); //45度角
48 
49    SpringArm->TargetArmLength = 400.0f; //弹簧臂长度
50 
51    SpringArm->bEnableCameraLag = true;
52 
53    SpringArm->CameraLagSpeed = 3.f;
54 
55 
56 
57    // 创建相机并附加到弹簧臂
58 
59    // 如果没有相机 什么都看不到
60 
61    UCameraComponent* Camera = CreateDefaultSubobject(TEXT("ActualCamera"));
62 
63    Camera->AttachTo(SpringArm, USpringArmComponent::SocketName);



然后配置按键: 打开ue编辑器, 选择编辑->项目设置-> 输入, 然后在右边的axis mappings加入如下设置:

MoveForWard,MoveRight,Turn,Turn_Y 可自定义,表示跟各个按键的绑定关系。

然后创建一个类CollidingPawnMovementComponent继承自PawnMovementComponent(控制pawn移动的组件),我们可以把WASD绑定的行为绑定到这个component上,然后把该component绑定到我们刚才创建的球体上:

CollidingPawnMovementComponent.cpp


  

[代码]:

view source
print?
01#include "Demo.h"
02 
03#include "CollidingPawnMovementComponent.h"
04 
05 
06 
07void UCollidingPawnMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
08 
09{
10 
11    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
12 
13 
14 
15    // Make sure that everything is still valid, and that we are allowed to move.
16 
17    if (!PawnOwner || !UpdatedComponent || ShouldSkipUpdate(DeltaTime))
18 
19    {
20 
21        return;
22 
23    }
24 
25 
26 
27    // Get (and then clear) the movement vector that we set in ACollidingPawn::Tick
28 
29    FVector DesiredMovementThisFrame = ConsumeInputVector().GetClampedToMaxSize(1.0f) * DeltaTime * 150.0f;
30 
31    if (!DesiredMovementThisFrame.IsNearlyZero())
32 
33    {
34 
35        FHitResult Hit;
36 
37        SafeMoveUpdatedComponent(DesiredMovementThisFrame, UpdatedComponent->GetComponentRotation(), true, Hit);
38 
39 
40 
41        // If we bumped into something, try to slide along it
42 
43        if (Hit.IsValidBlockingHit())
44 
45        {
46 
47            SlideAlongSurface(DesiredMovementThisFrame, 1.f - Hit.Time, Hit.Normal, Hit);
48 
49        }
50 
51    }
52 
53};


然后在CollidingPawn.h中加入如下代码:

[代码]:

view source
print?
1class UCollidingPawnMovementComponent* OurMovementComponent;
先将movementComponent绑定到刚才加的球体上,在CollidingPawn构造函数底部加入如下代码:

[代码]:

view source
print?
1// Create an instance of our movement component, and tell it to update the root.
2    OurMovementComponent = CreateDefaultSubobject<ucollidingpawnmovementcomponent>(TEXT("CustomMovementComponent"));
3    OurMovementComponent->UpdatedComponent = RootComponent;</ucollidingpawnmovementcomponent>
为了让游戏中的其他类知道CollidingPawn目前正在使用CollidingPawnMovementComponent作为移动控制组件,需要在CollidingPawn.h中加入以下代码:

[代码]:

view source
print?
1virtual UPawnMovementComponent* GetMovementComponent() const override;
然后在CollidingPawn.cpp中加入:

[代码]:

view source
print?
1UPawnMovementComponent* ACollidingPawn::GetMovementComponent() const
2{
3    return OurMovementComponent;
4}
刚才我们已经将新创建的移动控制组件绑定到了球体上,现在需要把WASD触发的函数绑定到移动组件上,在CollidingPawn中实现往前移动,往左移动,转动视角的三个方法:

[代码]:

view source
print?
01// 往前(后)移动
02void ACollidingPawn::MoveForward(float AxisValue)
03{
04    if (OurMovementComponent && (OurMovementComponent->UpdatedComponent == RootComponent))
05    {
06        OurMovementComponent->AddInputVector(GetActorForwardVector() * AxisValue);
07    }
08}
09 
10// 往左(右)移动
11void ACollidingPawn::MoveRight(float AxisValue)
12{
13    if (OurMovementComponent && (OurMovementComponent->UpdatedComponent == RootComponent))
14    {
15        OurMovementComponent->AddInputVector(GetActorRightVector() * AxisValue);
16    }
17}
18 
19// 左右转动视角
20void ACollidingPawn::Turn(float AxisValue)
21{
22    FRotator NewRotation = GetActorRotation();
23    NewRotation.Yaw += AxisValue;
24    SetActorRotation(NewRotation);
25}
然后将这三个方法在ACollidingPawn::SetupPlayerInputComponent中注册:

[代码]:

view source
print?
1void ACollidingPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent)
2{
3    Super::SetupPlayerInputComponent(InputComponent);
4 
5    InputComponent->BindAxis("MoveForward", this, &ACollidingPawn::MoveForward);
6    InputComponent->BindAxis("MoveRight", this, &ACollidingPawn::MoveRight);
7    InputComponent->BindAxis("Turn", this, &ACollidingPawn::Turn);
8}
以上就完成了一个可用WASD移动和鼠标控制左右视角的球体
如果上下移动视角,可仿照以上的ACollidingPawn::Turn方法,将NewRotation.Yaw += AxisValue; 改为NewRotation.Pitch += AxisValue;即可


0 0