目录
一、创建角色动画
注:在创建角色动画蓝图的时候,可以直接去创建一个动画蓝图,而不使用UEC++的方式去创建,蓝图中创建变量或者方法,去直接更新角色状态,这里是为了熟悉怎样用UEC++创建,所以不采用蓝图方式直接创建。
1. 创建动画实例类
创建角色蓝图是为了给角色添加动画,使用状态机让角色可以在各种动作之间进行顺滑转换。
基于AnimInstance为角色创建一个动画实例类。
在CharacterAnim.h中重写AnimInstance中的两个方法:
public:
virtual void NativeBeginPlay() override;
virtua lvoid NativeUpdateAnimation(floatDeltaSeconds) override;
NativeBeginPlay是所属组件调用开始时会调用,NativeUpdateAnimation是NativeBeginPlay执行完一次之后,不断更新执行,获取一些角色属性去更新角色动画。
2.创建角色动画蓝图
在自己的文件夹下创建一个动画蓝图,并指定骨骼,这里是指定小白人的骨骼。
创建完之后,双击打开,在类设置中将父类选择为自己创建的动画实例,这样才能去使用自己创建的动画实例类中的变量或者方法。
3.添加变量
添加角色引用的变量,这里使用的是AManCharacter,也可以使用ABaseCharacter,但是后续的角色设置会在AManCharacter蓝图继承类中去设置,所以我这里用AManCharacter。
CharacterAnim.h中:
private:
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category=Properties,meta=(AllowPrivateAccess="true"))
AManCharacter*CharacterRef;//角色引用
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category=Properties,meta=(AllowPrivateAccess="true"))
floatSpeed;//移动速度
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category=Properties,meta=(AllowPrivateAccess="true"))
boolIsInAir;//是否在空中
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category=Properties,meta=(AllowPrivateAccess="true"))
floatDirection;//方向
CharacterAnim.cpp中:
voidUCharacterAnim::NativeBeginPlay()
{
Super::NativeBeginPlay();
CharacterRef=Cast<AManCharacter>(TryGetPawnOwner());
}
voidUCharacterAnim::NativeUpdateAnimation(floatDeltaSeconds)
{
Super::NativeUpdateAnimation(DeltaSeconds);
if(!CharacterRef)
{
CharacterRef=Cast<AManCharacter>(TryGetPawnOwner());
}
else
{
FVectorCharacterVelocity=CharacterRef->GetVelocity();
Speed=CharacterVelocity.Size();
IsInAir=CharacterRef->GetMovementComponent()->IsFalling();
Direction=CalculateDirection(CharacterVelocity,CharacterRef->GetControlRotation());
}
}
需要添加的头文件:
#include"GameFramework/PawnMovementComponent.h"
#include"Gameplay/ManCharacter.h"
4.创建动画状态机
创建动画状态机并双击打开,添加各个动作之间的转化条件。
在动画状态机里面有一些是单个动画混合之后放进来进行动作转化的,这里不进行详细说明,创建混合动画的步骤跟UE4没有太大差别,没有做过混合动画的可以去我UE4的文章里去参考下。
5. 为角色赋予动画蓝图
选中网格体,在信息面板的动画模式选择使用动画蓝图,再将自己创建的动画蓝图设置上去即可。
运行,按键移动,就可以看到自己的角色会执行对应的状态。
6.对应代码
CharacterAnim.h
#pragma once
#include "CoreMinimal.h"
#include "Animation/AnimInstance.h"
#include "CharacterAnim.generated.h"
class AManCharacter;
/**
* 角色的动画蓝图
*/
UCLASS()
class SHOOTINGGAME_API UCharacterAnim : public UAnimInstance
{
GENERATED_BODY()
public:
virtual void NativeBeginPlay() override;
virtual void NativeUpdateAnimation(float DeltaSeconds) override;
private:
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category=Properties,meta=(AllowPrivateAccess="true"))
AManCharacter* CharacterRef;//角色引用
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category=Properties,meta=(AllowPrivateAccess="true"))
float Speed;//移动速度
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category=Properties,meta=(AllowPrivateAccess="true"))
bool IsInAir;//是否在空中
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category=Properties,meta=(AllowPrivateAccess="true"))
float Direction;//方向
};
CharacterAnim.cpp
#include "Animations/CharacterAnim.h"
#include "GameFramework/PawnMovementComponent.h"
#include "Gameplay/ManCharacter.h"
void UCharacterAnim::NativeBeginPlay()
{
Super::NativeBeginPlay();
CharacterRef = Cast<AManCharacter>(TryGetPawnOwner());
}
void UCharacterAnim::NativeUpdateAnimation(float DeltaSeconds)
{
Super::NativeUpdateAnimation(DeltaSeconds);
if (!CharacterRef)
{
CharacterRef = Cast<AManCharacter>(TryGetPawnOwner());
}
else
{
FVector CharacterVelocity = CharacterRef->GetVelocity();
Speed = CharacterVelocity.Size();
IsInAir = CharacterRef->GetMovementComponent()->IsFalling();
Direction = CalculateDirection(CharacterVelocity,CharacterRef->GetControlRotation());
}
}
二、添加武器
注:本文添加武器的方式,并不是角色去捡取的方式,而是暂时通过给角色添加武器模型的方式。
1.骨骼体添加插槽
在创建动画蓝图的时候,使用的是拿着武器的动画,那现在为角色添加一个武器。
我这边目前的做法是在角色网格体下创建一个武器的骨骼体模型组件,在角色的骨骼体手部创建一个武器插槽,在武器骨骼体附加到角色骨骼体的时候,选择创建的手部插槽,这样,武器就会放到手上。
选中小白人的骨骼,在右手处添加一个插槽。
可以选中一个持枪静止的动画,去调整武器在手中的位置。
2.创建武器骨骼体模型组件
因为不确定在之后的开发分享中会不会创建其他类型的角色,所以我在ManCharacter类中去创建武器骨骼体模型组件。
ManCharacter.h中:
private:
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category=Components,meta=(AllowPrivateAccess="true"))
USkeletalMeshComponent* WeaponMesh;
ManCharacter.cpp中:
WeaponMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("WeaponMesh"));
WeaponMesh->SetupAttachment(GetMesh(),"WeaponSocket");
组件实例化之后,附加到之前创建的武器插槽WeaponSocket处,编译通过之后,打开编辑器,找到ManCharacter蓝图类,为武器赋予模型。
3.对应代码
ManCharacter.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Gameplay/BaseCharacter.h"
#include "ManCharacter.generated.h"
class USkeletalMeshComponent;
/**
* 小白人角色
*/
UCLASS()
class SHOOTINGGAME_API AManCharacter : public ABaseCharacter
{
GENERATED_BODY()
public:
AManCharacter();
protected:
virtual void BeginPlay() override;
private:
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category=Components,meta=(AllowPrivateAccess="true"))
USkeletalMeshComponent* WeaponMesh;
};
ManCharacter.cpp
#include "Gameplay/ManCharacter.h"
AManCharacter::AManCharacter()
{
PrimaryActorTick.bCanEverTick = true;
WeaponMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("WeaponMesh"));
WeaponMesh->SetupAttachment(GetMesh(),"WeaponSocket");
}
void AManCharacter::BeginPlay()
{
Super::BeginPlay();
}