之前实现武器的装备是通过GA实现,现在通过组件来实现更多功能。
1.启动项目,创建一个ActorComponent类
2.先清除原有的函数,再在该类内创建三个模板函数
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "PawnExtensionComponentBase.generated.h"UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class ARPG_GRIVITY_API UPawnExtensionComponentBase : public UActorComponent
{GENERATED_BODY()public:protected://获取拥有当前对象的指针template<class T>T* GetOwningPawn() const{//静态断言,确保模板类型T是从APawn继承static_assert(TPointerIsConvertibleFromTo<T,APawn>::Value,"'T' Template Parameter get GetPawn must be derived from APawn");return CastChecked<T>(GetOwner());}//获取APawn类型的拥有者指针APawn* GetOwningPawn() const{return GetOwningPawn<APawn>();}//获取使用当前组件的对象的控制器template<class T>T* GetOwningController() const{static_assert(TPointerIsConvertibleFromTo<T,AController>::Value,"'T' Template Parameter get GetController must be derived from AController");return GetOwningPawn<APawn>()->GetController<T>();}};
3.打开项目,创建该类的子类
4.重新启动项目,再创建CombatComponent的子类
5.在玩家角色内实现该组件
在private部分创建该组件
//战斗组件UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Combat", meta = (AllowPrivateAccess = "true"))UXMBCombatComponent* XMBCombatComponent;
在public部分创建获取当前角色该组件的函数
//获取玩家的战斗组件FORCEINLINE UXMBCombatComponent* GetXMBCombatComponent() const { return XMBCombatComponent; }
进入cpp实现该组件
XMBCombatComponent = CreateDefaultSubobject<UXMBCombatComponent>(TEXT("XMBCombatComponent"));
6.启动项目,打开角色,看到CombaComponent表示成功。
7.进入PawnCombatComponent(敌人和玩家共用的CombatComponent)
#pragma once#include "CoreMinimal.h"
#include "Components/PawnExtensionComponentBase.h"
#include "GameplayTagContainer.h"
#include "PawnCombatComponent.generated.h"class AWeaponBase;/*** */
UCLASS()
class ARPG_GRIVITY_API UPawnCombatComponent : public UPawnExtensionComponentBase
{GENERATED_BODY()public://当前装备武器的标签UPROPERTY(BlueprintReadWrite,Category = "XMB|Combat")FGameplayTag CurrentEquippedWeaponTag;//生成武器时注册,bool在注册时都是设为假UFUNCTION(BlueprintCallable, Category = "XMB|Combat")void RegisterSpawnedWeapon(FGameplayTag InWeaponTagToRegister, AWeaponBase* InWeaponToRegister, bool bRegisterAsEquippedWeapon = false);//获取角色当前装备武器的TagUFUNCTION(BlueprintCallable, Category = "XMB|Combat")AWeaponBase* GetCharacterCarriedWeaponByTag(FGameplayTag InWeaponTagToGet) const;//获取角色当前的武器UFUNCTION(BlueprintCallable, Category = "XMB|Combat")AWeaponBase* GetCharacterCurrentEquippedWeapon() const;private://管理角色携带的武器的映射TMap<FGameplayTag, AWeaponBase*> CharacterCarriedWeaponMap; };
// Fill out your copyright notice in the Description page of Project Settings.#include "Components/Combat/PawnCombatComponent.h"#include "XMBDebugHelper.h"
#include "XMBGameplayTags.h"
#include "Items/Weapon/WeaponBase.h"void UPawnCombatComponent::RegisterSpawnedWeapon(FGameplayTag InWeaponTagToRegister, AWeaponBase* InWeaponToRegister, bool bRegisterAsEquippedWeapon)
{// 检查是否已经注册过相同标签的武器checkf(!CharacterCarriedWeaponMap.Contains(InWeaponTagToRegister),TEXT("A named %s has already been added as carried weapon"), *InWeaponTagToRegister.ToString());// 检查武器指针是否有效check(InWeaponToRegister);// 将武器添加到角色携带武器映射中CharacterCarriedWeaponMap.Emplace(InWeaponTagToRegister, InWeaponToRegister);// 如果需要注册为装备武器,则更新当前装备武器标签if (bRegisterAsEquippedWeapon){CurrentEquippedWeaponTag = InWeaponTagToRegister;}const FString WeaponString = FString::Printf(TEXT("Registered %s as carried weapon"), *InWeaponTagToRegister.ToString());Debug::Print(WeaponString);
}AWeaponBase* UPawnCombatComponent::GetCharacterCarriedWeaponByTag(FGameplayTag InWeaponTagToGet) const
{// 检查映射中是否包含指定的武器标签if (CharacterCarriedWeaponMap.Contains(InWeaponTagToGet)){// 尝试查找对应的武器指针if (AWeaponBase* const* FoundWeapon = CharacterCarriedWeaponMap.Find(InWeaponTagToGet)){// 如果找到,返回解引用后的武器指针return *FoundWeapon;}}return nullptr;
}AWeaponBase* UPawnCombatComponent::GetCharacterCurrentEquippedWeapon() const
{// 检查当前装备武器标签是否有效if (!CurrentEquippedWeaponTag.IsValid()){return nullptr;}//通过标签获取对应的武器return GetCharacterCarriedWeaponByTag(CurrentEquippedWeaponTag);
}
8.创建武器的标签,打开Tag
定义武器标签
/* Player tags */ARPG_GRIVITY_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Player_Weapon_Axe);
创建武器标签
/* Player tags */UE_DEFINE_GAMEPLAY_TAG(Player_Weapon_Axe, "Player.Weapon.Axe");
9.打开GameplayAbility
创建获取战斗组件的函数
//获取当前pawn的战斗组件UFUNCTION(BlueprintCallable, Category = "XMB|Ability")UPawnCombatComponent* GetPawnCombatComponentFromActorInfo() const;
实现它
UPawnCombatComponent* UXMBGameplayAbility::GetPawnCombatComponentFromActorInfo() const
{return GetAvatarActorFromActorInfo()->FindComponentByClass<UPawnCombatComponent>();
}
10.启动项目,
打开GA_Shared_SpawnWeapon
11.打开GA_XMB_SpawnWeapon
12.运行
屏幕打印和日志