I will start a series here along my journey to create a small demo game based on Lyra.
Epics recommends to use it as basis, I am a humble follower of X157 who convinced me on that path - I develop code for decades, but never games until now.
So follow me, stumbling along my path to use Lyra as a toolbox to create a new game. This will be a BluePrint only journey, no C++ will be used.
I will create an infographics for easier recollection - similar to Epics infographics that I always found quite handy to understand component connections.
Other than that, everything will be documtented on:
[Create a global listener to Lyra Gameplay Tag changes]
The next video in this series creates a global listener to any gameplay tag changes on various actors.
We create a simple glowing sphere that adds listeners to the gameplay tags of all characters BPs and reacts when the character triggers a defined ability.
“Wait Gameplay Tag Add to Actor” and “Wait Gameplay Tag Add Remove from Actor” are not runnning in the main game thread, but are multi-threaded, very easy to setup and to replicate: What’s not to like?
[Understanding Lyra Gameplay Cues, Cooldowns and Effects]
I extend our demo map with a teleporter system. We reuse widgets from Unreal Lyra to have cooldown effect shown and look into the game messaging subsystem to establish publisher/subscriber pattern for the widgets.
Finally, we look into Gameplay Cues and Effects.
Video available here: - YouTube
[Create your new Lyra Attribute Set in 5 Minutes using a code generator]
We define new attribute such as Mana, Thirst, Hunger and different attack values and integrate them into a Lyra Attribute Set using an online code generator (Google Colab)
We then use “AbilitySystem.DebugAttribute MyAttribute” to make our attribute visible during gameplay
[Mixamo and using Python to add notifier tracks to animations]
Adding a process to get Adobe Mixamo animations and using Python to automate the creation of the necessary notifier tracks
Video: - YouTube
Notifier tracks added:
LeftFootFX (for AN_FootPlant_Left)
RightFootFX (for AN_FootPlant_Right)
ContextFX (AnimEffect.FootStep.Walk/Land/Jog, … - best copy from existing Lyra Animation and adjust accordingly)
FootSyncMarkers
I use a ready made Mixamo retarget rig from manosmiras - MixamoToUE
For reference, here the commented Python script to add notifier tracks to your animations:
# Bastian Developer. MIT license
#
# Will search selected Animation assets to contain three animation notifier tracks used by Lyra: LeftFootFX, RightFootFX, ContextFX
# If the tracks are not found, they will be added
import unreal
from numpy import * # needs Plugin "Python Foundation Packages"
@unreal.uclass()
class GetEditorUtility(unreal.GlobalEditorUtilityBase):
pass
@unreal.uclass()
class GetEditorAssetLibrary(unreal.EditorAssetLibrary):
pass
@unreal.uclass()
class GetAnimationLibrary(unreal.AnimationLibrary):
pass
editorUtility = GetEditorUtility()
animLib = GetAnimationLibrary()
# get all assets that have been selected
selectedAssets = editorUtility.get_selected_assets()
if len(selectedAssets) == 0:
unreal.log_error("No assets have been selected to check for NotifyTracks - exiting scipt!")
exit()
# define and log array of tracks we want to have in each animation
TracksNeeded = ['LeftFootFX', 'RightFootFX', 'ContextFX','FootSyncMarkers']
for track in TracksNeeded:
unreal.log("Track to be expected: [%s]" % (track))
# open selected assets and compare tracks found with our predefined array 'TracksNeeded'
for selectedAsset in selectedAssets:
unreal.log("Checking '%s'..." % selectedAsset.get_name())
# copy array to remove what we find and only create all the surviving tracks
tmpTracksNeeded = TracksNeeded.copy()
try:
allNotifyTracksForSelectedAsset = animLib.get_animation_notify_track_names(selectedAsset)
except:
# exception getting tracks - maybe thisis not an animation asset?
unreal.log_error("'{asset}' has no tracks - maybe you selected an non-animation asset here?".format(asset = selectedAsset.get_name()))
continue
for existingTrack in allNotifyTracksForSelectedAsset:
unreal.log("{asset}: Found track '{track}'".format(asset = selectedAsset.get_name(), track = existingTrack))
# if name found is already in our tmpArray, remove it from there
try :
tmpTracksNeeded.index(existingTrack) # this will throw an exception if not found
tmpTracksNeeded.remove(existingTrack)
except ValueError :
unreal.log_warning("Unknown track '{track}' already exists in asset '{asset}'".format(track = existingTrack, asset = selectedAsset.get_name()))
# if nothing remains, we continue to the next iteration
if len(tmpTracksNeeded) == 0:
unreal.log_warning("Nothing to do in asset '{asset}'".format(asset = selectedAsset.get_name()))
continue
# now we have pruned the tmpTracksNeeded - but its not empty - let's add what is missing
for remainingTrack in tmpTracksNeeded:
animLib.add_animation_notify_track(selectedAsset, remainingTrack)
unreal.log_warning("I ADDED track '{track}'".format(track = remainingTrack))
selectedAsset.modify(True)
The concept to switch the language is essential for all games - and the longer you wait to lay down the base for that, the more complex it is to do later.
We shortly dive into the Localization Dashboard, look how to edit PO files for translations and change the language on the fly with BP and Lyra option menu.