Inventory Integration
Last modified: 01 April 2025Combat and Inventory can be integrated via the Weapon Manager and Weapon classes. You can do so using Blueprints or C++. This guide will walk you through the steps necessary to integrate both systems.
Create a base Weapon Actor, extending from
ANinjaCombatWeaponActor
.Add
NinjaEquipmentReceiverComponent
to this base Weapon Actor.Add the
EquipmentActorInterface
to the list of implemented interfaces.Implement the
GetWeaponOwner
function, from theWeaponInterface
, to provide the Equipment Owner.BlueprintC++// Ninja Bear Studio Inc., all rights reserved. #pragma once #include "CoreMinimal.h" #include "GameFramework/NinjaCombatWeaponActor.h" #include "IntegratedEquipmentWeaponActor.generated.h" class UNinjaEquipmentReceiverComponent; /** * A weapon actor that is prepared to be used with Equipment instances. */ UCLASS(Abstract, Blueprintable) class PLUGINLABS_API AIntegratedEquipmentWeaponActor : public ANinjaCombatWeaponActor { GENERATED_BODY() public: AIntegratedEquipmentWeaponActor(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); // -- Begin Weapon implementation virtual AActor* GetWeaponOwner_Implementation() const override; // -- End Weapon implementation private: UPROPERTY() TObjectPtr<UNinjaEquipmentReceiverComponent> EquipmentReceiver; };
// Ninja Bear Studio Inc., all rights reserved. #include "GameFramework/IntegratedEquipmentWeaponActor.h" #include "Components/NinjaEquipmentManagerComponent.h" #include "Components/NinjaEquipmentReceiverComponent.h" #include "GameFramework/NinjaEquipment.h" #include "GameFramework/NinjaInventoryItem.h" #include "GameFramework/ItemFragments/ItemFragment_Level.h" AIntegratedEquipmentWeaponActor::AIntegratedEquipmentWeaponActor(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { static const FName EquipmentReceiverName = TEXT("EquipmentReceiver"); EquipmentReceiver = CreateDefaultSubobject<UNinjaEquipmentReceiverComponent>(EquipmentReceiverName); } AActor* AIntegratedEquipmentWeaponActor::GetWeaponOwner_Implementation() const { if (IsValid(EquipmentReceiver) && EquipmentReceiver->Implements<UEquipmentActorInterface>()) { const UNinjaEquipment* Equipment = IEquipmentActorInterface::Execute_GetEquipment(EquipmentReceiver); if (IsValid(Equipment)) { return Equipment->GetEquipmentManager()->GetOwner(); } } // No integration or no receiver/equipment. Use the default weapon method. // It will most likely attempt to find the actor to which this one is attached to. // return Super::GetWeaponOwner_Implementation(); }
Implement the
GetHitEffectLevel
function, from theWeaponInterface
, to provide the Equipment Level.BlueprintC++// ... UCLASS(Abstract, Blueprintable) class PLUGINLABS_API AIntegratedEquipmentWeaponActor : public ANinjaCombatWeaponActor { // ... virtual float GetHitEffectLevel_Implementation() const override; // ... };
float AIntegratedEquipmentWeaponActor::GetHitEffectLevel_Implementation() const { // Consider the fallback level as the default effect set in the class. float ItemLevel = Super::GetHitEffectLevel_Implementation(); if (!bUseItemLevelAsEffectLevel) { return ItemLevel; } if (IsValid(EquipmentReceiver) && EquipmentReceiver->Implements<UEquipmentActorInterface>()) { const UNinjaEquipment* Equipment = IEquipmentActorInterface::Execute_GetEquipment(EquipmentReceiver); if (!IsValid(Equipment)) { return ItemLevel; } const UNinjaInventoryItem* Item = Equipment->GetItem(); check(IsValid(Item)); const UItemFragment_Level* LevelFragment = Item->FindFragment<UItemFragment_Level>(); if (IsValid(LevelFragment)) { ItemLevel = LevelFragment->GetLevel(Item); } } return ItemLevel; }
note
Default Level
Make sure to set the value of Default Level to
1
as a fallback! Otherwise, items without levels will apply an effect with level zero!The Base Weapon Class already provides a variable for the effect level, which you can use as a fallback.
Create a new Actor Component, extending from
ActorComponent
.Add the
CombatWeaponManagerInterface
to the list of implemented interfaces.Implement the
GetWeapon
function, to retrieve the weapon using the Equipment Manager.BlueprintC++// Ninja Bear Studio Inc., all rights reserved. #pragma once #include "CoreMinimal.h" #include "Components/ActorComponent.h" #include "Interfaces/Components/CombatWeaponManagerInterface.h" #include "IntegratedWeaponEquipmentComponent.generated.h" /** * Integration between Combat (Weapon Manager) and Inventory (Equipment Manager). */ UCLASS(Abstract) class PLUGINLABS_API UIntegratedWeaponEquipmentComponent : public UActorComponent, public ICombatWeaponManagerInterface { GENERATED_BODY() public: // -- Begin Weapon Repository implementation virtual AActor* GetWeapon_Implementation(const FGameplayTagQuery& WeaponQuery) const override; // -- End Weapon Repository implementation };
// Ninja Bear Studio Inc., all rights reserved. #include "Components/IntegratedWeaponEquipmentComponent.h" #include "NinjaCombatLog.h" #include "Interfaces/CombatWeaponInterface.h" #include "NinjaEquipmentFunctionLibrary.h" #include "Components/NinjaEquipmentManagerComponent.h" #include "GameFramework/NinjaEquipment.h" AActor* UIntegratedWeaponEquipmentComponent::GetWeapon_Implementation(const FGameplayTagQuery& WeaponQuery) const { AActor* WeaponActor = nullptr; const UNinjaEquipmentManagerComponent* EquipmentManager = UNinjaEquipmentFunctionLibrary::GetEquipmentManager(GetOwner()); if (!IsValid(EquipmentManager)) { COMBAT_LOG(Warning, "No equipment manager assigned to the owner."); return WeaponActor; } const UNinjaEquipment* Equipment = EquipmentManager->GetFirstEquipmentByQuery(WeaponQuery); if (!IsValid(Equipment)) { COMBAT_LOG_ARGS(Verbose, "No equipment found for query: %s.", *WeaponQuery.GetDescription()); return WeaponActor; } WeaponActor = Equipment->GetEffectCauserActor(); if (!IsValid(WeaponActor) || !WeaponActor->Implements<UCombatWeaponInterface>()) { COMBAT_LOG_ARGS(Warning, "Equipment %s does not have an Effect Causer Actor.", *GetNameSafe(Equipment)); return WeaponActor; } return WeaponActor; }
Add the new Actor Component created in the previous step to the base Character.
Make sure that this Character has an Equipment Manager properly configured.
Implement the
GetWeaponManager
function, to provide the new component.BlueprintC++// Ninja Bear Studio Inc., all rights reserved. #pragma once #include "CoreMinimal.h" #include "GameFramework/Character.h" #include "Interfaces/CombatSystemInterface.h" #include "IntegratedEquipmentWeaponActor.generated.h" class UIntegratedWeaponEquipmentComponent; /** * Base character class. */ UCLASS(Abstract) class PLUGINLABS_API ACombatCharacter : public ACharacter, public ICombatSystemInterface { GENERATED_BODY() public: ACombatCharacter(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); // -- Begin Combat System implementation virtual UActorComponent* GetWeaponManagerComponent() const override; // -- Begin Combat System implementation private: UPROPERTY() TObjectPtr<UIntegratedWeaponEquipmentComponent> WeaponManager; };
#include "GameFramework/CombatCharacter.h" #include "Components/IntegratedWeaponEquipmentComponent.h" ACombatCharacter::ACombatCharacter(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); static const FName WeaponManagerName = TEXT("WeaponManager"); WeaponManager = CreateDefaultSubobject<UIntegratedWeaponEquipmentComponent>(WeaponManagerName); }; UActorComponent* ACombatCharacter::GetWeaponManagerComponent() const { return WeaponManager; }