unreal-helper-library
unreal-helper-library copied to clipboard
UHL - unreal helper library, helps working with AI, GAS, customizing editor and so on
Unreal Helper Library [UHL]
UHL - unreal helper library, toolset to help developers working with AI, GAS, customizing editor and so on. Goal is to became a tool that insta-installed on new project creation. All tools are mostly tested on melee combat so if you have other background and think that something should work another way or have an idea on how to improve developer experience feel free to discuss.
GAS things not required to be used at all, you can use library only for AI things. GAS features provides much smoother GAS experience mostly based on Lyra features. All GAS features designed in mind that they or their part can be added or dropped by you in development in any time and replaced by something custom that fits your project needs
Support: tested UE5.4 - UE5.5-preview
Install
From source (recommended):
git submodule add https://github.com/Ciberusps/unreal-helper-library.git ./Plugins/UnrealHelperLibrary- add git submodule to your plugins folder- to use C++ things add code to file
<ProjectName>.Build.cs
// <ProjectName>.Build.cs
public GameName(ReadOnlyTargetRules Target) : base(Target)
{
PublicDependencyModuleNames.AddRange(new string[] {
// add "UnrealHelperLibrary" to use it in C++
"UnrealHelperLibrary",
});
// OPTIONALLY add "UnrealHelperEditor" module to use custom unreal engine editor features
if (Target.bBuildEditor)
{
PrivateDependencyModuleNames.AddRange(new string[] { "UnrealHelperEditor" });
}
}
[!NOTE] Don't forget to update your
README.mdwith instructions on how to setup -git submodule update --init --recursiveand how to update submodules/plugin(s) -git submodule update --remote
[!NOTE] Add
Editor Preferences -> Force Compilation on StartupinConfig/EditorPerProjectUserSettings.iniyour team don't want to recompile plugin manually 😉
From marketplace:
later this year on FAB
Update
From source:
git submodule update --remoteto update plugin from source
Modules
UHL consists of 3 modules:
- UnrealHelperLibrary - main module with GAS helper classes, AI behavior tree nodes, Blueprint Function Libraries. Most functionality can be tested in
Gyms(maps for testing atomic/single gameplay mechanic), allGymslocated in/Plugins/UnrealHelperLibrary/Content/Gyms - UnrealHelperEditor - optional module with editor customization, e.g. custom thumnails, custom class icons
- UHL Utils (EditorUtilityWidget) - widget with tools helping you make trivial things, like
ConvertToORMquite often task when you want to combine 3 texturesOcclusion,Roughness,Metalicin one ORM texture
Documentation
UnrealHelperLibrary - main module
- GAS
- Components
- AbilitySystemComponent
- InputConfig (GAS abilities input binding)
- AbilityInputCache (beta)
- GameplayAbility
- AttributeSet
- AbilitySet
- AbilitySystem Config
- Tasks
- InterpolateToPosition
- BaseCharacters
- BaseCharacter
- BaseCharacterWithASC (recommended for start)
- AnimNotifyState (ANS)
- ANS_UHL_Base
- ANS_ActivateAbility
- AI
- Components
- AIPerceptionComponent
- Composite
- RandomSelector
- Services
- GameplayFocus
- Decorators
- CheckGASGameplayTagsOnActor
- InAngle
- InRange
- LoopRandomCount
- RandomChance
- TimeLimitRandom
- Tasks
- SetBBValue
- DebugPrintBBValue
- DebugPrintString
- InvokeGameplayAbility
- PlayAnimMontage
- TurnTo
- Subsystems
- DebugSubsystem
- UnrealHelperLibraryBPL
- GAS
- TryActivateAbilityWithTag
- TryCancelAbilityWithTag
- TryCancelAbilitiesWithTags
- FireGameplayEvent
- UpdateStateGameplayTags
- FindTagByString
- RelativeAngles
- RelativeAngleToActor
- GetPointAtRelativeAngle
- GetPointAtRelativeDirection
- GetPointAtAngleRelativeToOtherActor
- GetPointAtDirectionRelativeToOtherActor
- DirectionToAngle
- Misc
- GetProjectVersion
- GetNamesOfComponentsOnObject
- GetAssetsOfClass
- GetBuildType
- Other
- GetHighestPoint
- LoadingUtilLibrary
- ApplyDefaultPriorityLoading
- ApplyStreamingPriorityLoading
- ApplyHighestPriorityLoading
- ApplyCustomPriorityLoading
- ForceGarbageCollection
- FlushLevelStreaming
- TraceUtilsBPL
- SweepCapsuleSingleByChannel
- Settings
- UHL Settings
UnrealHelperEditor
- UnrealHelperEditor
- Custom thumnails
- Custom class icon
UHL Utils (Editor Utility Widget)
- UHL Utils (Editor Utility Widget)
- ConvertToORM
GAS
Many GAS-related things based on "Lyra" sample project.
AbilitySystemComponent
UHLAbilitySystemComponent - for quick start with GAS. You can nest from it on start and than turn off its functions when you ready to replace them with your custom solution.
Features:
- set
InitialAttributes - give
Abilitieson start - activate
InitialActiveAbilities - apply
InitialGameplayTags - "Lyra"-like "InputConfig", GAS abilities input binding
Setup:
Option 1 - zero setup
Easy way with zero setup, just nest your character from AUHLBaseCharacterWithASC, fits new projects
there you don't want to waste time at all.
Option 2 - BP way
Easy way - just add UHLAbilitySystemComponent to your character and call InitAbilitySystem on BeginPlay/Possessed
Option 3 - C++
A bit harder and requires small C++ work, fits for projects with GAS already integrated.
Follow instructions below or just check AUHLBaseCharacterWithASC example
AUHLBaseCharacterWithASC::AUHLBaseCharacterWithASC(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
// create AbilitySystemComponent if you don't have it
AbilitySystemComponent = CreateDefaultSubobject<UUHLAbilitySystemComponent>(TEXT("UHLAbilitySystem"));
}
void AUHLBaseCharacterWithASC::PossessedBy(AController* NewController)
{
Super::PossessedBy(NewController);
// init AbilitySystem
AbilitySystemComponent->InitAbilitySystem(NewController, this);
}
If you want custom attributes init you can do it
- by overriding
InitAttributes_Implementation- recommended - or just don't activate abilities
AbilitySystemComponent->InitAbilitySystem(NewController, this, false)and make your own attributes init, and then callAbilitySystemComponent->ActivateInitialAbilities()
You have 3 levels of advancement using GAS with UHL
- entry - just using abilities/attributes in your character on start of a project
- when you understand that you want to share some abilities to other characters - use AbilitySets
- when your team grows and you understand that locking whole character just to add ability is or change some ability system settings is too much - use AbilitySystem Config and optionally defaults in UHLSettings
InputConfig (GAS abilities input binding)
Binding InputActions to GameplayAbilities using tags, based on Lyra but enhanced and adopted for 3D action game.
Setup
- turn on
bUseInputConfigonUHLAbilitySystemComponent - create
InputConfig-DataAssetnested fromUHLInputConfig - add
InputConfigto your characterUHLAbilitySystemComponent - in
Project Settings -> Input -> Default Input Component Class-> setUHLInputComponent - in your PlayerCharacter class add lines in
SetupPlayerInputComponentfor binding actions fromInputConfig
For now only C++ setup tested (blueprint option will be later)
// Your PlayerCharacter class
void AUHLPlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
UUHLInputComponent* UHLInputComponent = CastChecked<UUHLInputComponent>(PlayerInputComponent);
UUHLInputConfig* UHLInputConfig = AbilitySystemComponent->InputConfig;
TArray<uint32> BindHandles;
UHLInputComponent->BindAbilityActions(UHLInputConfig, AbilitySystemComponent, &UUHLAbilitySystemComponent::AbilityInputTagPressed, &UUHLAbilitySystemComponent::AbilityInputTagReleased, BindHandles);
// optional
// if (UHLInputComponent)
// {
// UHLInputComponent->BindAction(UHLInputConfig->NativeInputAction_Move.InputAction, ETriggerEvent::Triggered, this, &AUHLPlayerCharacter::InputMove);
// UHLInputComponent->BindAction(UHLInputConfig->NativeInputAction_Move.InputAction, ETriggerEvent::Completed, this, &AUHLPlayerCharacter::InputStopMove);
// UHLInputComponent->BindAction(UHLInputConfig->NativeInputAction_LookMouse.InputAction, ETriggerEvent::Triggered, this, &AUHLPlayerCharacter::InputLook);
// UHLInputComponent->BindAction(UHLInputConfig->NativeInputAction_LookStick.InputAction, ETriggerEvent::Triggered, this, &AUHLPlayerCharacter::InputLook);
// }
}
- in your PlayerController class add
// Your PlayerController.cpp
void AUHLPlayerController::OnPossess(APawn* InPawn)
{
Super::OnPossess(InPawn);
CachedPlayerCharacter = Cast<AUHLPlayerCharacter>(InPawn);
}
void AUHLPlayerController::PostProcessInput(const float DeltaTime, const bool bGamePaused)
{
Super::PostProcessInput(DeltaTime, bGamePaused);
if (!CachedPlayerCharacter.IsValid()) return;
if (UUHLAbilitySystemComponent* ASC = CachedPlayerCharacter.Get()->GetUHLAbilitySystemComponent())
{
ASC->ProcessAbilityInput(DeltaTime, bGamePaused);
}
}
// Your PlayerController.h
UCLASS()
class UHL_API AUHLPlayerController : public APlayerController
{
GENERATED_BODY()
protected:
virtual void OnPossess(APawn* InPawn) override;
virtual void PostProcessInput(const float DeltaTime, const bool bGamePaused) override;
private:
TWeakObjectPtr<AUHLPlayerCharacter> CachedPlayerCharacter;
};
- now create
InputAction(IA) and map it in yourInputMappingContext(IMC) - add
InputActionto createdInputConfigand map it toAbilityTags - now Abilities associated with
AbilityTagswill activates whenInputActiontriggered - WARN! abilities should nest from
UHLGameplayAbilityforActivationPolicywork correctly - to controll ability activation, every
UHLGameplayAbilityhaveActivationPolicyOnInputTriggered- will activate when InputAction triggeredWhileInputActive- activates ability when input pressed and deactivates when input releasedOnSpawn- activates ability when it gived(granted) to character
AbilityInputCache
AbilityInputCache (beta) - caches abilities activation. If you want to have input quality like in AAA games when you need cache some inputs and fire whem when its available. Abilities/Inputs to cache may vary depending on project e.g. for 3D actions(souls-likes, slashers) its critical, for shooters less important
[!WARN] dont work without UHLAbilitySystemComponent and InputConfig enabled
Setup:
Instructions here provided with souls-like developing background. Remember you can control AbilityInputCache wherever ASC(AbilitySystemComponent) is available just take AbilityInputCache from ASC and call AddTagToCache, CheckCache, ClearCache.... If you need "input window" just add UHL.AbilityInputCache.Catching on your character by hand and remove when window not required
- activate
bUseAbilityInputCacheinUHLAbilitySystemComponent - [optionaly] strongly recommended to activate
bUseInputCacheWindowsalso. IfbUseInputCacheWindowsnot activated any GameplayAbility marked withbInputCachethat you try to activate in any time on fail will be added toAbilityInputCachethats not what you want in 3D action game - in
GameplayAbilitythat you want to cache activatebInputCacheand fill if requiredAddingToCacheInputRequiredTags- tags that required to be on your character for this ability to be added toAbilityInputCacheAddingToCacheInputBlockedTags- tags that blocks adding this ability toAbilityInputCache
- prepare you attack animation - add anim notifies
ANS_CatchToAbilityInputCache- to mark when its possible to cache ability. Best practice - leave some frames on start(5-10frames at least) and finish when your "BlockAction" endANS_CheckAbilityInputCache- when you want to check cache and activate ability. Best practice - on end of "BlockAction" with 5-10frames duration
Debug:
- activate
AbilityInputCachedebug category in DebugSubsystem fromProjectSettings -> UHL DebugSubsystem Settings- or in runtime via
UHLDebugCategoriesListWidget
- write in console
ToggleAbilityInputDebug, don't forget to addProcessConsoleExecto yourGameInstanceor it won't work
AttributeSet
Just class with default things that every AttributeSet wants like ATTRIBUTE_ACCESSORS. Nest your AttributeSets from it to not duplicate same things other and other again.
AbilitySet
"Lyra"-like set of Abilities, AttributeSets, GameplayEffects, that can be added to character and removed later by tag
AbilitySet - is second level of advancement of using GAS in UHL, when you understand that you want to share some abilities to other characters - use AbilitySets
Use cases:
- gived by external source using or
AbilitySet->GiveToAbilitySystemand removed by external source viaAbilitySetGrantedHandles.TakeFromAbilitySystem - gived by external source using
ASC->GiveAbilitySet(UUHLAbilitySet* AbilitySet)and removed by tag callingASC->RemoveAbilitySetByTag(), of course if tag associated with set by definingAbilitySetTagsinAbilitySet
AbilitySystem Config
DataAsset - option for teams to edit AbilitySystem config externally to not locking character
for just changing abilities/initial attributes
Defaults can be changed in ProjectSettings -> UHL Settings
GameplayAbility
Additional events - OnSpawn
Activation policy - InputTriggered, WhileInputActive, OnSpawn
InputCache - to use it required to nest from GameplayAbility
InterpolateToPosition
AT_InterpolateToPosition - interpolate actor to specified position/rotation at a predetermined amount of time
BaseCharacter
UHLBaseCharacter - simplest BaseCharacter with only UHL interfaces implemented, so you don't need to do it by yourself
BaseCharacterWithASC
UHLBaseCharacterWithASC - recommended BaseCharacter for start - ASC created on start and
inited on PossessedBy. Can be turned off by disabling bInitUHLAbilitySystemOnPosses
ANS_UHL_Base
ANS_UHL_Base - base AnimNotifyState class with commonly used features like
- subscribing
OnMontageBlendingOutby overridingOnMontageBlendingOutcan be disabled bybUseOnMontageBlendingOut=false(true by default) - more come later
ANS_ActivateAbility
ANS_ActivateAbility - commonly used ANS that just activate ability on start and deactivate on end
GameplayAbilityTag- tag associated with ability to activatebDeactivateOnMontageBlendingOut- should ability deactivates on montage blends outbAllowRemoteActivation- you can allow remote activation
UHLAIPerceptionComponent
⚒️ InProgress
AI
UHL provides most needed AI nodes toolset for developing at least 3d-action AI - GameplayFocus, Random choices using RandomChance and RandomSelector, PlayAnimMontage to play attacks animations, InRange and InAngle to check distance to enemy and required angle
BTC_RandomSelector
Select random child node using weights
With cool validations
Warns if summary of weights > 1
Warns if chances array have more items then child nodes
Shows error if child nodes count > than chances count
CheckGASGameplayTagsOnActor
BTD_CheckGASGameplayTagsOnActor - checks that actor has GAS gameplay tags specified.
[!WARNING] Don't mess with
UBTDecorator_CheckGameplayTagsOnActor- its only checksGameplayTagson actor itself not onAbilitySystem.
Requirements:
- actor should implement
IAbilitySystemInterfaceto getAbilitySystemComponent
InAngle
BTD_InAngle - decorator to check is enemy in one of specified angle ranges. Useful in developing big enemies, for example we developing dragon we want to know is player under the right wing or leg, is player in front of dragon or behind and so on.
InRange
BTD_InRange - decorator to check distance between actors. Compliant with "MoveTo" node have same settings bIncludeSelfCapsuleRadius and bIncludeTargetCapsuleRadius to check distance excluding capsules radiuses
LoopRandomCount
BTD_LoopRandomCount - randomized version of decorator Loop
TimeLimitRandom
BTD_TimeLimitRandom - randomized version of decorator TimeLimit
RandomChance
BTD_RandomChance - commonly used decorator to randomize actions. Fine for single child node, extra bad for multiple nodes due to chance regression, for randomization between multiple child nodes better to use RandomSelector
SetGameplayFocus
BTS_SetGameplayFocus - alternative for "Set default focus". SetGameplayFocus made right way - prevents rotation jittering while enemy rotation. One of most common problems that anybody stucks when starting developing AI - "focus dont work"/"focus works wrong".
Requirements:
- turn on
UseControllerDesiredRotation - turn off
bOrientRotationToMovementUseControllerRotationYawUseControllerRotationPitchUseControllerRotationRoll
Troubleshooting:
- check that nothing "ClearFocus"
- check that MoveTo uses "AllowStafe"
SetBBValue
BTT_SetBBValue - helps settings values in blackboard, supports all blackboard types and for some values event provides opportunity to make calculations like int
DebugPrintBBValue
BTT_DebugPrintBBValue - prints BB value of any type
DebugPrintString
BTT_DebugPrintString - simple task for printing debug info on screen
InvokeGameplayAbility
BTT_InvokeGameplayAbility - activate/deactivate GAS Gameplay Ability by tag, with optional "wait for finishing"
PlayAnimMontage
BTT_PlayAnimMontage - play anim montage with option to customize PlayRate, Starting Position, Start Section Name and stopping montage on task abort
TurnTo
BTT_TurnTo - turn to enemy using turn animations
Drop in replacement for "RotateToFaceBBEntry" but with option to "RotateTo" with animations
To get settings from actor requires IUHLActorSettings to be implemented on character
UnrealHelperLibraryBPL
> RelativeAngles
RelativeAngleToActor
for most cases you want to use "InRange" like IsOtherActorInAngle (or IsOtherCharacterInRange if you want to check distance)
GetPointAtRelativeAngle
GetPointAtRelativeDirection
GetPointAtAngleRelativeToOtherActor
GetPointAtDirectionRelativeToOtherActor
DirectionToAngle
> GAS
CreateGenericGASGameplayEffectSpec - TODO: rename, remove "GAS"
> Misc
GetProjectVersion
Get project version from "Project Settings"
GetNamesOfComponentsOnObject
Get names of actor components on object, usefull for GetOptions UPROPERTY
GetAssetsOfClass
> Other
GetHighestPoint
Subsystems
DebugSubsystem
Any game needs debug system, in mid-size commands you always use limited set of debugging tools more always than others, so DebugSubsystem is as tool for creating your debug system as fast as possible
Use case: I want to have debug for AbilitySystem, it should turn on/off, available in editor between sessions and
Components:
DebugSubsystem
- you can get
IsDebugCategoryEnabled
DebugSubsystemSettings
- add new categories, turn on/off default state, every debug category is a tag
DebugCategoryComponents(DCC)
Check is category enabled/subscribe on debug category state change
WaitDebugCategoryChange- blueprint node to easier checkisDebugCategoryEnabledor not and wait for its changesIsUHLDebugSubsystemEnabled- blueprint nodeDebugCategoriesList- UI component for quick integration in your debug menu
Features:
- you can create DebugCategoryComponents that activate/deactivate console commands, event in blueprints like GAS abilities
- you can even compose DebugCategoryComponents e.g. you want Collisions + HitBoxes, so you can create combined DebugCategory and add "DCC_Collisions" and "DCC_HitBoxes"
- you can "Block" other DebugCategories by tag
- WaitDebugCategoryChange
Setup:
void AUHLPlayerController::BeginPlay()
{
Super::BeginPlay();
UUHLDebugSubsystem* UHLDebugSubsystem = UGameplayStatics::GetGameInstance(GetWorld())->GetSubsystem<UUHLDebugSubsystem>();
UHLDebugSubsystem->SetUpCategoriesThatRequiresPlayerController();
}
How to add DebugCategory: 1)
LoadingUtilLibrary
UHLLoadingUtilLibrary - loading utils from Lyra
ApplyDefaultPriorityLoading
ApplyStreamingPriorityLoading
ApplyHighestPriorityLoading
ApplyCustomPriorityLoading
ForceGarbageCollection
FlushLevelStreaming
TraceUtilsBPL
UHLTraceUtilsBPL - trace utils
Settings
UHL Settings
- You can set defaults for all AbilitySystem and AbilitySystem Config in your project its can be usefull
if you don't want to copy paste your
AttributeSets
UnrealHelperEditor
UnrealHelperEditor - optional module with editor customization, e.g. custom thumnails, custom class icons
Custom thumnails
Custom thumnails - to override thumbnail by your own, just implement IUHECustomThumbnail interface and define your own icon using GetCustomThumbnailIcon()
#if WITH_EDITOR
#include "UHECustomThumbnail.h"
#endif
// IUHECustomThumbnail not available in production build
#if !WITH_EDITOR
class IUHECustomThumbnail {};
#endif
class GAMECODE_API UInventoryItem : public UObject,
public IUHECustomThumbnail
{
// ...
/** IUHECustomThumbnail **/
#if WITH_EDITOR
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
UTexture2D* GetCustomThumbnailIcon() { return Description.Icon; };
#endif
/** ~IUHECustomThumbnail **/
// ...
⚠️ for now works only with C++, TODO add support for blueprints
Custom class icon
Custom class icon - to override classes icons on your own, just implement set settings in Project Settings -> Editor -> UnrealHelperEditor Settings
List of default Unreal Engine Editor icons
UHL Utils (Editor Utility Widget)
⚒️ InProgress
ConvertToORM
Combines separate Occlusion, Roughness, Metalic textures into one ORM
TODO check ref - https://github.com/Atulin/ChannelMerger