Tạo Tư Thế Đồ Họa Khi Trang Bị Vũ Khí Trong Unreal Engine 5

Tạo Tư Thế Đồ Họa Khi Trang Bị Vũ Khí

Trong bài học này, chúng ta sẽ thay đổi tư thế hoạt ảnh của nhân vật khi họ trang bị vũ khí. Điều này đảm bảo rằng trong một trò chơi nhiều người chơi, tất cả các client sẽ đồng bộ hóa đúng cách để hiển thị tư thế hoạt ảnh trang bị vũ khí của nhân vật.

1. Phát hiện trạng thái trang bị vũ khí trong lớp Animation Instance

Đầu tiên, chúng ta cần một cách để xác định xem nhân vật có đang trang bị vũ khí hay không. Chúng ta sẽ thực hiện điều này bằng cách thêm một biến boolean vào lớp Animation Instance và cập nhật nó từ lớp nhân vật.

1.1. Thêm biến vào lớp Animation Instance

Trong tệp tiêu đề của lớp Animation Instance (ví dụ: `MyAnimInstance.h`), thêm một biến boolean để theo dõi trạng thái trang bị vũ khí.

// MyAnimInstance.h
#pragma once

#include "CoreMinimal.h"
#include "Animation/AnimInstance.h"
#include "MyAnimInstance.generated.h"

UCLASS()
class MYGAME_API UMyAnimInstance : public UAnimInstance
{
    GENERATED_BODY()

protected:
    virtual void NativeUpdateAnimation(float DeltaTime) override;

private:
    UPROPERTY(BlueprintReadOnly, Category = "Character")
    class AMyCharacter* MyCharacter;

    UPROPERTY(BlueprintReadOnly, Category = "Movement")
    float Speed;

    UPROPERTY(BlueprintReadOnly, Category = "Movement")
    bool bIsInAir;

    UPROPERTY(BlueprintReadOnly, Category = "Movement")
    bool bIsAccelerating;

    // Biến mới để kiểm tra trạng thái trang bị vũ khí
    UPROPERTY(BlueprintReadOnly, Category = "Movement")
    bool isWeaponEquipped;
};

1.2. Tạo hàm kiểm tra trong lớp nhân vật

Tạo một hàm trong lớp nhân vật (`MyCharacter.h`) để kiểm tra xem vũ khí có đang được trang bị hay không. Hàm này sẽ truy cập vào thành phần chiến đấu (Combat Component) để lấy thông tin.

// MyCharacter.h
#pragma once

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

class UCombatComponent;

UCLASS()
class MYGAME_API AMyCharacter : public ACharacter
{
    GENERATED_BODY()

public:
    AMyCharacter();

    // Hàm để kiểm tra xem vũ khí có đang được trang bị không
    UFUNCTION(BlueprintCallable)
    bool IsWeaponEquipped();
};

1.3. Định nghĩa hàm trong tệp .cpp

Trong tệp `MyCharacter.cpp`, định nghĩa hàm `IsWeaponEquipped()` để trả về true nếu `CombatComponent` có một vũ khí được trang bị.

// MyCharacter.cpp
#include "MyCharacter.h"
#include "Components/CombatComponent.h"

AMyCharacter::AMyCharacter()
{
    // Thiết lập các thành phần mặc định
}

bool AMyCharacter::IsWeaponEquipped()
{
    if (CombatComponent)
    {
        return CombatComponent->GetCurrentWeapon() != nullptr;
    }
    return false;
}

1.4. Cập nhật trạng thái trong Animation Instance

Trong hàm `NativeUpdateAnimation` của `MyAnimInstance.cpp`, gọi hàm `IsWeaponEquipped()` của nhân vật để cập nhật biến `isWeaponEquipped`.

// MyAnimInstance.cpp
#include "MyAnimInstance.h"
#include "MyCharacter.h"

void UMyAnimInstance::NativeUpdateAnimation(float DeltaTime)
{
    Super::NativeUpdateAnimation(DeltaTime);

    if (MyCharacter == nullptr)
    {
        MyCharacter = Cast<AMyCharacter>(TryGetPawnOwner());
    }
    if (MyCharacter)
    {
        // Cập nhật các biến vận động khác...
        Speed = MyCharacter->GetVelocity().Size2D();
        bIsInAir = MyCharacter->GetCharacterMovement()->IsFalling();
        bIsAccelerating = MyCharacter->GetCharacterMovement()->GetCurrentAcceleration().SizeSquared() > 0.f;

        // Cập nhật trạng thái trang bị vũ khí
        isWeaponEquipped = MyCharacter->IsWeaponEquipped();
    }
}

2. Sao chép trạng thái trang bị vũ khí cho các client

Vấn đề hiện tại là biến `CurrentWeapon` trong `CombatComponent` không được sao chép (replicated). Điều này có nghĩa là client không biết nhân vật khác đang trang bị vũ khí hay không. Chúng ta cần sửa điều này.

2.1. Đánh dấu vũ khí là có thể sao chép

Trong tệp tiêu đề của `CombatComponent` (`CombatComponent.h`), đánh dấu biến `CurrentWeapon` là có thể sao chép.

// CombatComponent.h
#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "CombatComponent.generated.h"

class AWeapon;

UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class MYGAME_API UCombatComponent : public UActorComponent
{
    GENERATED_BODY()

public:
    UCombatComponent();

    // Các hàm khác...

protected:
    virtual void BeginPlay() override;

private:
    class AMyCharacter* Character;

    // Đánh dấu vũ khí là có thể sao chép
    UPROPERTY(Replicated)
    class AWeapon* CurrentWeapon;
};

2.2. Đăng ký thuộc tính để sao chép

Trong tệp `CombatComponent.cpp`, ghi đè hàm `GetLifetimeReplicatedProps` để đăng ký `CurrentWeapon` để sao chép.

// CombatComponent.cpp
#include "CombatComponent.h"
#include "Net/UnrealNetwork.h"

UCombatComponent::UCombatComponent()
{
    // Thiết lập các giá trị mặc định
}

void UCombatComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);

    // Đăng ký thuộc tính CurrentWeapon để sao chép
    DOREPLIFETIME(UCombatComponent, CurrentWeapon);
}

3. Thêm logic vào Animation Blueprint

Bây giờ, chúng ta cần sử dụng biến `isWeaponEquipped` trong Animation Blueprint để pha trộn giữa các tư thế hoạt ảnh khác nhau.

3.1. Sử dụng nút "Blend Poses by bool"

Mở Animation Blueprint của bạn (ví dụ: `MyAnimBP`). Trong khối `AnimGraph`, thêm một nút Blend Poses by bool.

Tạo một biến boolean trong Animation Blueprint và đặt tên là `Weapon Equipped`. Kết nối biến này với chân `Active Value` của nút `Blend Poses by bool`.

3.2. Thiết lập các tư thế hoạt ảnh

Tạo một State Machine mới và đặt tên là `Equipped`. Thêm các nút hoạt ảnh vào State Machine này (ví dụ: `Idle_Rifle_Hip`). Kết nối nút `Entry` với nút hoạt ảnh này.

Kết nối đầu ra của State Machine `Equipped` vào chân `True Pose` của nút `Blend Poses by bool`.

Kết nối đầu ra của State Machine `Unequipped` (từ các bài học trước) vào chân `False Pose` của nút `Blend Poses by bool`.

Cuối cùng, kết nối đầu ra của nút `Blend Poses by bool` vào chân `Result` của nút `Output Pose`.

Bây giờ, khi biến `Weapon Equipped` là `true`, Animation Blueprint sẽ sử dụng tư thế hoạt ảnh từ State Machine `Equipped`. Khi nó là `false`, nó sẽ sử dụng tư thế hoạt ảnh từ State Machine `Unequipped`.

Thẻ: Unreal Engine 5 C++ Animation Blueprint replication Multiplayer

Đăng vào ngày 7 tháng 6 lúc 03:20