重生玩家角色

在虚幻引擎中如何重生角色的操作指南。

Windows
MacOS
Linux

在游戏项目中,有时玩家角色会在游戏中"销毁",然后需要在场景中重生。

在本指南中,你将学习如何使用第三人称模板搭建一个简单的重生系统,可用于单人游戏。你需要在游戏模式(Game Mode)类中实现部分功能,以便第三人称玩家在关卡中重生。

image alt text

选择实现方法:

Blueprints

C++

项目设置

你可以从搭建第三人称模板开始,在项目设置中设置输入映射。这些输入映射会启用重新生成功能,你可以为玩家角色创建该功能。

  1. 首先,通过 游戏(Games) > 第三人称>蓝图(Third Person > Blueprint)创建名为 重新生成玩家(RespawnPlayer) 的新项目。

    image alt text

  2. 找到 编辑(Edit) > 项目设置(Project Settings) > 引擎(Engine)> 输入(Input),然后在 细节(Details) 面板的 绑定(Bindings) 类目中点击 动作映射(Action Mappings) 变量旁的 添加(+) 按钮,新建名为 重新开始(Restart) 的动作映射。

    image alt text

  3. 将重新开始动作映射的键值设为 R

    image alt text

执行重生玩家游戏模式类

在本示例中,游戏模式类负责在当玩家角色在游戏中死亡时,重生玩家角色类。你可以通过使用事件分发器实现此功能。

  1. 内容浏览器(Content Browser) 中找到 内容>第三人称蓝图(Content > ThirdPersonBP) 并双击 第三人称游戏模式(ThirdPersonGameMode) 蓝图并打开 类默认值(Class Defaults)

    image alt text

  2. 在类默认值中,点击 打开完整蓝图编辑器(Open Full Blueprint Editor) 链接。

    image alt text

  3. 我的蓝图(My Blueprint) 面板中找到 事件分发器(Event Dispatchers) 类别并点击 添加(+) ,创建一个新的名为 OnPlayerDied事件分发器

    image alt text

  4. 来到 细节(Details) 面板中,在 输入(Inputs) 类目中点击 添加(+) 按钮,创建蓝图类型角色的 新输入参数(New Input Parameter) 并将它命名为 角色(Character)

    image alt text

  5. 右击(Right-click) 事件图表(Event Graph) 打开 操作(Actions) 菜单,搜索并选择 事件开始运行(Event BeginPlay)

    image alt text

  6. 拖拽 开始运行(Begin Play) 节点的 执行引脚(execution pin),然后在 操作(Actions) 菜单中搜索并选择 Bind Event On Player Died 节点。

    image alt text

  7. 拖拽 Bind Event to On Player Died 节点的 事件(Event) 引脚,然后在 操作(Actions) 菜单中搜索并选择 添加自定义事件(Add Custom Event) 并将其命名为 PlayerDied

    image alt text

    你已经创建并将 事件(Event) 绑定到 了**自定义事件(Custom Event) 中,目的是从另一个 蓝图(Blueprint)** 中调用它。

    当事件在另一个蓝图中出现时,例如第三人称蓝图类中的 OnDestroy 事件,此项操作会在该蓝图中触发事件。这被称为 事件分发器(Event Dispatcher)

    如需附加文档,请参见事件分发器事件分发器快速入门

  8. 拖拽 PlayerDied Custom Event 节点的 角色(Character) 引脚,然后在 操作(Actions) 下拉菜单中搜索并选择 获取控制器(Get Controller) 节点。

    image alt text

  9. 拖拽 PlayerDied 节点的 执行引脚(execution pin),然后在 操作(Actions) 菜单中搜索并选择 重生玩家(Restart Player) 功能。

    image alt text

  10. 拖拽 获取控制器(Get Controller) 节点的 返回值(Return Value) 输出引脚,并连接到 重生玩家(RestartPlayer) 节点的 新玩家(New Player) 输入引脚。

    image alt text

    重生玩家是已经在游戏模式基础(GameModeBase)类中的解决方法。它会试图在由找到玩家起点返回的位置处生成玩家Pawn。

  11. 点击 编译(Compile)保存(Save)

    image alt text

完成后的蓝图

image alt text

执行重生玩家角色类

你现在可以执行逻辑来摧毁重生玩家角色,并启用游戏模式的重启玩家方式。

  1. 内容浏览器(Content Browser) 中找到 内容>第三人称蓝图(Content > ThirdPersonBP) 并双击 第三人称角色(ThirdPersonCharacter) 打开 类默认项(Class Defaults)

    image alt text

  2. 我的蓝图(My Blueprint) 面板中,找到 函数(Functions) 类目并选择 重载(Override) 按钮。接着,从下拉菜单中选择**已销毁(Destroyed)重载函数(Override Function)**。

    image alt text

    当选中函数类目下的重载按钮时,每个函数列举出类,角色的重载继承自这些类。此处列出了已销毁事件,因为角色类继承自Actor 类,而Actor类中包含了已销毁(Destroyed)函数。

  3. 拖拽 事件已销毁(Event Destroyed) 执行引脚,在 操作(Actions) 菜单中搜索并选择 转换至第三人称游戏模式(Cast to Third Person Game Mode)

    image alt text

  4. 拖拽 转换至第三人称游戏模式(Cast to Third Person Game Mode) 节点的 对象(Object) 引脚,搜索并选择 获取游戏模式(Get Game Mode) 节点。

    image alt text

  5. 拖拽 第三人称游戏模式(Third Person Game Mode) 节点的 作为第三人称游戏模式(As Third Person Game mode) 引脚,然后搜索并选择 Call On Player Died 事件分发器。

    image alt text

  6. 拖拽 Call On Player Died 节点的 角色引脚(Character pin) ,在 操作(Actions) 菜单中搜索并选择 获取对自身的引用(Get a reference to self)

    image alt text

  7. 我的蓝图(My Blueprint) 选项卡中,找到 函数(Functions) 类目并勾选 添加(+) 按钮,创建名为 调用重生玩家(Call Restart Player) 的新函数。

    image alt text

  8. 双击 调用重生玩家(Call Restart Player) 找到 本地变量(Local Variables) 类目并点击 添加(+) 按钮,创建新本地函数类型 控制器(Controller) 并命名为 ControllerRef

    image alt text

  9. ControllerRef 变量拖拽到 调用重生玩家(Call Restart Player) 节点的 执行引脚(Execution pin) 上。

    image alt text

  10. 拖拽 ControllerRef 引脚,在 操作(Actions) 菜单中搜索并选择 Pawn类别(Pawn category)获取控制器(Get Controller)

    image alt text

  11. 回到 Set ControllerRef 节点中,拖拽 执行引脚(execution pin) ,在 操作(Actions) 菜单中搜索并选择 销毁Actor(DestroyActor)

    image alt text

  12. 拖拽 销毁Actor(Destroy Actor) 节点的执行引脚,在 操作(Actions) 菜单中,搜索并选择 转换至第三人称游戏模式(Cast to Third Person Game Mode)

    image alt text

  13. 拖拽 转换至第三人称游戏模式(Cast to Third Person Game Mode) 节点的 对象(Object) 引脚,搜索并选择 获取游戏模式(Get Game Mode) 节点。

    image alt text

  14. 拖拽 第三人称游戏模式(Third Person Game Mode) 节点的 作为第三人称游戏模式(As Third Person Game mode) 引脚,然后搜索并选择重生玩家( RestartPlayer)。

    image alt text

  15. 我的蓝图(My Blueprint) 面板中,找到 本地变量(Local Variables) 类目,将 ControllerRef 的副本拖拽到 重生玩家(Restart Player) 节点的 新玩家(New Player) 引脚上。

    image alt text

  16. 点击 编译(Compile)保存(Save)

    image alt text

    完成调用重生玩家函数后如下图所示。

    image alt text

  17. 回到 事件图表(Event Graph),然后右击搜索并选择 重新开始(Restart) 输入操作事件。

    image alt text

  18. 拖拽 按下键(Pressed key) 引脚,然后在**操作(Actions) 菜单中,搜索并选择 调用重启玩家(Call Restart Player)**。

    image alt text

    调用重启玩家(Call Restart Player)函数会销毁你的玩家角色,按下 R 键就会触发。在会让角色消失的Gameplay事件中,当玩家在失去一定的生命值时将会触发 销毁(Destroy) 方式。

  19. 选择 编译(Compile)保存(Save)

    image alt text

完成后的蓝图

image alt text

最终结果

回到编辑器并选择 在编辑器中运行(Play in Editor)PIE)。

你可以使用W、A、S、D键来控制角色在地图中的移动。

当按下 R 键时,你的玩家角色会立即消失,然后在 玩家出生点(Player Start Location) 重生。

image alt text

项目设置

首先,你需要创建一个新的第三人称模板,并通过项目设置来设置输入映射。这些输入映射将启用你要为玩家角色创建的重生功能。

  1. 首先,点击 游戏(Games) > 第三人称(Third Person)>C++项目(C++ project),创建名为 RespawnPlayer 的项目。

    ![image alt text](image_1. png)(convert:false)

  2. 前往 编辑(Edit) > 项目设置(Project Settings) > 引擎(Engine) > 输入(Input),然后在 细节(Details) 面板的 绑定(Bindings) 类别中,点击 操作映射(Action Mappings) 变量旁边的 添加(Add)(+) 按钮,创建名为 Restart 的新操作映射。

    image alt text

  3. 将Restart操作映射键值设置为 R

    image alt text

实现RespawnPlayerGameMode类

在此示例中,GameMode类负责在玩家角色在游戏过程中被销毁时重新生成玩家角色类。你将负责通过使用委托来实现此功能。

  1. 内容浏览器(Content Browser) 中,前往你的 C++类(C++ Classes) 文件夹,双击 RespawnPlayerGameMode 打开 RespawnPlayerGameMode.h

    image alt text

  2. RespawnPlayerGameMode.h 文件中,在你的库include声明下声明以下代码:

    DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPlayerDiedSignature, ACharacter*, Character);

    当玩家角色死亡时,此操作为你要绑定的游戏模式类将创建动态组播委托 FOnPlayerDiedSignature。

  3. 然后,声明以下类声明:

    public:
        const FOnPlayerDiedSignature& GetOnPlayerDied() const { returnOnPlayerDied; }
    
        //尝试生成玩家的Pawn。
        virtual void RestartPlayer(AController* NewPlayer) override;
    
    protected:
        virtual void BeginPlay() override;
    
        //在玩家角色死亡时调用。
        UFUNCTION()
        virtual void PlayerDied(ACharacter* Character);
    
        //要绑定委托的签名。 
        UPROPERTY()
        FOnPlayerDiedSignature OnPlayerDied;

    RestartPlayer是GameModeBase类中已经存在的方法。它会尝试在FindPlayerStart返回的位置上生成玩家的Pawn。

  4. 找到你的 RespawnPlayerGameMode.cpp 文件并实现以下类方法

    void ARespawnPlayerGameMode::BeginPlay()
    {
        Super::BeginPlay();
    
        //将我们的玩家已死亡委托绑定到GameMode的PlayerDied函数。
        if (!OnPlayerDied.IsBound())
        {
            OnPlayerDied.AddDynamic(this, &ARespawnPlayerGameMode::PlayerDied);
        }
    
    }
    
    void ARespawnPlayerGameMode::RestartPlayer(AController* NewPlayer)
    {
        Super::RestartPlayer(NewPlayer);
    }
    
    void ARespawnPlayerGameMode::PlayerDied(ACharacter* Character)
    {
        //获得角色玩家控制器的引用
        AController* CharacterController = Character->GetController();
        RestartPlayer(CharacterController);
    }
  5. 编译你的代码。

已完成代码

RespawnPlayerGameMode.h

//版权所有Epic Games, Inc。保留所有权利。
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "RespawnPlayerGameMode.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPlayerDiedSignature, ACharacter*, Character);

UCLASS(minimalapi)

class ARespawnPlayerGameMode : public AGameModeBase
{
    GENERATED_BODY()

public:

    ARespawnPlayerGameMode();

    const FOnPlayerDiedSignature& GetOnPlayerDied() const { return OnPlayerDied; }

//尝试生成玩家的Pawn。
virtual void RestartPlayer(AController* NewPlayer) override;

protected:

    virtual void BeginPlay() override;

    //在玩家角色死亡时调用。
    UFUNCTION()
    virtual void PlayerDied(ACharacter* Character);

    //要绑定委托的签名。 
    UPROPERTY()
    FOnPlayerDiedSignature OnPlayerDied;
};

RespawnPlayerGameMode.cpp

#include "RespawnPlayerGameMode.h"
#include "RespawnPlayerCharacter.h"
#include "UObject/ConstructorHelpers.h"

ARespawnPlayerGameMode::ARespawnPlayerGameMode()
{
    //将默认Pawn类设置为已绘制蓝图的角色
    static ConstructorHelpers::FClassFinder<APawn> PlayerPawnBPClass(TEXT("/Game/ThirdPersonCPP/Blueprints/ThirdPersonCharacter"));
    if (PlayerPawnBPClass.Class != NULL)
    {
        DefaultPawnClass = PlayerPawnBPClass.Class;
    }
}

void ARespawnPlayerGameMode::BeginPlay()
{
    Super::BeginPlay();

    //将我们的玩家已死亡委托绑定到GameMode的PlayerDied函数。
    if (!OnPlayerDied.IsBound())
    {
        OnPlayerDied.AddDynamic(this, &ARespawnPlayerGameMode::PlayerDied);
    }

}

void ARespawnPlayerGameMode::RestartPlayer(AController* NewPlayer)
{
    Super::RestartPlayer(NewPlayer);
}

void ARespawnPlayerGameMode::PlayerDied(ACharacter* Character)
{
    //获得角色玩家控制器的引用
    AController* CharacterController = Character->GetController();
    RestartPlayer(CharacterController);
}

实现RespawnPlayerCharacter

现在,你将负责实现用于销毁RespawnPlayerCharacter的逻辑,并通过RespawnPlayerGameMode的类实现重生。

  1. 内容浏览器(Content Browser) 中,前往你的 C++类(C++ Classes) 文件夹,双击 RespawnPlayerCharacter 打开 RespawnPlayerCharacter.h 文件。

    image alt text

  2. RespawnPlayerCharacter.h 文件中,声明以下代码:

    protected:
    
        //当我们的Actor在游戏过程中被销毁时调用。
        virtual void Destroyed();
    
        //调用GameMode类以重新启动玩家角色。
        void CallRestartPlayer();

    在此声明中,已销毁的方法被标记为 virtual,因为角色类是从Actor类继承的,该类包含自身的已销毁的方法。

  3. 找到你的RespawnPlayerCharacter.cpp文件,然后声明以下类库include:

    #include "RespawnPlayerGameMode.h"

    你将需要包含GameMode库声明,以便在稍后从玩家角色类调用其类功能。

  4. 然后,添加以下RespawnPlayerCharacter类方法。

    void ARespawnPlayerCharacter::Destroyed()
    {
        Super::Destroyed();
    
        //关于绑定至GameMode中的OnPlayerDied事件的示例 
        if (UWorld* World = GetWorld())
        {
            if (ARespawnPlayerGameMode* GameMode = Cast<ARespawnPlayerGameMode>(World->GetAuthGameMode()))
            {
                GameMode->GetOnPlayerDied().Broadcast(this);
            }
        }
    }
    
    void ARespawnPlayerCharacter::CallRestartPlayer()
    {
        // 获得Pawn控制器的引用。
        AController* CortollerRef = GetController();
    
        //销毁玩家  
        Destroy()
    
        //在世界中获得World和GameMode,以调用其重启玩家函数。
        if (UWorld* World = GetWorld())
        {
            if (ARespawnPlayerGameMode* GameMode = Cast<ARespawnPlayerGameMode>(World->GetAuthGameMode()))
            {
                GameMode->RestartPlayer(CortollerRef);
            }
        }
    }
    
    void ARespawnPlayerCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
    {
        //设置输入键操作,以调用Restart Player
        PlayerInputComponent->BindAction("Restart", IE_Pressed, this, &ARespawnPlayerCharacter::CallRestartPlayer);
    }

    CallRestartPlayer 函数将销毁玩家角色,并会在按下 R 时调用。若发生了导致玩家角色消失的Gameplay事件,玩家因此失去足够的生命值,通常会调用 销毁(Destroy) 方法。

  5. 编译你的代码。

已完成代码

RespawnPlayerCharacter.h

//版权所有Epic Games, Inc。保留所有权利。

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "RespawnPlayerCharacter.generated.h"

UCLASS(config=Game)
class ARespawnPlayerCharacter : public ACharacter
{
    GENERATED_BODY()

    /** 用于将摄像机放置在角色身后的摄像机升降臂 */
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
    class USpringArmComponent* CameraBoom;

    /** 跟随摄像机 */
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
    class UCameraComponent* FollowCamera;

public:

    ARespawnPlayerCharacter();

    /** 基础旋转速度,以度/秒为单位。其他单位可能会影响最终旋转速度。*/
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
    float BaseTurnRate;

    /** 基础向上看/向下看速度,以度/秒为单位。其他单位可能会影响最终速度。*/
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
    float BaseLookUpRate;

protected:

    virtual void BeginPlay();
    virtual void Destroyed();
    void CallRestartPlayer();

    /** 重置VR中的HMD方向。*/
    void OnResetVR();

    /** 为向前/向后输入而调用*/
    void MoveForward(float Value);

    /** 为侧面到侧面输入而调用 */
    void MoveRight(float Value);

    /** 
     * 通过输入进行调用,从而以给定的速度旋转 
     * @param 速度    这是规范化速度,即1. 0表示100%的所需旋转速度
     */
    void TurnAtRate(float Rate);

    /**
     * 通过输入进行调用,从而以给定的速度向上看/向下看 
     * @param 速度    这是规范化速度,即1. 0表示100%的所需旋转速度
     */
    void LookUpAtRate(float Rate);

    /** 在触摸输入开始时使用的处理程序。*/
    void TouchStarted(ETouchIndex::Type FingerIndex, FVector Location);

    /** 在触摸输入停止时使用的处理程序。*/
    void TouchStopped(ETouchIndex::Type FingerIndex, FVector Location);

protected:

    // APawn接口
    virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
    // APawn末端接口

public:
    /** 返回CameraBoom子对象 **/
    FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }

    /** 返回FollowCamera子对象 **/
    FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; }
};

RespawnPlayer.cpp

//版权所有Epic Games, Inc。保留所有权利。

#include "RespawnPlayerTestCharacter.h"
#include "HeadMountedDisplayFunctionLibrary.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/Controller.h"
#include "GameFramework/SpringArmComponent.h"
#include "RespawnPlayerTestGameMode.h"

//////////////////////////////////////////////////////////////////////////
// ARespawnPlayerCharacter

ARespawnPlayerCharacter::ARespawnPlayerCharacter()
{
    // 设置碰撞胶囊体的大小
    GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);

    // 为输入设置我们的旋转速度
    BaseTurnRate = 45.f;
    BaseLookUpRate = 45.f;

    // 当控制器旋转时不旋转使其仅影响摄像机。
    bUseControllerRotationPitch = false;
    bUseControllerRotationYaw = false;
    bUseControllerRotationRoll = false;

    // 配置角色移动
    GetCharacterMovement()->bOrientRotationToMovement = true; // Character moves in the direction of input...   
    GetCharacterMovement()->RotationRate = FRotator(0.0f, 540.0f, 0.0f); // ...以此旋转速度
    GetCharacterMovement()->JumpZVelocity = 600.f;
    GetCharacterMovement()->AirControl = 0.2f;

    // 创建摄像机升降臂(发生碰撞则朝着玩家推进)
    CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
    CameraBoom->SetupAttachment(RootComponent);
    CameraBoom->TargetArmLength = 300.0f; // The camera follows at this distance behind the character   
    CameraBoom->bUsePawnControlRotation = true; // 基于控制器旋转升降臂

    // 创建一个跟随摄像机
    FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
    FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); // 将摄像机连接到升降臂末端,对升降臂进行调整以便与控制器方向保持一致
    FollowCamera->bUsePawnControlRotation = false; // 摄像机不相对于升降臂旋转

    // 注意:网格体组件上的骨骼网格体和动画蓝图引用(从角色继承) 
    // 是在名为MyCharacter的推导蓝图资产中设置的(以避免在C++中直接引用内容)
    static ConstructorHelpers::FObjectFinder<USkeletalMesh>SkeletalMeshAsset(TEXT("SkeletalMesh'/Game/Mannequin/Character/Mesh/SK_Mannequin.SK_Mannequin'"));
    GetMesh()->SetSkeletalMesh(SkeletalMeshAsset.Object);
    GetMesh()->SetRelativeLocation(FVector(0.0f, 0.0f, -97.0f));
    GetMesh()->SetRelativeRotation(FQuat(FRotator(0.0f, 270.0f, 0.0f)));
    static ConstructorHelpers::FObjectFinder<UAnimBlueprintGeneratedClass>AnimInstanceAsset(TEXT("AnimBlueprint'/Game/Mannequin/Animations/ThirdPerson_AnimBP.ThirdPerson_AnimBP_C'"));
    GetMesh()->SetAnimInstanceClass(AnimInstanceAsset.Object);
}

//////////////////////////////////////////////////////////////////////////
// 输入

void ARespawnPlayerCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
    // 设置Gameplay键绑定
    check(PlayerInputComponent);
    PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
    PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);
    PlayerInputComponent->BindAxis("MoveForward", this, &ARespawnPlayerCharacter::MoveForward);
    PlayerInputComponent->BindAxis("MoveRight", this, &ARespawnPlayerCharacter::MoveRight);

    // 我们提供了两个版本的旋转绑定来处理不同类型的设备,
    // "旋转"负责处理可以提供绝对增量的设备,例如鼠标。
    // "旋转速度"适用于我们选择作为更改速度来处理的设备,例如模拟摇杆
    PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
    PlayerInputComponent->BindAxis("TurnRate", this, &ARespawnPlayerCharacter::TurnAtRate);
    PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
    PlayerInputComponent->BindAxis("LookUpRate", this, &ARespawnPlayerCharacter::LookUpAtRate);

    // 处理触摸设备
    PlayerInputComponent->BindTouch(IE_Pressed, this, &ARespawnPlayerCharacter::TouchStarted);
    PlayerInputComponent->BindTouch(IE_Released, this, &ARespawnPlayerCharacter::TouchStopped);

    // VR头戴设备功能
    PlayerInputComponent->BindAction("ResetVR", IE_Pressed, this, &ARespawnPlayerCharacter::OnResetVR);
    PlayerInputComponent->BindAction("Restart", IE_Pressed, this, &ARespawnPlayerCharacter::CallRestartPlayer);
}

void ARespawnPlayerCharacter::BeginPlay()
{
    Super::BeginPlay();
}

void ARespawnPlayerCharacter::Destroyed()
{
    Super::Destroyed();

    //关于绑定至GameMode中的OnPlayerDied事件的示例如果是多人游戏,那么此方法_不是_一个好选项。
    if (UWorld* World = GetWorld())
    {
        if (ARespawnPlayerGameMode* GameMode = Cast<ARespawnPlayerGameMode>(World->GetAuthGameMode()))
        {
            GameMode->GetOnPlayerDied().Broadcast(this);
        }
    }
}

void ARespawnPlayerCharacter::CallRestartPlayer()
{
    AController* CortollerRef = GetController();
    Destroy();

    if (UWorld* World = GetWorld())
    {
        if (ARespawnPlayerGameMode* GameMode = Cast<ARespawnPlayerGameMode>(World->GetAuthGameMode()))
        {
            GameMode->RestartPlayer(CortollerRef);
        }
    }
}

void ARespawnPlayerCharacter::OnResetVR()
{
    // 如果在虚幻编辑器中通过"添加功能(Add Feature)"将RespawnPlayer添加到项目,则RespawnPlayer.Build.cs中HeadMountedDisplay上的依赖关系不会自动传播,
    // 并将产生连接器错误。
    // 你将需要:
    //      将"HeadMountedDisplay"添加到[YourProject].Build.cs,以成功构建PublicDependencyModuleNames(如果支持VR则适用)
    // 或者:
    //      注释或删除以下对ResetOrientationAndPosition的调用(如果不支持VR则适用)
    UHeadMountedDisplayFunctionLibrary::ResetOrientationAndPosition();
    CallDestroyPlayer();
}

void ARespawnPlayerCharacter::TouchStarted(ETouchIndex::Type FingerIndex, FVector Location)
{
        Jump();
}

void ARespawnPlayerCharacter::TouchStopped(ETouchIndex::Type FingerIndex, FVector Location)
{
        StopJumping();
}

void ARespawnPlayerCharacter::TurnAtRate(float Rate)
{
    // 根据速度信息计算此帧的增量
    AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds());
}

void ARespawnPlayerCharacter::LookUpAtRate(float Rate)
{
    // 根据速度信息计算此帧的增量
    AddControllerPitchInput(Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds());
}

void ARespawnPlayerCharacter::MoveForward(float Value)
{
    if ((Controller != nullptr) && (Value != 0.0f))
    {
        // 找出向前方向
        const FRotator Rotation = Controller->GetControlRotation();
        const FRotator YawRotation(0, Rotation.Yaw, 0);

        // 获取向前向量
        const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
        AddMovementInput(Direction, Value);
    }
}

void ARespawnPlayerCharacter::MoveRight(float Value)
{
    if ( (Controller != nullptr) && (Value != 0.0f) )
    {
        // 找出向右方向
        const FRotator Rotation = Controller->GetControlRotation();
        const FRotator YawRotation(0, Rotation.Yaw, 0);

        // 获取向右向量 
        const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
        // 添加该方向动作
        AddMovementInput(Direction, Value);
    }
}

最终结果

回到编辑器,然后点击 在编辑器中运行(Play in Editor) (PIE)。

你可以使用W、A、S、D键来控制角色在地图中移动。

如果按下 R 键,玩家角色将被销毁,短暂消失一段时间之后,在 玩家出生点位置(Player Start Location) 上重新生成。

image alt text

欢迎帮助改进虚幻引擎文档!请告诉我们该如何更好地为您服务。
填写问卷调查
取消