设置角色动作

在本操作指南中,你将创建一个可操作角色,展示不同形式的角色动作。

Choose your operating system:

Windows

macOS

Linux

角色动作为类人角色提供移动系统,以便在你的世界中穿行。 角色动作组件 Actor组件 ,提供 角色(Character) 类的移动模式,包括行走、跌倒、游泳和飞行。此外,角色动作组件具有强大的网络Gameplay集成功能,并提供框架帮助开发人员创建自定义的联网动作。

有关虚幻引擎中网络复制的其他文档,参见 联网 Actor复制

在Gameplay操作指南中,你将创建角色类,编写其运动逻辑和输入的脚本,并创建动画蓝图帮助确定你的角色所处的状态,然后播放相应的动画。

角色动作的实际效果

选择实现方法:

Blueprints

C++

新建项目

  1. 首先,登录到 Epic Games启动程序 ,通过 新建(New)>游戏(Games)>空白(Blank)>项目(Project) 创建名为 **CharacterMovement 的项目。

    创建新蓝图项目

  2. 要为角色制作动画,你将需要 动画初学者包(Animation Starter Pack) ,可从 Epic Games虚幻商城 免费下载。 点击 免费(Free) 按钮,下载动画初学者包,并将其添加到 Epic Games库

    获取动画初学者包

  3. 库(Library) 中,搜索 动画初学者包(Animation Starter Pack) ,点击 添加到项目(Add to Project) ,然后从 选择要向其添加资产的项目(Select the Project to Add the Asset to) 菜单,搜索并选择 CharacterMovement 项目文件,然后点击 添加到项目(Add to Project)

    将动画初学者包添加到项目

  4. 将动画初学者包添加到你的项目中后,你将在 内容浏览器(Content Browser) 中看到它。

    内容浏览器中的动画初学者包

  1. 首先,点击 新建(New)> 游戏(Games)> 空白(Blank)> C++ 创建名为 CharacterMovement 的项目。

    新建C++项目

  2. 要为角色制作动画,你将需要 动画初学者包(Animation Starter Pack) ,可从 Epic Games虚幻商城 免费下载。 点击 免费(Free) 按钮,下载动画初学者包,并将其添加到 Epic Games库

    获取动画初学者包

  3. 库(Library) 中,搜索 动画初学者包(Animation Starter Pack) ,点击 添加到项目(Add to Project) ,然后从 选择要向其添加资产的项目(Select the Project to Add the Asset to) 菜单,搜索并选择 CharacterMovement 项目文件,然后点击 添加到项目(Add to Project)

    将动画初学者包添加到项目

  4. 将动画初学者包添加到你的项目中后,你将在 内容浏览器(Content Browser) 中看到它。

    内容浏览器中的动画初学者包

创建玩家角色

玩家需要角色类进行控制。角色是带有角色动作组件的Pawn,可为类人角色提供移动系统以便在你的世界中穿行。按照以下步骤设置角色。

  1. 点击 添加/导入(Add/Import) 按钮新建蓝图 角色 类,将其命名为 BP_PlayerCharacter

    添加新蓝图角色类

  2. 双击 BP_PlayerCharacter 打开 类默认值 ,然后在组件(components)选项卡中,选择 网格体 (CharacterMesh0) 骨骼网格体组件(Skeletal Mesh Component) ,并导航至 细节面板(Details panel)

    点击查看大图。

  3. 网格体(Mesh) 类别中,选择 骨骼网格体变量(Skeletal Mesh variable) 旁边的下拉箭头,并从下拉菜单中选择 SK_Mannequin

    选择骨骼网格体

  4. 细节面板(Details panel) 导航到 变换类别(Transform category) ,将网格体的 位置(Location) 旋转(Rotation) 设置为( 0 , 0 , -90 )。

    变换设置

  5. 角色的 骨骼网格体 现在将出现在朝前的 箭头组件 方向,如下图所示。

    骨骼网格体方向

  6. 导航至 组件选项卡(Components tab) ,选择网格体组件,然后点击 添加组件(Add Component) ,在下拉菜单中搜索并选择SpringArm,然后将 弹簧臂组件(Spring Arm Component) 命名为" SpringArmComp "。

    添加弹簧臂组件

  7. 导航至 细节面板(Details panel) ,在 摄像机设置(Camera Settings) 类别,启用 使用Pawn控制旋转(Use Pawn Control Rotation)

    摄像机设置

    启用使用Pawn控制旋转将使摄像机相对于弹簧臂旋转。

  8. 摄像机类别(Camera category) 中,将 套接字偏移(socket offset) 设置为( 0,0,30 ),然后导航至 变换类别(Transform category) ,并将 SpringArmComp的位置(SpringArmComp's Location) 设置为( 0,0,50 )。

    弹簧臂组件设置

  9. 选择SpringArmComp后,点击 添加组件(Add Component) 按钮,然后,在下拉菜单搜索和选择摄像机,以便添加名为 CameraComp 摄像机组件(Camera Component)

    添加摄像机组件

10.在 组件(Components) 选项卡中,选择 角色动作组件(Character Movement Component) ,然后导航至 细节面板(Details panel) ,在 角色动作(Character Movement) 旋转设置(Rotation Settings) )类别,启用 使用控制器所需旋转(Use Controller Desired Rotation) 将旋转定向到动作(Orient Rotation To Movement)

![角色动作旋转设置](RotationSettings.png)(w:400)

11.在 角色动作:行走(Character Movement:Walking) 类别,启用 忽略基地旋转(Ignore Base Rotation) 变量。

![启用忽略基地旋转](IgnoreBaseRotationEnable.png)(w:400)
[REGION:caption]
将忽略基地旋转设置为true将告知角色保持其当前世界旋转,并忽略它所站立基地旋转的任何变化。 
[/REGION]

12.在 角色动作导航动作类别(Character Movement Nav Movement category) ,导航至 移动能力(Movement Capabilities) ,并选择下拉箭头查看更多变量设置,导航至 Can Crouch布尔(Can Crouch Boolean) ,并点击启用它。

![启用Can Crouch布尔](CanCrouchEnable.png)(w:600)

13. 编译(Compile) 保存(Save)

![编译并保存按钮](CompileSave.png)(w:200)

玩家需要角色类进行控制。角色是带有角色动作组件的Pawn,可为类人角色提供移动系统以便在你的世界中穿行。按照以下步骤设置角色。

  1. C++类向导(C++ Class Wizard) 中,新建名为 PlayerCharacter 角色(Character) 类,然后导航到 PlayerCharacter 文件,并声明以下类定义:

    protected:
    
    //跟随玩家背后摄像机的弹簧臂组件
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
    class USpringArmComponent* SpringArmComp;
    
    //玩家跟随摄像机
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
    class UCameraComponent* CameraComp; 
  2. 导航至 PlayerCharactor.cpp 文件并添加以下类库:

    #include "Camera/CameraComponent.h"
    #include "GameFramework/SpringArmComponent.h"
    #include "GameFramework/CharacterMovementComponent.h"
  3. APlayerCharactor::APlayerCharacter 构造函数方法中,声明以下内容

    //实例化你的类组件
    
    SpringArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArmComp"));
    
    CameraComp = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComp"));
    
    //设置角色网格体变换的位置和旋转
    
    GetMesh()->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, -90.0f), FQuat(FRotator(0.0f, -90.0f, 0.0f)));
    
    //将你的类组件附加到默认角色的骨骼网格体组件。
    
    SpringArmComp->SetupAttachment(GetMesh());
    
    CameraComp->SetupAttachment(SpringArmComp,USpringArmComponent::SocketName);
    
    //设置弹簧臂的类变量
    
    SpringArmComp->bUsePawnControlRotation = true;
    
    //设置角色动作组件的类变量
    
    GetCharacterMovement()->bOrientRotationToMovement = true;
    
    GetCharacterMovement()->bUseControllerDesiredRotation = true;
    
    GetCharacterMovement()->bIgnoreBaseRotation = true;
  4. 编译 你的代码。

  5. 编辑器(Editor) 中,导航至 C++类文件夹 ,然后右键点击 PlayerCharacter 类,在 C++类操作(C++ Class Actions) 下拉菜单中,选择 基于PlayerCharacter创建蓝图类(Create Blueprint class based on PlayerCharacter) 。将蓝图命名为 Bp_PlayerCharacter

    点击查看大图。

  6. 双击 BP_PlayerCharacter 打开 类默认值 ,然后在 组件(Components) 选项卡中,选择 网格体 (CharacterMesh0) 骨骼网格体组件(Skeletal Mesh Component) ,并导航至 细节面板(Details panel)

    点击查看大图。

10.在 网格体(Mesh) 类别中,选择 骨骼网格体变量(Skeletal Mesh variable) 旁边的下拉箭头,并从下拉菜单中选择 SK_Mannequin

![选择骨骼网格体](SKMeshSelect.png)(w:400)

11.角色的 骨骼网格体 将出现在朝前的 箭头组件 方向,如下图所示。

![骨骼网格体方向](NinetyDegreeChar.png)(w:600)

12. 编译(Compile) 保存(Save)

![编译并保存按钮](CompileSave.png)(w:200)

创建输入密钥映射和输入动作事件

你将需要设置一些自定义逻辑,以便在按下输入键(如W、A、S、D)时移动角色。

  1. 导航至 编辑(Edit)>项目设置(Project Settings)>输入(Input) ,然后在 绑定类别(Bindings Category) 中点击 操作映射(Action Mappings) 旁边的 + 号,添加以下内容:

    动作映射

    键值

    跳跃

    空格键

    蹲伏

    左Ctrl

    冲刺

    左Shift

    移动映射

  2. 绑定类别(Bindings Category) 中,点击 轴映射(Axis Mappings) 旁边的 + 号,添加以下 轴映射(Axis Mappings)

    轴映射

    键值

    缩放

    MoveForward

    W

    1.0

    S

    -1.0

    MoveRight

    D

    1.0

    A

    -1.0

    Turn

    鼠标X

    1.0

    LookUp

    鼠标Y

    -1.0

    输入操作映射

  3. 内容浏览器(Content Browser) 中,双击 BP_PlayerCharacter 打开 类默认值 ,然后右键点击 事件图表(Event Graph) ,并在下拉菜单中搜索和选择 MoveForward

    点击查看大图。

  4. InputAxis MoveForward 节点拖移 执行引脚 ,在下拉菜单搜索并选择 Add Movement Input 节点,然后将 InputAxis MoveForward 节点的 轴值(Axis Value) 引脚连接到 Add Movement Input 节点的 缩放值(Scale Value) 引脚。

    点击查看大图。

  5. 右键点击 事件图表(Event Graph) ,在上下文菜单搜索并选择 Get Control Rotation ,然后从 旋转体返回值(Rotator Return Value) 引脚拖移,并在下拉菜单搜索和选择 Break Rotator

    点击查看大图。

  1. Break Rotator 节点的 Z Yaw )引脚拖移,在下拉菜单搜索并选择 Make Rotator 节点,然后,从 Make Rotator 节点的 旋转体返回值(Rotator Return Value) 引脚拖移,在下拉菜单搜索并选择 Get Forward Vector

    点击查看大图。

  2. Get Forward Vector 节点的 矢量返回值(Vector Return Value) 引脚拖移,将其插入到 Add Movement Input 节点的 世界方向(World Direction) 引脚。

    点击查看大图。

  3. 再次右键点击图表,搜索并为你的 输入轴事件 选择 向右移动(Move Right)

    点击查看大图。

  4. InputAxis MoveRight 节点拖移 执行引脚 ,在下拉菜单搜索并选择 Add Movement Input* 节点,然后将 InputAxis MoveForward 节点的 轴值(Axis Value) 引脚连接到 Add Movement Input 节点的 缩放值(Scale Value)** 引脚。

    点击查看大图。

10.从 Make Rotator 节点的 旋转体返回值(Rotator Return Value) 引脚拖移,在下拉菜单搜索并选择 Get Right Vector 节点,然后拖移 矢量返回值(Vector Return Value) 引脚,并将其插入到 Add Movement Input 节点的 世界方向(World Direction) 引脚。

[REGION:lightbox]
[![连接右旋转体输入](MoveRightInputConnect.png)(w:600)](MoveRightInputConnect.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

11.已完成的动作输入事件蓝图图表将如下所示。

[REGION:lightbox]
[![已完成动作输入事件蓝图图表](CompletedInputEvents.png)(w:600)](CompletedInputEvents.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

12. 右键点击 事件图表(Event Graph) ,然后搜索并选择 InputAxis LookUp 事件节点,然后右键点击,搜索并选择 Add Controller Pitch Input 节点。

[REGION:lightbox]
[![添加控制器Pitch输入](AddControllerPitch.png)(w:600)](AddControllerPitch.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

13.从Input Axis LookUp节点的 轴值(Axis Value) 引脚拖移,并连接到 Add Controller Pitch Input 节点的 Val 引脚。从 InputAxis LookUp 节点的 执行输出引脚 拖移,并连接到 Add Controller Pitch Input 节点的 执行输入引脚

[REGION:lightbox]
[![连接添加控制器Pitch输入](ControllerPitchConnect.png)(w:600)](ControllerPitchConnect.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

14.右键点击 事件图表(Event Graph) ,然后搜索并选择 Input Axis Turn 事件节点,然后右键点击,搜索并选择 Add Controller Yaw Input 节点。

[REGION:lightbox]
[![添加控制器Yaw输入](AddYawInput.png)(w:600)](AddYawInput.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

15.从 Input Axis Turn 节点的 轴值(Axis Value) 引脚拖移,并连接到 Add Controller Yaw Input 节点的 Val 引脚。从 Input Axis Turn 节点的 执行输出引脚 拖移,并连接到 Add Controller Yaw Input 节点的 执行输入引脚

[REGION:lightbox]
[![连接添加控制器Yaw输入](ConnectToYaw.png)(w:600)](ConnectToYaw.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

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

![编译并保存按钮](CompileSave.png)(w:200)

半成品蓝图

此时,你的蓝图图表应如下图所示。

点击查看大图。

你将需要设置一些自定义逻辑,以便在按下输入键(如W、A、S、D)时移动角色。

  1. 导航至 编辑(Edit)>项目设置(Project Settings)>输入(Input) ,然后在 绑定(Bindings) 类别,点击 操作映射(Action Mappings) 旁边的 + 号,添加以下 操作映射(Action mappings)

    操作映射

    键值

    跳跃

    空格键

    蹲伏

    左Ctrl

    冲刺

    左Shift

    动作操作映射

  2. 绑定类别(Bindings Category) 中,点击 轴映射(Axis Mappings) 旁边的 + 号,添加以下 轴映射(Axis Mappings)

    轴映射

    键值

    缩放

    MoveForward

    W

    1.0

    S

    -1.0

    MoveRight

    D

    1.0

    A

    -1.0

    Turn

    鼠标X

    1.0

    LookUp

    鼠标Y

    -1.0

    输入操作映射

  3. 在PlayerCharacter.h中,声明以下类方法

    protected:
    
    //为向前/向后输入而调用
    
    void MoveForward(float InputAxis);
    
    //为左/右侧输入而调用
    
    void MoveRight(float InputAxis);
  4. 在PlayerCharacter.Cpp中,为 APlayerCharacter::MoveForward APlayerCharacter::MoveRight 类方法实现以下逻辑。

    void APlayerCharacter::MoveForward(float AxisValue)
    {
        if ((Controller != nullptr) && (AxisValue != 0.0f))
        {
            // 找出向前方向
            const FRotator Rotation = Controller->GetControlRotation();
            const FRotator YawRotation(0, Rotation.Yaw, 0);
    
            // 获取向前矢量
            const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
            AddMovementInput(Direction, AxisValue);
        }
    }
    
    void APlayerCharacter::MoveRight(float AxisValue)
    {
        if ((Controller != nullptr) && (AxisValue != 0.0f))
        {
            // 找出向右方向
            const FRotator Rotation = Controller->GetControlRotation();
            const FRotator YawRotation(0, Rotation.Yaw, 0);
    
            // 获取向右矢量 
            const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
    
            // 添加该方向动作
            AddMovementInput(Direction, AxisValue);
        }
    }
  5. 接下来导航至 APlayerCharacter::SetupPlayerInputComponent 方法,并实现以下代码。

    //为将功能绑定到输入而调用
    void APlayerCharacter::SetupPlayerInputComponent(UInputComponent*)
    {
        Super::SetupPlayerInputComponent(PlayerInputComponent);
    
        PlayerInputComponent->BindAxis("MoveForward", this, &APlayerCharacter::MoveForward);
        PlayerInputComponent->BindAxis("MoveRight", this, &APlayerCharacter::MoveRight);
        PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
        PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
    
    }
  6. 编译 你的代码

阶段性代码

PlayerCharacter.h

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

    UCLASS()
    class CHARACTERMOVEMENT_API APlayerCharacter : public ACharacter
    {
        GENERATED_BODY()

    public:
        // 为此角色的属性设置默认值
        APlayerCharacter();

    protected:
        // 当游戏开始或重生(Spawn)时被调用
        virtual void BeginPlay() override;

        //跟随玩家背后摄像机的弹簧臂组件
        UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
        class USpringArmComponent* SpringArmComp;

        //玩家跟随摄像机
        UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
        class UCameraComponent* CameraComp; 

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

        //为左/右侧输入而调用
        void MoveRight(float InputAxis);

    public: 
        // 每一帧都调用
        virtual void Tick(float DeltaTime) override;

        // 为将功能绑定到输入而调用
        virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
    };

PlayerCharacter.Cpp

    #include "PlayerCharacter.h"
    #include "Camera/CameraComponent.h"
    #include "GameFramework/SpringArmComponent.h"
    #include "GameFramework/CharacterMovementComponent.h"

    // 设置默认值
    APlayerCharacter::APlayerCharacter()
    {
        // 将此角色设置为每帧调用Tick()。  如果你不需要此特性,你可以关闭以提升性能。
        PrimaryActorTick.bCanEverTick = true;

        //实例化你的类组件
        SpringArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArmComp"));
        CameraComp = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComp"));

        //设置角色网格体变换的位置和旋转
        GetMesh()->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, -90.0f), FQuat(FRotator(0.0f, -90.0f, 0.0f)));

        //将你的类组件附加到默认角色的骨骼网格体组件。
        SpringArmComp->SetupAttachment(GetMesh());
        CameraComp->SetupAttachment(SpringArmComp,USpringArmComponent::SocketName);

        //设置弹簧臂的类变量
        SpringArmComp->bUsePawnControlRotation = true;

        //设置角色动作组件的类变量
        GetCharacterMovement()->bOrientRotationToMovement = true;
        GetCharacterMovement()->bUseControllerDesiredRotation = true;
        GetCharacterMovement()->bIgnoreBaseRotation = true;

    }

    // 当游戏开始或重生(Spawn)时被调用
    void APlayerCharacter::BeginPlay()

    {
        Super::BeginPlay();

    }

    void APlayerCharacter::MoveForward(float AxisValue)

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

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

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

            // 获取向右矢量 
            const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);

            // 添加该方向动作
            AddMovementInput(Direction, AxisValue);
        }
    }

    // 每一帧都调用
    void APlayerCharacter::Tick(float DeltaTime)
    {
        Super::Tick(DeltaTime);

    }

    // 为将功能绑定到输入而调用
    void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
    {
        Super::SetupPlayerInputComponent(PlayerInputComponent);
        PlayerInputComponent->BindAxis("MoveForward",this, &APlayerCharacter::MoveForward);
        PlayerInputComponent->BindAxis("MoveRight", this, &APlayerCharacter::MoveRight);
        PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
        PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
    }

创建输入密钥映射和输入操作事件

现在你已完成向前移动、向右移动、向上看和转向输入事件的蓝图脚本逻辑,你将需要完成为跳跃、蹲伏和冲刺输入事件完成实现操作映射。

  1. 右键点击 事件图表(Event Graph) ,然后在 此蓝图的所有操作(All Actions for this Blueprint) 下拉菜单中,搜索并选择 跳跃操作事件(Jump Action Event)

    点击查看大图。

  2. InputAction Jump 节点的 Pressed执行引脚 拖移,然后在下拉菜单中,搜索并选择角色函数 Jump

    添加跳跃角色函数

  3. InputAction Jump 节点的 执行引脚 连接到 Jump 节点的 执行引脚

    点击查看大图。

  4. InputAction Jump 节点的 Released执行引脚 拖移,然后在下拉菜单中,搜索并选择角色函数 Stop Jumping

    点击查看大图。

  5. 右键点击 事件图表(Event Graph) ,然后在下拉菜单中,搜索并选择 输入操作冲刺(Input Action Sprint)

    添加输入操作冲刺

  6. 导航至 组件选项卡(Components tab) ,然后点击 角色动作组件(Character Movement Component) 并将其拖放到 事件图表(Event Graph)

    点击查看大图。

  7. 拖移 角色动作引脚(Character Movement pin) ,并从下拉菜单搜索和选择 Set Max Walk Speed 。将 最高行走速度浮点值 设置为 1000 ,然后将 InputAction Sprint 节点的 Pressed执行引脚 连接到 Set Max Walk Speed 输入执行 引脚。

    点击查看大图。

  8. 角色动作引脚(Character Movement pin) 拖移,然后搜索并选择另一 Max Walk Speed 节点。将 最高行走速度浮点值 设置为 600 ,然后将 InputAction Sprint 节点的 Pressed执行引脚 连接到 设置最高行走速度执行输入引脚

    点击查看大图。

  9. 右键点击 事件图表(Event Graph) ,然后在下拉菜单中,搜索并选择 Input Action Crouch

    添加输入操作蹲伏

10.从 InputAction Crouch 节点的 Pressed执行引脚 拖移,然后在下拉菜单中,搜索并选择角色类函数 Crouch

[REGION:lightbox]
[![将输入操作执行引脚连接到Crouch](PressedToJump.png)(w:600)](PressedToJump.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

11.从 InputAction Crouch 节点的 Released执行引脚 拖移,然后在下拉菜单中,搜索并选择角色类函数 Un Crouch

[REGION:lightbox]
[![连接用于蹲伏的Released执行引脚](CrouchToUnCrouch.png)(w:600)](CrouchToUnCrouch.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

12. 编译(Compile) 保存(Save) 蓝图。

![编译并保存按钮](CompileSave.png)(w:200)

完成后的蓝图

完成后的蓝图如下图所示。

点击查看大图。

现在你已经完成了 向前移动 向右移动 向上看 转向输入事件 的代码脚本逻辑,你将需要为 跳跃 蹲伏 冲刺 输入事件完成实现 操作映射

  1. 导航至PlayerCharacter.h文件并声明以下类方法

    protected:
    
        //将角色移动速度设置为冲刺值。
        void BeginSprint();
    
        //将角色移动速度设置回默认速度值。
        void EndSprint();
    
        //角色蹲伏请求
        void BeginCrouch();
    
        //角色结束蹲伏请求
        void EndCrouch();
  2. 在PlayerCharacter.cpp文件中,为 APlayerCharacter::BeginSprint APlayerCharacter::EndSprint 类方法实现以下逻辑。

    void APlayerCharacter::BeginSprint()
    {
        GetCharacterMovementComponent()->MaxWalkSpeed = 1000.0f;    
    }
    
    void APlayerCharacter::EndSprint()
    {
        GetCharacterMovementComponent()->MaxWalkSpeed = 600.f;
    }
  3. APlayerCharacter::BeginCrouch APlayerCharacter::EndCrouch 方法实现以下逻辑。

    void APlayerCharacter::BeginCrouch()
    {
        Crouch();
    }
    
    void APlayerCharacter::EndCrouch()
    {
        UnCrouch();
    }
  4. 导航至 APlayerCharacter:: ::SetupPlayerInputComponent 方法,并声明以下代码:

    void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
    {
    
        PlayerInputComponent->BindAction("Jump",IE_Pressed,this,&ACharacter::Jump);
        PlayerInputComponent->BindAction("Jump",IE_Released,this,&ACharacter::StopJumping);
        PlayerInputComponent->BindAction("Crouch",IE_Pressed,this,&APlayerCharacter::BeginCrouch);
        PlayerInputComponent->BindAction("Crouch",IE_Released,this,&APlayerCharacter::EndCrouch);
        PlayerInputComponent->BindAction("Sprint",IE_Pressed,this,&APlayerCharacter::BeginSprint);
        PlayerInputComponent->BindAction("Sprint",IE_Released,this,&APlayerCharacter::EndSprint);
    
    }
  5. 编译 你的代码。

完成后的代码

PlayerCharacter.h

    #pragma once

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

    UCLASS()
    class CHARACTERMOVEMENT_API APlayerCharacter : public ACharacter
    {
        GENERATED_BODY()

    public:
        // 为此角色的属性设置默认值
        APlayerCharacter();

    protected:
        // 当游戏开始或重生(Spawn)时被调用
        virtual void BeginPlay() override;

        //跟随玩家背后摄像机的弹簧臂组件
        UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
        class USpringArmComponent* SpringArmComp;

        //玩家跟随摄像机
        UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
        class UCameraComponent* CameraComp; 

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

        //为左/右侧输入而调用
        void MoveRight(float InputAxis);

        //将角色移动速度设置为冲刺值。
        void BeginSprint();

        //将角色移动速度设置回默认速度值。
        void EndSprint();

        //角色蹲伏请求
        void BeginCrouch();

        //角色结束蹲伏请求
        void EndCrouch();

    public: 

        // 每一帧都调用
        virtual void Tick(float DeltaTime) override;

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

    };

PlayerCharacter.cpp

    #include "PlayerCharacter.h"
    #include "Camera/CameraComponent.h"
    #include "GameFramework/SpringArmComponent.h"
    #include "GameFramework/CharacterMovementComponent.h"

    // 设置默认值
    APlayerCharacter::APlayerCharacter()
    {
        // 将此角色设置为每帧调用Tick()。  如果你不需要此特性,你可以关闭以提升性能。
        PrimaryActorTick.bCanEverTick = true;

        //实例化你的类组件
        SpringArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArmComp"));
        CameraComp = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComp"));

        //设置角色网格体变换的位置和旋转
        GetMesh()->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, -90.0f), FQuat(FRotator(0.0f, -90.0f, 0.0f)));

        //将你的类组件附加到默认角色的骨骼网格体组件。
        SpringArmComp->SetupAttachment(GetMesh());
        CameraComp->SetupAttachment(SpringArmComp,USpringArmComponent::SocketName);

        //设置弹簧臂的类变量
        SpringArmComp->bUsePawnControlRotation = true;

        //设置角色动作组件的类变量
        GetCharacterMovement()->bOrientRotationToMovement = true;
        GetCharacterMovement()->bUseControllerDesiredRotation = true;
        GetCharacterMovement()->bIgnoreBaseRotation = true;
    }

    // 当游戏开始或重生(Spawn)时被调用
    void APlayerCharacter::BeginPlay()
    {
        Super::BeginPlay();

    }

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

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

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

            // 获取向右矢量 
            const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);

            // 添加该方向动作
            AddMovementInput(Direction, AxisValue);
        }
    }

    void APlayerCharacter::BeginSprint()
    {
    GetCharacterMovementComponent()->MaxWalkSpeed = 1000.0f;
    }

    void APlayerCharacter::EndSprint()
    {
        GetCharacterMovementComponent()->MaxWalkSpeed = 600.f;
    }

    void APlayerCharacter::BeginCrouch()
    {
        Crouch();
    }

    void APlayerCharacter::EndCrouch()
    {
        UnCrouch();
    }

    // 每一帧都调用
    void APlayerCharacter::Tick(float DeltaTime)
    {
        Super::Tick(DeltaTime);
    }

    // 为将功能绑定到输入而调用
    void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
    {
        Super::SetupPlayerInputComponent(PlayerInputComponent);
        PlayerInputComponent->BindAxis("MoveForward",this, &APlayerCharacter::MoveForward);
        PlayerInputComponent->BindAxis("MoveRight", this, &APlayerCharacter::MoveRight);
        PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
        PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
        PlayerInputComponent->BindAction("Jump",IE_Pressed,this, &ACharacter::Jump);
        PlayerInputComponent->BindAction("Jump",IE_Released,this, &ACharacter::StopJumping);
        PlayerInputComponent->BindAction("Crouch",IE_Pressed,this,&APlayerCharacter::BeginCrouch);
        PlayerInputComponent->BindAction("Crouch",IE_Released,this,&APlayerCharacter::EndCrouch);
        PlayerInputComponent->BindAction("Sprint",IE_Pressed,this, &APlayerCharacter::BeginSprint);
        PlayerInputComponent->BindAction("Sprint",IE_Released,this, &APlayerCharacter::EndSprint);
    }

设置游戏模式

游戏模式 定义游戏的一组规则。这些规则包括游戏启动时玩家将生成的默认Pawn。你需要设置这些规则才能生成你已创建的玩家角色。

  1. 内容浏览器(Content Browser) 中,点击 添加/导入(Add/Import) 按钮,并创建新的 蓝图(Blueprint) 类,当 选择父类(Pick a Parent Class) 菜单显示时,选择 游戏模式基础(Game Mode Base) ,并将新游戏模式类命名为 Bp_GameMode

    点击查看大图。

  2. 双击 Bp_GameMode 打开类默认值,然后导航至 细节面板类类别(Details panel Classes category) ,默认Pawn类选择Bp_PlayerCharacter。

    选择默认Pawn类

  3. 编译(Compile) 保存(Save) 蓝图。

    编译并保存按钮

  4. 导航至 编辑(Edit)>项目设置(Project Settings)>地图和模式(Maps & Modes) ,在 默认模式类别(Default Modes category) ,选择 Bp_GameMode

    点击查看大图。

游戏模式 定义游戏的一组规则。这些规则包括游戏启动时玩家将生成的默认Pawn。你需要设置这些规则才能生成你已创建的玩家角色。

  1. 在编辑器中导航至你的C++类文件夹。右键点击CharacterMovementGameModeBase,从 C+类操作(+C++ Class Actions) 菜单,基于CharacterMovementGameModeBase创建蓝图类,然后命名新Gamemode类为 Bp_GameMode

    点击查看大图。

  2. 双击 Bp_GameMode 打开 类默认值 ,然后导航至 详情面板类类别(Details panel Classes category) ,默认Pawn类选择Bp_PlayerCharacter。

    选择默认Pawn类

  3. 编译(Compile) 保存(Save) 蓝图。

    编译并保存按钮

  4. 导航至 编辑(Edit)>项目设置(Project Settings)>地图和模式(Maps & Modes) ,在 默认模式类别(Default Modes category) ,选择 Bp_GameMode

    点击查看大图。

创建移动混合空间

现在你的角色拥有了在关卡中移动的输入功能,你需要为动作状态(冲刺、慢跑和蹲伏)创建 混合空间(Blend Spaces)

混合空间(https://docs.unrealengine.com/en-US/AnimatingObjects/SkeletalMeshAnimation/Blendspaces/index.html)是特殊资产,它能基于两个输入值将动画混合起来。你将创建自己的混合空间,根据角色的移动速度或方向前后左右移动。

  1. 内容浏览器(Content Browser) 中,点击 (添加/导入)Add/Import > 动画(Animation) > 混合空间(BlendSpace) ,当提示选择骨架时,选择 UE4_Mannequin_Skeleton ,然后将你的混合空间命名为 Locomotion_BS

    创建混合空间

  2. 双击打开 Locomotion_BS 混合空间。在 资产详情选项卡(Asset Details tab) 中,导航至 轴设置(Axis Settings) 类别,然后选择 水平轴(Horizontal Axis) 垂直轴(Vertical Axis) 旁边的箭头,查看更多变量详情。

    资产详情轴设置

  3. 水平轴设置(Horizontal Axis settings) 中,将 名称(Name) 变量更改为 方向(Direction) ,然后将 最小轴值(Minimum Axis Value) 设置为 -180 ,将 最大轴值(Maximum Axis Value) 设置为 180

    水平轴设置

  4. 垂直轴设置(Vertical Axis Settings) 中,将 名称(Name) 变量更改为 速度(Speed) ,然后将 最大轴值(Maximum Axis Value) 设置为 1000

    垂直轴设置

  5. 编译(Compile) 保存(Save)

    编译并保存按钮

  6. 导航至 资产浏览器(Asset Browser) ,然后在过滤器搜索栏中,输入 Idle_Rifle_Hip ,然后将 Idle_Rifle_Hip 资产拖放到 方向0.0**和**速度0.0 混合空间

    点击查看大图。

  7. 重复前一步骤,插入 Idle_Rifle_Hip 资产到以下值的混合空间:

    • 方向180 速度0

    • 方向90 速度0

    • 方向-90 速度0

    • 方向-180 速度0

    点击查看大图。

  8. 资产浏览器(Asset Browser) 选项卡的 过滤器(Filters) 搜索栏中,输入 Walk_Fwd_Rifle_Ironsights ,然后将 Walk_Fwd_Rifle_Ironsights 资产拖放到 方向0.0 速度250 混合空间

    点击查看大图。

  9. 然后,在 资产浏览器(Asset Browser) 选项卡的 过滤器(Filters) 搜索栏中,输入 Walk_Lt_Rifle_Ironsights ,然后将 Walk_Lt_Rifle_Ironsights 资产拖放到 方向-90 速度250 混合空间

    点击查看大图。

10.在 资产浏览器选项卡过滤器(Asset Browser tab Filters) 搜索栏中,输入 Walk_Rt_Rifle_Ironsights ,然后将 Walk_Rt_Rifle_Ironsights 资产拖放到 方向90 速度250 混合空间

[REGION:lightbox]
[![将步行向右步枪动画添加到混合空间](Walk_Rt_RifleIronsightsAsset.png)(w:600)](Walk_Rt_RifleIronsightsAsset.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

11.在 资产浏览器选项卡过滤器(Asset Browser tab Filters) 搜索栏中,输入 Walk_Bwd_Rifle_Ironsights ,然后将 Walk_Bwd_Rifle_Ironsights 资产拖放到 方向180 速度250 混合空间 ,然后再次将其拖放到 方向-180 速度250

[REGION:lightbox]
[![将步行后退步枪动画添加到混合空间](Walk_Bwd_Rifle_Ironsights.png)(w:600)](Walk_Bwd_Rifle_Ironsights.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

12.在 资产浏览器(Asset Browser) 选项卡的 过滤器(Filters) 搜索栏中,输入 Jog_Fwd_Rifle ,然后将 Jog_Fwd_Rifle 资产拖放到 方向0.0 速度500 混合空间

[REGION:lightbox]
[![将慢跑向前步枪动画添加到混合空间](JogFwdRifleAsset.png)(w:600)](JogFwdRifleAsset.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

13.导航至 资产浏览器(Asset Browser) ,然后在过滤器搜索栏中,输入 Jog_Lt_Rifle ,然后将 Jog_Lt_Rifle 资产拖放到 方向-90 速度500 混合空间

[REGION:lightbox]
[![将慢跑向左步枪动画添加到混合空间](JogLtRifleProject.png)(w:600)](JogLtRifleProject.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

14.导航至 资产浏览器(Asset Browser) ,然后在过滤器搜索栏中,输入 Jog_Rt_Rifle ,然后将 Jog_Rt_Rifle 资产拖放到 方向90 速度500 混合空间

[REGION:lightbox]
[![将慢跑向右步枪动画添加到混合空间](JogRTAsset.png)(w:600)](JogRTAsset.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

15.在资产浏览器搜索栏过滤器中,输入 Jog_Bwd_Rifle_Ironsights ,然后将 Jog_Bwd_Rifle_Ironsights 资产拖放到 方向180 速度500 混合空间 ,然后将额外的 Jog_Bwd_Rifle_Ironsights 拖放到 方向-180 速度500 的混合空间。

[REGION:lightbox]
[![将慢跑后退步枪动画添加到混合空间](JogBwdRifleAsset.png)(w:600)](JogBwdRifleAsset.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

16.导航到资产浏览器完成你的混合空间,搜索并选择 Sprint_Fwd_Rifle_Ironsights ,然后将 Sprint_Fwd_Rifle_Ironsights 资产拖放到 方向0 速度1000 混合空间

[REGION:lightbox]
[![将冲刺向前步枪动画添加到混合空间](SprintFwdRifleAsset.png)(w:600)](SprintFwdRifleAsset.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

17. 编译(Compile) 保存(Save)

![编译并保存按钮](CompileSave.png)(w:200)

已完成的 Locomotion_BS 将如下图所示!

已完成的移动混合空间

创建蹲伏移动混合空间

完成移动混合空间后,你将需要创建蹲伏移动混合空间。

  1. 内容浏览器(Content Browser) 中,点击 (添加/导入)Add/Import > 动画(Animation) > BlendSpace ,当提示选择骨架时,选择 UE4_Mannequin_Skeleton ,然后将你的混合空间命名为 LocomotionCrouch_BS

  2. 双击打开 Locomotion_BS 混合空间。在 资产详情选项卡(Asset Details tab) 中,导航至 轴设置(Axis Settings) 类别,然后选择 水平轴(Horizontal Axis) 垂直轴(Vertical Axis) 旁边的箭头,查看更多变量详情。

    资产详情轴设置

  3. 水平轴设置(Horizontal Axis settings) 中,将 名称(Name) 变量更改为 方向(Direction) ,然后将 最小轴值(Minimum Axis Value) 设置为 -180 ,将 最大轴值(Maximum Axis Value) 设置为 180

    蹲伏水平轴设置

  4. 垂直轴设置(Vertical Axis Settings) 中,将 名称(Name) 变量更改为 速度(Speed) ,然后将 最大轴值(Maximum Axis Value) 设置为 300

    蹲伏垂直轴设置

  5. 重复"创建移动混合空间"部分的上述步骤,将你的资产放入设置了下述值的混合空间。

    动画资产名称

    速度

    方向

    Crouch_Idle_Rifle_Hip

    0

    0, 90, -90, 180, -180

    Crouch_Walk_Fwd_Rifle_Hip

    300

    0

    Crouch_Walk_Lt_Rifle_Hip

    300

    -90

    Crouch_Walk_Rt_Rifle_Hip

    300

    90

    Crouch_Walk_Bwd_Rifle_Hip

    300

    180, -180

  6. 保存并编译LocomotionCrouch_BS

    编译并保存按钮

已完成的LocomotionCrouch_BS混合空间将如下图所示。

已完成的蹲伏移动混合空间

创建动画蓝图

你将需要 动画蓝图 ,它将根据玩家的当前动作确定要播放的角色动画。此外,你将需要设置 状态机(State Machine) 以便创建 行走(Walk) 蹲伏(Crouch) 状态,然后设置状态之间的过渡。

  1. 内容浏览器(Content Browser) 中,点击 添加/导入(Add/Import)>动画(Animation)>动画蓝图(Animation Blueprint) ,当提示选择骨架时,选择 UE4_Mannequin_Skeleton ,然后将你的动画蓝图命名为 PlayerCharacter_AB

    创建动画蓝图

  2. 双击 PlayerCharacter_AB 打开动画蓝图。在 我的蓝图选项卡(My Blueprint tab) 中,导航至 变量(Variables) 类别 ,并选择旁边的 + 号,创建名为 Is Crouched Is Jumping 两个 布尔 变量。

    Is Crouched和Is Jumping变量

  3. 点击 事件图表(Event Graph) 选项卡,然后从 Try Get Pawn Owner 节点的 返回值引脚(Return Value pin) 拖移,然后从下拉菜单搜索并选择 Cast to BP_PlayerCharacter

    点击查看大图。

  4. Cast to BP_PlayerCharacter 节点的 BP_PlayerCharacter返回时(As BP_PlayerCharacter return) 引脚拖移,然后搜索并选择 Get Is Crouched

    Get Is Crouched

  5. 导航至 我的蓝图选项卡(My Blueprint tab) ,然后从 变量类别(variables category) Is Crouched 变量拖放到 Get Is Crouched 节点的 返回引脚

    点击查看大图。

  6. 投射到BP_PlayerCharacter 输出执行引脚 拖移,将其连接到 Set Is Crouched 节点的 输入执行引脚

    点击查看大图。

  7. Cast to BP_PlayerCharacter 节点的 BP_PlayerCharacter返回时(As BP_PlayerCharacter return) 引脚拖移,然后从 全部操作(All Actions) 下拉菜单搜索并选择 Get Pressed Jump

    添加Get Pressed Jump操作

  8. MyBlueprint 选项卡,导航至 变量类别(variables category) ,然后将 Is Jumping 变量拖放到 Get Pressed Jump 节点的 返回引脚

    点击查看大图。

  9. Set Is Crouched 节点的 输出执行引脚 拖移,将其连接到 Set Is Jumping 节点的 输入执行引脚

    点击查看大图。

10. 编译(Compile) 保存(Save) PlayerCharacter_AB 动画蓝图。

![编译并保存按钮](CompileSave.png)(w:200)

11.从 变量类别(Variables category) 选择旁边的 + 号,创建名为 速度(Speed) 方向(Direction) 的两个 浮点变量

![创建速度和方向变量](SpeedDirectionVariables.png)(w:400)

12.从 Cast to BP_PlayerCharacter 节点的 BP_PlayerCharacter返回时(As BP_PlayerCharacter return) 引脚拖移,然后 启用 上下文相关 框,搜索并选择 Get Velocity

![上下文相关Get Velocity节点](GetVelocityFunction.png)(w:400)
  1. Get Velocity 节点的 返回值(Return Value) 引脚拖移,然后从 操作(Actions) 下拉菜单,搜索并选择 Vector Length

    添加Vector Length节点

14.在 我的蓝图选项卡(My Blueprint tab) 中,将 速度(Speed) 变量拖放到 Vector Length 节点的 矢量返回值(vector Return Value) 引脚。

[REGION:lightbox]
[![将速度变量连接到Vector Length](SpeedVariableConnect.png)(w:600)](SpeedVariableConnect.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

15.然后,将 Set Is Jumping 节点的 执行输出引脚 连接到 Set Speed 节点的 执行输入引脚

[REGION:lightbox]
[![将Set Is Jumping连接到Set Speed](IsJumpSetSpeedExecutionConnect.png)(w:600)](IsJumpSetSpeedExecutionConnect.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

16.从 Cast to BP_PlayerCharacter 节点的 BP_PlayerCharacter返回时 引脚拖移,然后搜索并选择 Get Actor Rotation

![添加Get Actor Rotation节点](GetActorRotationFunction.png)(w:400)
  1. GetActorRotation 节点的 旋转体返回值(rotator return value) 引脚拖移,然后从 操作(Actions) 下拉菜单,搜索并选择 Calculate Direction

    添加Calculate Direction节点

18.然后,从 Get Velocity 节点的 矢量返回值引脚(vector Return Value pin) 拖移,将其插入到 Calculate Direction 节点的 速度输入引脚(Velocity input pin)

[REGION:lightbox]
[![将Get Velocity连接到Calculate Direction](GetVelocityReturnConnect.png)(w:600)](GetVelocityReturnConnect.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

19.从 我的蓝图(My Blueprint) 选项卡,点击拖放 方向(Direction) 变量,并将其拖到 Calculate Direction 节点的 浮点返回值引脚(float Return Value pin)

[REGION:lightbox]
[![将方向变量连接到Calculate Direction节点](ReturnDirectionConnect.png)(w:600)](ReturnDirectionConnect.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

20.然后,将 Set Speed 节点的 执行输出引脚 连接到 Set Speed 节点的 执行输入引脚

[REGION:lightbox]
[![将Set Speed连接到Set Direction](ConnectSpeedDirection.png)(w:600)](ConnectSpeedDirection.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

21.从 Event Blueprint Update Animation 节点的 执行输出引脚 拖移,并将其连接到 Cast To BP_PlayerCharacter 节点。

[REGION:lightbox]
[![将更新动画连接到投射到玩家角色](UpdateExecutionConnect.png)(w:600)](UpdateExecutionConnect.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

22. 编译(Compile) 保存(Save) PlayerCharacter_AB 动画蓝图

![编译并保存按钮](CompileSave.png)(w:200)

已完成的 动画事件图表 将如下图所示

点击查看大图。

创建动画状态机

状态机 可以用图形显示骨骼网格体的动画组织成一系列 状态 。这些状态会在 过渡规则 的控制下从一种状态过渡到另一种状态。你将使用布尔变量在前面分段中创建的不同运动混合空间之间过渡。

  1. PlayerCharacter_AB 动画蓝图中,导航至 动画图表(Anim Graph)

    点击查看大图。

    AnimGraph 用于评估骨骼网格体的最终姿势。

  2. 右键点击 AnimGraph ,并从 操作(Actions) 下拉菜单搜索并选择 添加新的状态机(Add New State Machine)

    添加新的状态机

  3. 将State Machine节点重命名为 Locomotion ,双击节点打开图表。从 条目(Entry) 引脚拖移,并从 操作(Actions) 下拉菜单中选择 添加状态(Add State)

    点击查看大图。

  4. 将新状态命名为 动作(Movement) ,然后双击打开 动作状态节点(Movement State Node) 。导航至 资产浏览器(Asset browser) ,搜索 Locomotion_BS ,然后点击并将其拖放到图表中。

    点击查看大图。

  5. 我的蓝图选项卡(My Blueprint tab) ,点击并将 速度浮点变量 拖放到混合空间的 速度垂直轴

    点击查看大图。

  6. 导航回 我的蓝图选项卡(My Blueprint tab) ,点击并将 方向浮点变量 拖放到混合空间的 方向水平轴

    点击查看大图。

  7. 动画姿势输出引脚(Animation Pose output pin) 连接到 Output Animation Pose 节点的 动画姿势结果引脚(Animation Pose Result pin)

    点击查看大图。

  8. 编译(Compile) 保存(Save)

    编译并保存按钮

  9. 导航回 移动状态机 ,然后点击并拖放 Movement state节点 ,以便创建名为 蹲伏动作(Crouch Movement) 的新动画状态。

    点击查看大图。

10.双击 Transition rule节点**打开 动画图表(Anim Graph)**。

[REGION:lightbox]
[![打开过渡动画图表](MovementToCrouchLocomotion.png)(w:600)](MovementToCrouchLocomotion.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

11.从 我的蓝图选项卡(My Blueprint Tab) ,导航至 变量类别(variables category) ,并将 Is Crouched布尔 拖放到 Result节点 Can Enter Transition输入引脚

[REGION:lightbox]
[![将Is Crouched连接到Can Enter Transition](BoolVariableLocomotionCrouch.png)(w:600)](BoolVariableLocomotionCrouch.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]
  1. 导航回 移动状态机图表 ,双击 蹲伏动作(Crouch Movement) 状态打开动画图表。在 资产浏览器(Asset browser) 中搜索 LocomotionCrouch_BS ,点击并将其拖入图表。

    点击查看大图。

13.从 我的蓝图选项卡(My Blueprint Tab) ,导航至 变量类别(variables category) ,并将 速度(Speed) 方向(Direction) 浮点变量拖放到其在 LocomotionCrouch_BS 上的各自引脚,然后将 LocomotionCrouch_BS 动画姿势 连接到 输出动画姿势引脚(Output Animation Pose Result pin)

[REGION:lightbox]
[![将变量连接到移动蹲伏](FloatVariableLocomotionCrouch.png)(w:600)](FloatVariableLocomotionCrouch.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]
  1. 编译(Compile) 保存(Save) 动画蓝图。

    编译并保存按钮

15.导航回 Locomotion AnimGraph ,然后点击并拖移 CrouchMovement 动画状态 ,并将其连接到 动作动画状态(Movement Animation State)

[REGION:lightbox]
[![将蹲伏动作连接到动作动画](MovementToCrouchMovementTransitionConnect.png)(w:600)](MovementToCrouchMovementTransitionConnect.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

16.双击 Transition rule节点 打开 动画图表(Anim Graph)

[REGION:lightbox]
[![动作到蹲伏动作过渡](MovementToCrouchMovementTransitionRule.png)(w:600)](MovementToCrouchMovementTransitionRule.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

17.从 我的蓝图选项卡(My Blueprints tab) ,点击 Is Crouched 布尔变量并将其拖放到动画图表,选择 Get Is Crouched ,然后从其 输出引脚 拖移,在操作下拉菜单中,搜索并选择 NOT Boolean

[REGION:lightbox]
[![Is Crouched NOT Boolean](IsCrouchedNotBoolean.png)(w:600)](IsCrouchedNotBoolean.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

18.然后,将 NOT Boolean的返回引脚 连接到 Can Enter Transition输入引脚

[REGION:lightbox]
[![将NOT Boolean连接到Can Enter Transition](CrouchToMovementResultConnect.png)(w:600)](CrouchToMovementResultConnect.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

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

![编译并保存按钮](CompileSave.png)(w:200)

20.导航回 动画图表(Anim Graph) ,然后点击并从 动作动画状态 拖移,选择 添加状态(Add State)

[REGION:lightbox]
[![添加跳跃状态](MovementToJumpAddState.png)(w:600)](MovementToJumpAddState.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

21.将此 动画状态 重命名为 跳跃(Jump) ,然后双击打开其动画图表。导航至 资产浏览器(Asset browser) ,搜索 Jump_From_Jog ,然后并将其拖放到图表中。

[REGION:lightbox]
[![从慢跑资产添加跳跃](AssetBrowserJumpFromJog.png)(w:600)](AssetBrowserJumpFromJog.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

22.将 Play Jump_From_Jog 动画姿势连接到 输出动画姿势结果(Output Animation Pose Result) 引脚,完成跳跃动画状态。

[REGION:lightbox]
[![将Jump from Jog连接到输出动画](JumpOutputAnimPose.png)(w:600)](JumpOutputAnimPose.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

23.导航回 移动动画图表(Locomotion Anim Graph) ,然后双击 Movement to Jump Transition rule节点 打开 动画图表(Anim Graph)

[REGION:lightbox]
[![打开动作到跳跃过渡动画图表](MovementToJumpTransitionRuleNode.png)(w:600)](MovementToJumpTransitionRuleNode.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

24.在 过渡规则动画图表(Transition Rule Anim Graph) 中,导航至 我的蓝图选项卡(My Blueprints tab) ,将 Is Jumping 布尔变量拖放到 结果节点的Can Enter Transition输入引脚

[REGION:lightbox]
[![将Is Jumping布尔连接到Can Enter Transition](MoveToJumpBoolTransitionRule.png)(w:600)](MoveToJumpBoolTransitionRule.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

25.导航回 移动动画图表(Locomotion Anim Graph) ,然后点击并拖移 Jump anim节点 创建过渡 Movement Anim Graph节点

[REGION:lightbox]
[![跳跃动画过渡到动作](JumpToMovementTransition.png)(w:600)](JumpToMovementTransition.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

26.双击 *Jump to Movement Transition rule节点** 打开 **动画图表(Anim Graph)**。

[REGION:lightbox]
[![跳跃到动作过渡规则动画图表](MovementToJumpTransitionRule.png)(w:600)](MovementToJumpTransitionRule.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

27.从 我的蓝图选项卡(My Blueprints tab) ,点击 Is Crouched Is Jumping 布尔变量并拖放到 动画图表(Anim Graph) ,然后拖移每个输出引脚,并从操作下拉菜单搜索和选择 NOT Boolean

[REGION:lightbox]
[![添加布尔变量和NOT节点](JumpToMoveBoolVars.png)(w:600)](JumpToMoveBoolVars.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

28.拖移 NOT Boolean输出引脚 ,搜索并选择 AND Boolean

![将NOT Boolean连接到AND Boolean](ActionMenuAndBoolean.png)(w:400)

29.将 Is Crouched Is Jumping NOT Boolean 节点输出引脚连接到 AND Boolean节点的输入引脚 ,然后将 AND boolean的输出引脚 连接到 Result节点的Can Enter Transition输入引脚

[REGION:lightbox]
[![将AND Boolean连接到Can Enter Transition](JumpToMovementTransitionRule.png)(w:600)](JumpToMovementTransitionRule.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

30.导航回 移动动画图表(Locomotion Anim Graph) ,然后点击并拖移 Crouch节点 创建过渡 Jump节点

[REGION:lightbox]
[![Crouch Animation节点过渡到Jump Animation节点](CrouchToJumpTransitionConnect.png)(w:600)](CrouchToJumpTransitionConnect.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

31.双击 Crouch Movement to Jump Transition rule 节点打开 动画图表(Anim Graph)

[REGION:lightbox]
[![打开Jump Transition规则动画图表](CrouchToJumpTransitionRule.png)(w:600)](CrouchToJumpTransitionRule.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

32.在 蹲伏动作到跳跃过渡规则(CrouchMovement to Jump transition rule) 动画图表中,导航至 我的蓝图选项卡(My Blueprints tab) ,然后点击并将 Is Jumping布尔变量 拖放到 Result节点的Can Enter Transition输入引脚

[REGION:lightbox]
[![将Is Jumping连接到Can Enter Transition](CrouchToJumpTransition.png)(w:600)](CrouchToJumpTransition.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

33.导航回 移动动画图表(Locomotion Anim Graph) ,然后拖移 Jump 节点和 创建过渡 CrouchMovement节点

[REGION:lightbox]
[![跳跃过渡到蹲伏动作](JumpToCrouchTransition.png)(w:600)](JumpToCrouchTransition.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

34.双击 Jump to Crouch Movement Transition rule 节点,打开 动画图表(Anim Graph)

[REGION:lightbox]
[![打开跳跃到蹲伏动作过渡规则动画图表](JumpToCrouchMovementTransitionRule.png)(w:600)](JumpToCrouchMovementTransitionRule.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

35.从 我的蓝图选项卡(My Blueprint tab) 点击 Is Crouched Is Jumping 变量并拖放到 动画图表(Anim Graph)

[REGION:lightbox]
[![添加Is Crouched和Is Jumping布尔](JumpToCrouchVariableBoolDrag.png)(w:600)](JumpToCrouchVariableBoolDrag.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

36.从 Is Jumping Boolean输出引脚 拖移,并从操作下拉菜单搜索和选择 NOT Boolean ,然后从 Is Crouched布尔输出引脚 拖移,并搜索和选择 AND Boolean 。 将 Is Jumping NOT Boolean输出引脚 连接到 AND Boolean输入引脚 ,然后将 AND Boolean输出引脚 连接到 Can Enter Transition Result引脚 ,完成此过渡规则。

[REGION:lightbox]
[![连接NOT Boolean和AND Boolean](JumpToCrouchTransitionRules.png)(w:600)](JumpToCrouchTransitionRules.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

37.已完成的 Locomotion AnimGraph 将如下图所示。

[REGION:lightbox]
[![已完成的移动动画图表](CompletedLocomotionGraph.png)(w:600)](CompletedLocomotionGraph.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

38.导航至 AnimGraph ,并将 移动姿势输出引脚(Locomotion Pose Output pin) 连接到 输出姿势结果引脚(Output Pose Result pin)

[REGION:lightbox]
[![将移动动画图表连接到输出姿势结果](ConnectAnimGraph.png)(w:600)](ConnectAnimGraph.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

39. 编译(Compile) 保存(Save)

![编译并保存按钮](CompileSave.png)(w:200)

40.从 内容浏览器(Content Browser) 双击 Bp_PlayerCharacter ,打开 类默认值 ,然后在 组件(Components) 选项卡中,选择 网格体组件(Mesh component) ,然后导航至 细节面板动画类别 ,在 动画类变量下拉菜单中 ,搜索并选择 PlayerCharacter_AB

[REGION:lightbox]
[![将动画添加到蓝图](PlayerCharacter_ABSetup.png)(w:600)](PlayerCharacter_ABSetup.png) 
[/REGION]
[REGION:caption]
点击查看大图。
[/REGION]

结果

现在可以测试你的逻辑。从工具栏选择 Play (PIE) ,你将能够使用W、A、S、D键控制角色的移动。要冲刺,请点击并按住左shift键,要蹲伏,请按住左ctrl,要跳跃,请按空格键。

角色动作的实际效果

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