Unreal Engine使用C++入门示例

转载自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  
11 UCLASS()
12  
13 class DEMO__API ACollidingPawn : public APawn
14  
15 {
16  
17     GENERATED_BODY()
18  
19  
20  
21 public:
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  
07 void 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 ?
1 class 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(TEXT("CustomMovementComponent"));
3     OurMovementComponent->UpdatedComponent = RootComponent;
为了让游戏中的其他类知道CollidingPawn目前正在使用CollidingPawnMovementComponent作为移动控制组件,需要在CollidingPawn.h中加入以下代码:

[代码]:

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

[代码]:

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

[代码]:

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

[代码]:

view source
print ?
1 void 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;即可


你可能感兴趣的:(c++)