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:
[代码]:
05 | #include "GameFramework/Pawn.h" |
07 | #include "CollidingPawn.generated.h" |
13 | class DEMO__API ACollidingPawn : public APawn |
31 | virtual void BeginPlay() override ; |
37 | virtual void Tick( float DeltaSeconds ) override ; |
43 | virtual void SetupPlayerInputComponent( class UInputComponent* InputComponent) override ; |
接下来,我们在原来的基础上,来实现按键控制物体的小程序 先创建一个可见的球体: 在CollidingPawn.cpp的构造函数ACollidingPawn::ACollidingPawn()中添加一个球体,一个网格组件(mesh),一个弹簧臂和相机,代码如下:
[代码]:
03 | USphereComponent* SphereComponent = CreateDefaultSubobject(TEXT( "RootComponent" )); |
07 | RootComponent = SphereComponent; |
11 | SphereComponent->InitSphereRadius(40.0f); |
13 | SphereComponent->SetCollisionProfileName(TEXT( "Pawn" )); |
19 | UStaticMeshComponent* SphereVisual = CreateDefaultSubobject(TEXT( "VisualRepresentation" )); |
23 | SphereVisual->AttachTo(RootComponent); |
25 | static ConstructorHelpers::FObjectFinder SphereVisualAsset(TEXT( "/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere" )); |
27 | if (SphereVisualAsset.Succeeded()){ |
29 | SphereVisual->SetStaticMesh(SphereVisualAsset.Object); |
31 | SphereVisual->SetRelativeLocation(FVector(0.0f, 0.0f, -40.0f)); |
33 | SphereVisual->SetWorldScale3D(FVector(0.8f)); |
43 | USpringArmComponent* SpringArm = CreateDefaultSubobject(TEXT( "CameraAttachmentArm" )); |
45 | SpringArm->AttachTo(RootComponent); |
47 | SpringArm->RelativeRotation = FRotator(-45.f, 0.f, 0.f); |
49 | SpringArm->TargetArmLength = 400.0f; |
51 | SpringArm->bEnableCameraLag = true ; |
53 | SpringArm->CameraLagSpeed = 3.f; |
61 | UCameraComponent* Camera = CreateDefaultSubobject(TEXT( "ActualCamera" )); |
63 | Camera->AttachTo(SpringArm, USpringArmComponent::SocketName); |
然后配置按键: 打开ue编辑器, 选择编辑->项目设置-> 输入, 然后在右边的axis mappings加入如下设置: MoveForWard,MoveRight,Turn,Turn_Y 可自定义,表示跟各个按键的绑定关系。 然后创建一个类CollidingPawnMovementComponent继承自PawnMovementComponent(控制pawn移动的组件),我们可以把WASD绑定的行为绑定到这个component上,然后把该component绑定到我们刚才创建的球体上: CollidingPawnMovementComponent.cpp
[代码]:
03 | #include "CollidingPawnMovementComponent.h" |
07 | void UCollidingPawnMovementComponent::TickComponent( float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) |
11 | Super::TickComponent(DeltaTime, TickType, ThisTickFunction); |
17 | if (!PawnOwner || !UpdatedComponent || ShouldSkipUpdate(DeltaTime)) |
29 | FVector DesiredMovementThisFrame = ConsumeInputVector().GetClampedToMaxSize(1.0f) * DeltaTime * 150.0f; |
31 | if (!DesiredMovementThisFrame.IsNearlyZero()) |
37 | SafeMoveUpdatedComponent(DesiredMovementThisFrame, UpdatedComponent->GetComponentRotation(), true , Hit); |
43 | if (Hit.IsValidBlockingHit()) |
47 | SlideAlongSurface(DesiredMovementThisFrame, 1.f - Hit.Time, Hit.Normal, Hit); |
然后在CollidingPawn.h中加入如下代码:
[代码]:
1 | class UCollidingPawnMovementComponent* OurMovementComponent; |
先将movementComponent绑定到刚才加的球体上,在CollidingPawn构造函数底部加入如下代码:
[代码]:
2 | OurMovementComponent = CreateDefaultSubobject<ucollidingpawnmovementcomponent>(TEXT( "CustomMovementComponent" )); |
3 | OurMovementComponent->UpdatedComponent = RootComponent;</ucollidingpawnmovementcomponent> |
为了让游戏中的其他类知道CollidingPawn目前正在使用CollidingPawnMovementComponent作为移动控制组件,需要在CollidingPawn.h中加入以下代码:
[代码]:
1 | virtual UPawnMovementComponent* GetMovementComponent() const override ; |
然后在CollidingPawn.cpp中加入:
[代码]:
1 | UPawnMovementComponent* ACollidingPawn::GetMovementComponent() const |
3 | return OurMovementComponent; |
刚才我们已经将新创建的移动控制组件绑定到了球体上,现在需要把WASD触发的函数绑定到移动组件上,在CollidingPawn中实现往前移动,往左移动,转动视角的三个方法:
[代码]:
02 | void ACollidingPawn::MoveForward( float AxisValue) |
04 | if (OurMovementComponent && (OurMovementComponent->UpdatedComponent == RootComponent)) |
06 | OurMovementComponent->AddInputVector(GetActorForwardVector() * AxisValue); |
11 | void ACollidingPawn::MoveRight( float AxisValue) |
13 | if (OurMovementComponent && (OurMovementComponent->UpdatedComponent == RootComponent)) |
15 | OurMovementComponent->AddInputVector(GetActorRightVector() * AxisValue); |
20 | void ACollidingPawn::Turn( float AxisValue) |
22 | FRotator NewRotation = GetActorRotation(); |
23 | NewRotation.Yaw += AxisValue; |
24 | SetActorRotation(NewRotation); |
然后将这三个方法在ACollidingPawn::SetupPlayerInputComponent中注册:
[代码]:
1 | void ACollidingPawn::SetupPlayerInputComponent( class UInputComponent* InputComponent) |
3 | Super::SetupPlayerInputComponent(InputComponent); |
5 | InputComponent->BindAxis( "MoveForward" , this , &ACollidingPawn::MoveForward); |
6 | InputComponent->BindAxis( "MoveRight" , this , &ACollidingPawn::MoveRight); |
7 | InputComponent->BindAxis( "Turn" , this , &ACollidingPawn::Turn); |
以上就完成了一个可用WASD移动和鼠标控制左右视角的球体
如果上下移动视角,可仿照以上的ACollidingPawn::Turn方法,将NewRotation.Yaw += AxisValue; 改为NewRotation.Pitch += AxisValue;即可
|