2.8 - 为角色添加第一人称模型

构建 FPS 游戏的常见方法是使用两个单独的角色模型:一个是完整身体模型,另一个是“武器和手臂”模型。完整身体模型用于从第三人称视角查看角色,然而玩家以第一人称视角观察游戏时它处于隐藏状态。“武器和手臂”模型通常附加到摄像机,玩家以第一人称视角查看关卡时才能看到这个模型。在这步中,我们将为角色添加一个第一人称模型。

添加第一人称角色模型

  1. 切回 Visual Studio,打开 FPSCharacter.h 添加以下代码:

    // 第一人称模型(手臂),仅对拥有玩家可见。
    UPROPERTY(VisibleDefaultsOnly, Category = Mesh)
    USkeletalMeshComponent* FPSMesh;
  2. 打开 FPSCharacter.cpp,前往构造函数,并添加以下代码创建和配置第一人称模型:

    // 为拥有玩家创建一个第一人称模型组件。
    FPSMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FirstPersonMesh"));
    // 该模型仅对拥有玩家可见。
    FPSMesh->SetOnlyOwnerSee(true);
    // 将 FPS 模型添加到 FPS 摄像机。
    FPSMesh->AttachTo(FPSCameraComponent);
    // 禁用部分环境阴影,保留单一模型存在的假象。
    FPSMesh->bCastDynamicShadow = false;
    FPSMesh->CastShadow = false;

    SetOnlyOwnerSee 表明此模型仅对拥有此 CharacterPlayerController 可见。 此代码还将把模型附加到摄像机,并禁用部分环境阴影。 如果附加到摄像机的手臂投射阴影,第一人称角色单个模型存在的假象将不复存在。

  3. 最后,在 FPSCharacter.cpp 里的构建函数中添加以下代码,对拥有角色隐藏现有的第三人称模型:

    // 拥有玩家无法看到普通(第三人称)身体模型。
    GetMesh()->SetOwnerNoSee(true);
  4. 在 Visual Studio 中保存 FPSCharacter 头(*.h)和实现(*.cpp)文件。

  5. Solution Explorer 中找到 FPSProject

  6. 右键单击 FPSProject 并选择 Build 编译项目。

    BuildProject.png

  7. 构建完成后,在 PIE 模式中打开并运行 FPSProject

    HiddenMeshInGame.png

    此时,编辑器中便无法看到角色模型。

构建模型蓝图

从以下链接下载并提取样本模型,然后继续: “第一人称骨架网格体”

  1. 在 Content Browser 文件框中单击右键打开 Import Asset 对话框。

  2. 点击 “Import to /Game...” 打开 Import 对话框。

    RightClickImport.png

  3. 找到并选择 HeroFPP.fbx 模型文件。

  4. 点击 Open 开始导入模型到项目。

  5. FBX Import Options 对话框将出现在 Content Browser 中。点击 Import 将模型添加到项目。

    忽略以下关于平滑组的错误: FBXWarning.png
    此模型仍将展现第一人称模型设置,可用于之后设置的动画。

  6. 点击 Save 按钮保存导入的模型。

  7. 返回 Content Browser 中的 Blueprints 文件夹。

  8. 双击 BP_FPSCharacter 图标将其在 蓝图编辑器 中打开。

  9. Components 标签中找到新建的 FPSMesh 组件。

    LocateFPSMeshComponent.png

    FirstPersonMesh 组件是 FirstPersonCameraComponent 的子项,意味着它将固定被附加到摄像机。

  10. Components 菜单中点击 FirstPersonMesh

  11. 向下滚动到 Details 标签的 Mesh 部分,点击显示为“None”的下拉菜单。 选择 HeroFPP 骨架网格体将手臂添加到 视口

    SelectHeroFPPSkeletalMesh.png

  12. 新增的 HeroFPP 骨架网格体在 视口 中应与下图相似。

    HeroFPPMesh_Viewport.png

  13. 将新增模型的 Location 设为 {240, 0, 35},Rotation 设为 {-180, 50, -180},使其处于摄像机前。

    点击图片放大查看。

  14. 关闭 蓝图编辑器 之前须 编译保存 BP_FPSCharacter 蓝图

在游戏中查看新模型

  1. 点击 关卡编辑器工具栏 中的 Play 按钮在游戏中查看新模型。

    NewMeshInGame.png

  2. 按下 Esc 键或点击关卡编辑器中的 Stop 按钮即可退出 Play in Editor(PIE)模式。

完成分段代码

FPSCharacter.h

// 在 Project Settings 的 Description 页面填入版权声明。

#pragma once

#include "GameFramework/Character.h"
#include "FPSCharacter.generated.h"

UCLASS()
class FPSPROJECT_API AFPSCharacter : public ACharacter
{
    GENERATED_BODY()

public:
    // 设置该角色属性的默认值
    AFPSCharacter();

    // 游戏开始时或生成时调用
    virtual void BeginPlay() override;

    // 每帧调用
    virtual void Tick( float DeltaSeconds ) override;

    // 调用后将功能绑定到输入
    virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;

    // 处理前后移动的输入。
    UFUNCTION()
    void MoveForward(float Value);

    // 处理左右移动的输入。
    UFUNCTION()
    void MoveRight(float Value);

    // 按下按键时设置跳跃标记。
    UFUNCTION()
    void StartJump();

    // 松开按键时清除跳跃标记。
    UFUNCTION()
    void StopJump();

    // FPS 摄像机。
    UPROPERTY(VisibleAnywhere)
    UCameraComponent* FPSCameraComponent;

    // 第一人称模型(手臂),仅对拥有玩家可见。
    UPROPERTY(VisibleDefaultsOnly, Category = Mesh)
    USkeletalMeshComponent* FPSMesh;
};

FPSCharacter.cpp

// 在 Project Settings 的 Description 页面填入版权声明。

#include "FPSProject.h"
#include "FPSCharacter.h"

// 设置默认值
AFPSCharacter::AFPSCharacter()
{
    // 设置此角色每帧调用 Tick()。不需要时可将此关闭,以提高性能。
    PrimaryActorTick.bCanEverTick = true;

    // 创建一个第一人称摄像机组件。
    FPSCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
    // 将摄像机组件附加到胶囊体组件。
    FPSCameraComponent->AttachTo(GetCapsuleComponent());
    // 将摄像机放置在眼睛上方不远处。
    FPSCameraComponent->SetRelativeLocation(FVector(0.0f, 0.0f, 50.0f + BaseEyeHeight));
    // 用 pawn 控制摄像机旋转。
    FPSCameraComponent->bUsePawnControlRotation = true;

    // 为拥有玩家创建一个第一人称模型组件。
    FPSMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FirstPersonMesh"));
    // 该模型仅对拥有玩家可见。
    FPSMesh->SetOnlyOwnerSee(true);
    // 将 FPS 模型添加到 FPS 摄像机。
    FPSMesh->AttachTo(FPSCameraComponent);
    // 禁用部分环境阴影,保留单一模型存在的假象。
    FPSMesh->bCastDynamicShadow = false;
    FPSMesh->CastShadow = false;

    // 拥有玩家无法看到普通(第三人称)身体模型。
    GetMesh()->SetOwnerNoSee(true);
}

// 游戏开始时或生成时调用
void AFPSCharacter::BeginPlay()
{
    Super::BeginPlay();

    if (GEngine)
    {
        // 显示调试信息五秒。-1“键”值(首个参数)说明我们无需更新或刷新此消息。
        GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("We are using FPSCharacter."));
    }
}

// 每帧调用
void AFPSCharacter::Tick( float DeltaTime )
{
    Super::Tick( DeltaTime );

}

// 调用后将功能绑定到输入
void AFPSCharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
    Super::SetupPlayerInputComponent(InputComponent);

    // 设置“移动”绑定。
    InputComponent->BindAxis("MoveForward", this, &AFPSCharacter::MoveForward);
    InputComponent->BindAxis("MoveRight", this, &AFPSCharacter::MoveRight);

    // 设置“查看”绑定。
    InputComponent->BindAxis("Turn", this, &AFPSCharacter::AddControllerYawInput);
    InputComponent->BindAxis("LookUp", this, &AFPSCharacter::AddControllerPitchInput);

    // 设置“动作”绑定。
    InputComponent->BindAction("Jump", IE_Pressed, this, &AFPSCharacter::StartJump);
    InputComponent->BindAction("Jump", IE_Released, this, &AFPSCharacter::StopJump);
}

void AFPSCharacter::MoveForward(float Value)
{
    // 明确哪个方向是“前进”,并记录玩家试图向此方向移动。
    FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::X);
    AddMovementInput(Direction, Value);
}

void AFPSCharacter::MoveRight(float Value)
{
    // 明确哪个方向是“向右”,并记录玩家试图向此方向移动。
    FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::Y);
    AddMovementInput(Direction, Value);
}

void AFPSCharacter::StartJump()
{
    bPressedJump = true;
}

void AFPSCharacter::StopJump()
{
    bPressedJump = false;
}

恭喜!您已学会:

✓ 制作新角色
✓ 设置轴映射
✓ 实现角色移动函数
✓ 实现鼠标摄像机控制
✓ 实现角色跳跃
✓ 为角色添加模型
✓ 更改摄像机视图
✓ 为角色添加第一人称模型

下一部分将学习如何实现发射物。