Hi there,
i am currently trying to understand how to Spawn different AI Actors in the Lyra Project.
I tried the “standard” way without Lyra (Spawn AIFrom class) and although it did indeed spawn my actor, somehow Lyra/The AbilitySystem was not setup correctly for that Pawn and it seemed like some LyraAttributeSets were not correctly set (I could not reduce the Health from that PAwn and the MaxHealth was 0)
So what is the intended Method to spawn new and different AIs with differnet Pawns?
After following the C++LYra Code for quite some time i noticed the function “SetPawnData” which takes a DataAsset (which makes Sense, since this models the Abilities fo example) but i cant figure out if or when i should call it.
My first try just logged an Error, like “PawnData has already been set” and it seems the default Pawn was already set, but currently i dont understand how this is happening.
I’m also interested in figuring this out. It seems that Lyra was built on the assumption that all characters in the game are using the same pawn at any given time.
A placed AI character’s “init state” will not progress beyond “spawned,” which seems to prevent the GAS component from being properly initialized. However, if you spawn the same AI through the Lyra bot spawner component, it will work fine.
The problem there seems to be that 1) it expects a player state, which you may not want for your NPCs and 2) you may need to them have an entirely different base class for their pawn. However, the Lyra Game State assumes you want the pawn defined in your pawn data and will spawn that for your AI controller to posses.
We need to keep this topic open. My web searches are not producing any substance on Lyra specific AI usage nor modifications. I really would prefer to stick with the workflow that is the Lyra-way. Any other way will produce the snowball effect the designers warned us about.
What is missing from the lyra project is a good diagram that answers questions like “What does it take to create a Weapon?” or “Everything necessary to create an AI”. Because each one is programming a different project, it is even a little difficult to understand the questions in the Forum.
@BaseReality
So first thing is AI needs the PlayerState, removing the need for a PlayerState in AI seems to be a bit more involved, since the main issue is that the ability system component gets added to the PlayerState.
If you look at how AI gets spawned in LyraBotCreationComponent, all it’s doing is creating a controller based on the class set in BotControllerClass (this should have “NeedsPlayerState” bool on).
The player state then is listening for a OnExperienceLoaded event, in which it asks the GameMode for a PawnData, the GameMode then checks if the PlayerState has one assinged on its own PawnData Variable, and if not it returns the default for the Experience.
So, we need to intercept this function and give the AI player state another PawnData.
In my case I’ve been trying not to modify the Lyra Code, and instead making child classes of a lot of things to add and modify for my needs.
But here is a quick way if you don’t mind changing Lyra classes, all you have to do is go to LyraExperienceDefinition.h and add a variable
Then in LyraGameMode.cpp find the function called GetPawnDataForController and replace this part
if (ExperienceComponent->IsExperienceLoaded())
{
const ULyraExperienceDefinition* Experience = ExperienceComponent->GetCurrentExperienceChecked();
if (Experience->DefaultPawnData != nullptr)
{
return Experience->DefaultPawnData;
}
// Experience is loaded and theres still no pawn data, fall back to the default for now
return ULyraAssetManager::Get().GetDefaultPawnData();
}
with this
EDIT
if (ExperienceComponent->IsExperienceLoaded())
{
const ULyraExperienceDefinition* Experience = ExperienceComponent->GetCurrentExperienceChecked();
if (InController != nullptr && InController->IsA<AAIController>() && Experience->DefaultAIPawnData != nullptr)
{
return Experience->DefaultAIPawnData;
}
else if (Experience->DefaultPawnData != nullptr)
{
return Experience->DefaultPawnData;
}
// Experience is loaded and theres still no pawn data, fall back to the default for now
return ULyraAssetManager::Get().GetDefaultPawnData();
}
Now you can add the AI PawnData class in the ExperienceDefinition
I’ll Try to remember to come back here once I find a more elegant way without changing Lyra Base Classes, pretty sure its fine if you make your child gameMode and PlayerState and add it there, I already have a custom child player state with custom attribute sets etc
Seems this is either an overlook on Epic or a future to add thing because they even call the PawnData “Hero”
BIG THANKS ! for this as I’m not A C++ Guy, but BP’s gave me a good understanding of Code, and Im willing to try c++ edits.
This is the kind of thing I was looking for. Not a go do a thing without showing me visually what I need to change so top marks for the mini tutorial and explanation.
This is super helpful as I also want to add an extra actor value to the weapon definition so the weapon spawner gives the default weapons to BOT’s but a custom version to the players. I already have that working but as a value in the BP itself.
But being able add a value for, “hey spawn this class for AI bots” and “spawn this class for players” is all I ever wanted and opens up a ton of options in lyra even for different game types. If you discover anything else please keep me informed.
Like many I was super excited watching the Lyra presentation thinking it was the best thing ever, Only to find they gimped it with weird restricted complexity of c++ and not having important values exposed that could make it more flexible for people that are mainly Blueprint coders.
even being able to select a team is not exposed
Im feeling a bit dumb here!
I made the changes to the lyra definition. h
and the gamemode.cpp
but I was not seeing an extra value in the definition in the project
So I think you may have made a typo here In the first bit of code, Did you not mean to say AIpawnData instead of this?
Because when I changed it to AIpawndata I now see it added prob because defaultpawnData is the already existing value, Please correct me if I’m wrong as Im just winging it here and guessing
That is correct, my bad, I hadn’t event made the changes in my project when I posted haha, but yeah It works fine.
Just make sure you use that same variable name in the game mode in the “If Is AI” return. return Experience->DefaultAIPawnData;
will still look for a solution that does not modify any Lyra code, want to be able to just grab their latest.
Hey If your still around I want to add a new dynamic feature to this option .
I think I would Like to have a 2nd player pawn entry.
1: default lyra player pawn hero data entry.
2: my custom VR player pawn hero data entry.
And I would like the experience definition to ask if the head mounted display is enabled or a vr mode is active and then load the relevant hero data for the mode.