This video demonstrates how to optimize Unreal Engine 5's Lyra indicator system (name plates above character heads) by converting from a component-based approach to an Entity Component System (ECS) architecture. The developer identifies that the original update canvas function was taking 4 milliseconds when handling 1000 entities, and through ECS implementation with spatial queries, sorting by distance, and proper entity management, the system achieves significantly better performance (55 microseconds for 1000 entities). Key optimizations include using ECS registry sorting, implementing max name plate count limits, adding distance-based opacity and scaling, and decoupling from skeletal mesh components to allow any entity with a name plate source tag to have indicators.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
[UE5] Rewriting lyra's indicators #shortsAdded:
Hello.
Hello.
Oh no. Oh no. That was the wrong one.
Already added. Oops. Oopsies.
Remove source.
Wait.
Oh, it automatically does it. Okay, never mind. We are good. We are a good Mhm.
There. Okay, there are all of my thingies. Cool.
All right, let's get started.
I am revisiting uh my Lyra indicators.
Uh I had broken them.
I used to have little name plates essentially is what that is. Little name plates.
Hello private. Welcome. New name.
New name. Welcome in.
Oh yeah. Do we need that many? Do we need that many?
I don't think so. Well, no, cuz I'm going to be doing performance comparisons. So, we're going to keep it static there. Uh, but yeah, those name plates are what I'm working on today because I wanted to add those little health bars to the trees that I've been working on. Tree chopping.
So, that's what we're doing today.
That's what we're doing today. Okay. So, I think uh when I was looking at the performance of it, it's not it wasn't great in this uh worst case scenario.
So, there's some pretty easy performance savings that I can get by just uh switching this over to ECS. So, I'm going to do that.
I'm going to do that.
This um where is it? Where is the function? This update canvas function is the is the worst offender. Good.
Welcome.
And I was sneezy boy today. Boy, am I a sneezy boy.
So, yeah, I've been kind of going through here and adjusting things.
I added in uh scaling to the name place cuz they were all just one size no matter how far away they were. So, I want to I want to update that. That's a goal for today. I do have the ability to scale them. Wrote that in. And then opacity as well.
Um, yeah, opacity. So, I'm going to use that for like when you're targeting someone, that one's going to show in full uh opakquakeness.
Full full opaken. Is that the right way to say it? Yeah, I think so.
And then all the other ones are going to be transparent on some level.
I'm vibe coding in Unreal at the moment.
The horror.
Welcome in Ice Creek. Been a while.
Hello.
Uh, so yeah, I think what I need to do here, I've already set up the Lyra indicator descriptors to be spawned with an entity right there.
And I think I need to actually create the data.
Dude, if I'm going to be sneezing the whole time, if I'm going to be sneezing the whole goddamn time.
Um, okay. So, I have a couple views I've set up here. I need to figure out how to sort an ent view. Are you coding? I am coding. Yes. Well, I haven't written a lick of it today yet, but I am I am getting there.
Okay, they didn't have my answer.
Uh, you do registry sort.
Okay.
So, ECS registry sorts and then we want f name plate indicators data and then it takes the sort function See, the thing is I want to sort by How do I want to do this? Because I want to sort by closest to player cuz I I want a max number of name plates on the screen.
So I would I would actually need to sort this one, but then every that's going to be every [ __ ] entity. Can I do Can I put two in here?
I only want to sort the ones that have name plates.
dot use. Is that actually Are you hallucinating that or is that real?
No, that is uh that is valid. That is valid ENT syntax there.
Let's read some GitHub posts here.
I guess I have to look up the data on the sort, right?
When I sort over the name plate data, I literally took allergy medicine. I'm still sneezing my ass off, man.
Mhm.
Yeah, I think I need to sort I think what we have to do is like this.
And then I need to Uh yeah, I mean sort of that except not.
Sort of that except not.
Uh something like that. Yeah, we got to capture a local player here.
And everything that has a name plate source should have a location. I'm not even going to check.
Local player, what is your I think I have to like get pawn or something. How do I get uh what what are you local player? What's your What do you got on you?
What do you got on you?
Why can't I get the [ __ ] player actor?
Like what?
Player controller. I suppose that works.
I'll just create a var variable for this player location.
And then why are you mad? Uh oh. Right, right, right. Yeah, you guys are different variables.
FEX was able to add a sprint gameplay builder and change the animation blueprint to have different animations.
Impressive stuff.
>> PC specs.
>> If you have to ask big man, you can't afford it.
>> Okay, so this theoretically should be sorted.
And then we're going to do use I suppose is the syntax here. Use name plate indicators data which should good god what is this?
That is not correct.
Can I see the actual docks here?
How do I actually do I need to do use iteration order?
By default, a view is iterated along a pool that contains the smallest number of elements. I mean that should be name plate indicators data but oh you have to you just call it on it afterwards. Okay I see I see I see there we go.
Here we go. Okay.
So, we're we're basically what we're going to do here is I have a max. I guess this should be in game settings.
I don't have player settings yet.
I don't have a notion for that. I don't feel like doing that right now. It seems like a side quest.
Uh let's just do let's put a little section up here.
I'll I'll probably put this somewhere else later.
Uh, and then this is going to be int max name plates.
I don't know. I don't know if this should be a player. I think it was set to 30 before. I don't know if that's like a player setting or something else like a server set variable.
Uh, but we can do max name plates. Maybe a name plate. Uh uh. Woo. Whoop. Float name plate. Yeah.
So, I'm going to right now they're coupled to the skeletal meshes, but I think I want to change that. Go 4,000.
And then I'm going to need some structure to determine their opacity ranges basically based on distance.
or their scale. I mean, not opacity.
Although opacity based on distance is an interesting idea.
But anyways, we have that there. Let's go game settings.
Let's just put this at the top, right?
Uh, what are these settings? What do I call those? Just game settings. Okay.
Uh, get max. Uh, what did I call it? Get max num name plates or just get max name plates and then float get name plate view distance.
Okay.
Uh, yep.
Oh, come back. Come back to me. Here we go.
Name plate view distance. Yeah. Okay.
So, we have those. Let's go back into our processor.
And so, we're just going to say I guess I need a count.
Uh, you game settings.
Get max name plates. Oh, you're not you're not static, are you?
And then we want to break.
Well, I guess I want to remove all of the rest of the datas, right?
Yeah. Yeah.
What are Lyra indicators? They're the little name plates that float above their head. I I I yanked that system out and I'm rewriting it now.
The uh this update canvas function was taking like I think it was originally taking four when I had a thousand entities all spawn in a location. Um, the closest ones are all skeletal meshes. And when they're skeletal meshes, they have the name plate source component that comes with the Lyra systems.
And I would have like I had like 400 Lyra indicators and this function was taking like 4 milliseconds. So trying to cut down on that.
Rate my PC.
>> I don't think so.
>> Don't want to do that.
Thanks for sharing with the class though.
So yeah, I'm going to kind of like decouple. I'm not going to have components anymore.
Components are slow.
So this is my way on my way to doing that.
So yeah, we're going to remove the name plate indicators data.
I suppose I need to add that when it gets spawned.
No, I'm going to add that here. Yeah, yeah, yeah, yeah, yeah. So, I'm going to have a name plate source tag here.
Rather than using a Unreal Engine component, I'm going to use an ECS component.
Do I need to sort these?
>> I don't think so.
>> I don't think so.
>> I'm using that I'm using that one a lot today.
I also don't think I want to iterate over every single name plate source that has that doesn't have indic an an indicator.
Also, this should probably go first before this view, I think, because then we're going to end up with more.
What is that thing to my right?
Oh, you mean it? This to my That's my That's That's my left. I guess that uh does look like my ride, doesn't it?
That is the Tower of Barador.
The Lego Eye of Sauron.
Okay. So, let's also check distance.
And honestly, if we're sorted, if we are sorted based on distance, the second we find one that's a greater distance, then the then we don't need to calculate it anymore. Basically, let's go too far.
If I can [ __ ] spell here too far.
Yeah, if we are beyond max name plates don't even do anything else.
Else what are we going to do here? We were going to say something like I do want uh yeah the indicator data. Yeah. Yeah.
Yeah. That would be there too.
I hate allergies.
So, I guess let's just check here. No, do this first. Do this part first.
Have you been toiling away your game since I last saw it? No, I actually stopped once you started once you stopped showing up. So, I was I was waiting for you to come back.
I noticed you were gone. I was like, "Well, Ice Creek is going to want to see this, so I'm going to stop." So, it's been Yeah, it's been a long time. I'm glad you're back so I can keep working on it. I've been wanting to work on it so bad.
Okay. Yeah. If we're already too far, then we just do that basically.
Reach that down. I'm sorry for forgetting progress on your game. You should be. How dare you? How dare you?
I'm kidding. Of course. Yes, of course I've been. I have been working on the game.
actually do greater than not greater than or equal. Okay, so we've iterated over them. If we're already too far, just remove Okay. Yeah, I think that's good for that view. That view is good.
Uh, this one potential indicators view.
Now, yeah, I don't want to iterate over every single entity in the [ __ ] world. That's not going to be good. Do I do a spatial query for this? Maybe.
Oh, I also need to know what uh what they are too, right?
Cuz now I have buildings are now a part of my spatial queries, which was cool that they just kind of I just added location data to the the buildings and then they automatically got uh added to that. Didn't even have to do anything.
the beauty of ECS.
So yeah, I guess there could be setting cuz I know in like WoW you can toggle name plates for like uh only enemy units, only pets or or you know you can you can toggle them separately. enemy units, pets, totems, friendly players, yourself.
And I guess for me, there's also going to be buildings as well.
So I don't know, would you want I guess the max number of name plates is max total.
Yeah. So this view would be source independent for sure, but then potential indicators view when we're adding new indicators.
That would depend on what settings we have. Hey, what's up? Been a while since I've got a YouTube sub notification. Welcome in, my man.
So, let's just add like a little bit here.
Uh, ble show building name plates.
Let's go falls for now.
And let's make a couple more.
B, show friendly name plates.
B. And then what about neutral? Do I need a separate one for neutral?
Or is that I think that that is included in enemy name plates there.
I don't have pets or anything yet, so that's not going to matter.
Glasquow has a shorter distance to display name plates than most spell ranges, which is really annoying. Yeah, I agree.
I agree. I would like to see those from farther away. I think part of it um because one thing I'm going to have to do here is check LOS line of sight and I think it's probably why they do that cuz doing an LOS check is not something you can do on the client.
So it's like literally the larger the view distance is the more processing power it is on the server more bandwidth is taken up you know yeah I think I I want to do a spatial query here.
Is it VS Code? No. No.
If you ask a third time, the answer is going to be no as well. Yep. Nope. Nope.
Still no. I knew it was coming. I knew it was coming.
All right.
All right. We'll take care of that before it gets out of hand.
I kind of want to write a better interface for my chunk processor.
Uh, do I have a chunk processor? for funky wonkier in game settings.
No, let's uh let's toss that in somewhere.
Uh you chunk processor or I guess it's just get processor, right? Yeah. Yeah. Yeah. Just you my processor.
It is templated.
It is templateed.
Which Unreal Engine version you use for 3D modeling or something?
Um, I do not use Unreal Engine for 3D modeling, nor do I do 3D modeling, I am on version 57.
So, I guess this needs to be templated, which I don't like. I don't like that because then I'm going to need to include game mode rather than forward declaring it.
If I do that, then that kind of defeats the part of the purpose of this class, which is to isolate.
Like I don't want to if I change something in game mode, which has a lot of stuff in it. I don't want to have to rebuild the entire, you know, my entire application because everything includes game mode.
So, this is kind of lame.
This is kind of lame. I think I need a blueprint version of this.
No, we're not going to inline that.
There we go. That's what we want.
Forward declare, of course.
Oh yeah, it needs to be U entity processor. Yeah.
We'll just call it BP.
Why blueprint callable and blueprint pure at the same time? Uh, they do different things. What do you mean?
Blueprint pure makes it uh one of those little const nonexecution pin nodes.
Blueprint Collable just allows you to use it in blueprints at all.
Welcome in.
Sorry, I'm a sniffly sneezy mess this morning.
Pure includes callable. Does it actually?
I would love to see. Can you show me?
Can you show me the where this is defined at, please? Unreal Engine.
There are more There are more blueprint pures than that.
I will have to confirm that at a later time.
Uh, and process. Uh, yeah, that's that's good. Let's Yeah, that's that's good. That's good.
Uh, now we can use that in game settings. Come here, you. Come here, you.
Yes. Except we want to change this.
Okay, now let's grab that.
Okay.
There we go. Okay.
Don't have one. Return. Go ahead and make sure that we do.
We always should just put that at the top. Why don't we?
Okay. So, chunk processor. Let's perform a spatial query here.
Um, all right. What do we got here?
That is uh I don't know what the AI thought was going on there.
Was it What do I use here? Int vector.
Cool.
Okay. Now let's also chunk processor uh query.
What do we got here? Entity chunk locations chunks and radius. Ignored entities. I don't think we I don't think we have any ignored entities.
Maybe the self player entity.
Yeah, maybe we ignore that one.
ignore that one. Okay. Out entities now give me the targetable. Oh, right. And we get the the location information is already on there, which is kind of nice.
Okay.
Okay. Let's call this uh entities in radius.
And then I guess we loop over that instead.
entities in radius. Um I guess and then I guess we need to like check if they have I guess I don't use this view at all, do I?
Yeah, we skip it if it doesn't have a name plate source tag.
Okay. Then we would need to like add a new indicator.
So, is this where I'm Excuse me. Is this where I'm constructing the indicators now?
Let me flip over. I would This was previously happening here in blueprints.
Register name plate source, I believe.
Yeah, register name plate source. I need to like convert all this to C++, I believe.
Mhm.
Then I might I might end up just removing them later in the frame. I not later in the frame. Uh later in the function here.
This seems like a lot to do.
if we are potentially for some of them just going to get rid of them.
So this get uh this entity query does this actually check is this a course?
Yeah, this is a course radius. Okay, so there's definitely going to be some in that radius that uh get removed here.
You already have an indicator. Skip it.
Yeah. Yeah. Yeah.
I mean, honestly, yeah, we should just we should probably just do this all at once, honestly.
Mhm. And I think maybe what we do is we just have like a little throwaway here.
Here, let's let's do one of these things here.
F add name plate.
I don't think we need any data on should I sort this?
Yeah, I think this needs to be sorted.
because then yeah, we're going to do the same. We're going to do the same function. Okay, so we're going to actually not use any of that there.
Um, okay.
Okay, that uh is getting considerably simpler.
So, we sort um let's just do a four I here then.
Entities in radius. Um, uh, if I greater than max name plates break. Yeah, because we're not going to add any more.
Um, there's a more efficient way to do that because I'm iterating over every entity here.
And I'm going to need to check their faction, too.
Watch this not even be more performance than the old one.
Oh, I don't think I need that. I think I automatically do that now.
Let's just do it the naive way first here.
Actually, I still think I need to sort the view.
I still think I want that.
Do I still have to get rid of I still have to get rid of any?
Yeah, I think I have to do both actually.
Okay, copy this for a second.
Well, no. What we're going to do is we're going to undo.
We're going to copy that and then we're going to redo everything.
Put that there. Well, no. We want to put that. We want to do that after we've added them.
And so now I want No, here's what we're going to do. We're going to add the add add name plate data and then we're also going to add F indicator name plate indicator data, too. So, we're going to add both of those.
And then at the end of the frame, what we're going to do, ECS registry, clear add uh name plate data. Just get rid of all of them. That's just going to be a temporary thing that we use to know which entities had a name plate added this frame. And then once we've gone through and called all of them, create another view.
Let's call this initialize uh name plates view which is add name plate data which is actually more of a tag. So let's rename that uh add name plate tag name plate indicators data.
Uh and then indicator descriptor is where we will need to you know do some like setup set up initialize or what what am I calling this like spawn indicator.
And I I don't know what uh information that'll need, but it's there when we want it.
Okay. So, let's let me take a look at this then.
Okay. If we already have indicator otherwise.
Um, okay. I think all of that looks I think all of this looks good.
spawn any new indicators. Okay.
And then that way we're not like setting up. The reason we do this first in between setting them up is so we don't have to set them up for for ones that uh are maybe trying to get spawned this frame but are over the max amount or slightly too far and then get uh cold anyway.
Okay.
And then I will need to check faction information here too, I think.
Okay, so now let's figure out what we need to do to spawn these, which there the indicator descriptor is a U object.
And we don't like U objects here. We don't like U objects in my neck of the woods where I come from. So I'm going to have to change that. But I think we're going to stick with the U object for now just to get this working.
Good god, there's so much [ __ ] [ __ ] Dude, I hate translating blueprints into C++.
Like this. This would like this looks like so much in C++. This is going to fit on like one screen. Like it's going to be so much uh cleaner, I guess, is the term.
Streamlined.
Okay, so setup spawn indicator.
So this is going to be U indicator descriptor.
Yeah. Uh yeah, sure. We can parent that doesn't really matter what we parent it to to be honest with you.
So just do that actually.
Uh indicator set class. Uh, and I'm going to need to put something in game mode.
I'll just put it here. Even though it's not a player setting.
Uh, is it just widget? Is it just widget?
Go to Okay, never mind. It doesn't want to go.
Doesn't want to go.
E soft glass pointer you user widget.
Yes, we will use that gameplay. Would you click? Okay. Now, game settings.
pathetic.
Uh, let me copy.
Okay.
Okay, we set the class. Uh, I need to get capsule collision. So, I need the actor that we're like attaching this to, which if we're going to put these over entities, we're no longer going to have that.
So, we're going to have to potentially Yeah, we're going to have to use this component point projection, which let me look at that.
Get pixel point.
Yeah, we'll see how that looks. cuz I may need to adjust things there.
It wants a pointer to an Fector, too.
What a What a weird parameter.
Okay, that seems fine. But yeah, we're going to have to do this here. Uh, now it wants it still wants a scene component. What do we use the scene component for?
It's not even used there.
It's not used here at all.
World location. Yeah. I wonder I I just have the world look. I think I should probably just change this.
God, there's so much [ __ ] information on this thing.
Does it is there a world location on here somewhere already?
I I don't want to just add more information.
No, there's not. Um, so how does the how's the component point supposed to work?
World maybe just world position offset is effectively what uh I mean that is effectively what it is, right? Yeah, cuz we're just going to add that to a zero.
So yeah, let's just we'll just set we need to set uh set world position offset means we need the location entity data.
We'll just we'll just pass in the location in there.
Okay, done and done. And then we want to set the projector mode component point because we don't have a component at all which I don't know what point. Oh, let's change that to absolute location.
I think it's a better better name for that more descriptive. Okay, so we've set all those set data object. Now what do I need that for? Pretel get data object. Where are you called from?
Uh we are sorting in here based on distance which we're no longer going to do in here. That's already That's already done.
Yeah. And this max num to show. We don't need that. I don't even know if we need that anymore.
So by the time we get here, I know that everything should show.
I don't even use this component here either. Do we even need to do that?
Let's just keep adding to-dos here to check cuz I don't want to like just break everything and figure out what I what I broke.
Okay. So, I'm going to assume that we don't need the date. Well, let me look at uh the rest of those that were found here. Owner actor, which is not used.
So, yeah, delete that.
Okay.
Okay. This Yeah. So, it it acts as a way to get information in on the blueprint side of things, which I think I still I still need that for for what is displayed visually. And I'll be able to delete the tick on the on this name plate function, I believe.
Yeah, I guess I'll want to do another view to like update the um like the scale and stuff based on distance.
Okay. So we will set a data object.
do that there.
Auto removing component is null.
Set clamp to screen is out. False.
Scale and opacity. I wasn't actually doing anything with those. That was just for testy tests. Just for testy tests.
Okay. So, that's all set up.
So, theoretically, this would work.
Rebuild. While that rebuilds, I'm going to BRB, grab some more coffee, go to the bathroom.
Hear me.
Heat.
Hey. Hey.
You feel me?
Heat. Heat. N.
Okay.
Hey Heat. Heat.
Okay, we're back.
What broke?
Uh, missing type specifier.
You know what? Do we even need it to be a strct?
Oh, I think we do, actually. I think I think I wrote some Oh, well, okay. We'll see. Okay. So, I need to add this new processor to my my list.
Once this loads up, I always forget to do that.
name plate processor. Yeah, just throw that at the end for counting. Welcome.
Always a good day. Yes, always a good day to refactor.
Okay, so I guess I didn't think about the name plate source. I guess we want to take that off of this. So, we no longer want that to be a name plate source cuz we're going to be adding these ourselves.
There is no chunk processor.
That is a no chunk processor.
Uh we need like is is a processor class. That's what we need. And also Excuse me.
So, we don't have to look this up again.
Okay, rebuild that.
Yeah. So, doing a little bit of rewriting of the Lyra indicators. These are like the little name plates uh with like the health above the above the player, the characters, enemies.
And um I've I've added some functionality to adjust the scale of the name plates and adjust the opacity of the name plates.
And then I noticed that in my extreme cases where I had like a thousand entities all in one location, the Lyra indicators were taking up like 4 milliseconds because I I I did shoehorn in like a a max name plate count.
And so it was spending a lot of time trying to figure out which ones should show, which one which ones shouldn't.
And I was just kind of like I was adding a name plate to any entity that was spawned as a skeletal mesh component.
And so when they were all on top of me, there was like 400 skeletal meshes. And so there were 400 name plates, which is a lot. So ECS to the rescue.
Now, did all that persist?
Okay, it seems it seems so.
Wonderful. There are no There are no name plates.
Perfect. Perfection.
Are we getting here? Yes.
Entities in radius. Yeah, we have a thousand entities in our radius.
Okay. So, this might actually this might actually be worse. This might be worse performance-wise.
This might actually be worse.
Do we ever get here?
No, nothing is uh nothing's being added.
Yeah, I have a feeling this is worse. I mean, let me take a quick sample here.
Sorry, the the crunchy grass is crunching.
Ah, actually that's pretty [ __ ] quick.
That is a lot faster than I thought it would be. Holy [ __ ] Okay, I see you.
So, we're we're iterating over a thousand entities in like 55 microsconds. That's that's a lot better.
Is this writer? Yes.
And then the well I guess yeah the name plate part of it is nowhere to be found because there are no name plates. So okay. So this is going to get once this actually starts working it'll get worse.
But that's a lot better than I thought it was going to be to start off with.
And then let's do some some of these here.
sort indicators or I'll say sort uh registry uh registry entities in radius. This add name plate tags. Sure. That's only ever going to be up to 30, but we still need to iterate and break. Still a little bit of time there potentially.
Trace CPU profiler vins scope call name.
Wow. I haven't even used the word colon here, but I've been using that in my head. Read my mind. AI read my mind.
Bond indicators. Okay.
Yeah. So, what uh what is not getting who's it here?
Let's put a break point there. I want to see that.
And let's put a break point just inside that body. Okay. Live coding.
She for millisecond. Yeah. I mean it was in a very very extreme scenario. So it's I'm I'm kind of hyper hyper optimizing here. But I don't want to have to come back and do this when I don't when I've forgotten how the system works, right? Like I was already in here. I just want to get do this change now and get it over with.
should be should be relatively straightforward. I've only spent an hour on it so far.
Okay. Yeah. So, we're not even hitting this guy here.
What is get Mac? Oh, I need to uh Oh. Oh, yeah. Nothing has the name plate source on it.
Nothing has the name plate source.
Um, I guess for now, for now, let's just let's just add it to Let's just add it here.
Just to kind of get it moving. I should probably put that on the archetype, but I don't feel like going through and updating all of my archetypes right now to include that. And I think I want a better archetype definition asset anyway.
There we go. I think Yeah.
Yeah. Okay, now we're we're getting Now we're getting somewhere.
Okay, now we're spawning. Now we're spawning things. What is this?
Oh, I'm just I'm [ __ ] returning null pointer here. Oops.
Yep, that makes sense. That makes sense.
So, I think this was how far I was able to get it down without doing ECS stuff.
Oops.
Can you stop interrupting me?
So, it's a it's it's this right here.
So, most notably, a lot of it is just like calling to the uh the name plate widget itself to tick, which I will be replacing that as well.
But I guess the I was able to get the update canvas down pretty low.
See, let's pick like a bad frame here.
Most of it is just the I'm like merging skeletal meshes every [ __ ] frame.
Yeah, I should I should do something about that.
Is VS still required for the build if you're using writer? Uh, I think just the tool chain, just the build tools.
So, yeah, we'll see if we can beat 900 milliseconds. I'm going to guess no. I probably shouldn't have closed that.
Hang on.
Is that this one?
Let's see. 1.5 milliseconds there. Yeah.
We'll see if we can get lower than that.
600. Yeah, keep that around.
I have a feeling I'm not going to be able to beat that, which is uh interesting. So, I still have no name plates.
Oh, I need to like actually add this to like the system. Yeah, yeah, yeah, yeah, yeah, yeah. So, let me figure out what uh what do I need to do there?
I need to get the local player. Yeah.
And then add the indicator. Okay, I suppose I need to remove in these cases, too.
All right, then.
>> All right, then. Keep your secrets.
>> So, let me grab the indicator manager component should be on the local player as well.
Uh, Lyra indicator manager component.
Not a subsystem.
my git component.
Oh, it is on the it is on the player controller though, right?
Yeah, it is on the player controller.
Okay. And I guess we also need to remove here And then let's put the local player stuff.
on here.
And I guess maybe the indicator manager would probably make sense as well.
And then that way this we can just do one of these guys here.
Uh, no. We don't want that to be static.
Um, and then yeah, I need the indicator if we have one.
So actually give it the the indicator as well.
Okay.
Also, I don't know if the absolute location actually works.
Okay, rebuild.
Yeah, I'm very skeptical that I'll actually be able to uh I'm skeptical I'll actually be able to beat that performance actually.
But, uh, I think this is going to be necessary anyway because like I said before, it was directly coupled to there being a skeletal mesh.
So, now it's not. Now it's decoupled from that.
So now things that aren't skeleton meshes can have name plates, which if I was going to do that anyway, I would have had to I guess I don't need to run the spatial query every single frame.
Okay, we're still not still not getting them added unless they're just gone. Uh, let me here. Play that again.
I have indicators.
So, I wonder if they're just uh they're in the wrong spot potentially.
The projection is successful. So I think we hopefully we get in there for all of them. Yeah. Okay. Let's look at this.
Then the indicators like opacity is set to one by default, right?
Yeah, opestian scale by default one.
Okay is what we want.
What is our screen space position here?
Okay.
I guess let's try to find them.
Okay, we may need to uh let's decrease the amount of skeletons getting generated every frame here.
Thank you for the sub. Welcome, man.
Welcome.
Guy's freaking out.
H.
Oh, you know what? We're never getting the Oh, no. We're getting that world location. Okay, never mind. Never mind though. That's never like get screen space offset.
Well, we're getting to project world location.
Um, okay. How do I debug this? I guess just a bunch of debug drawings, right, for these locations.
Are there like vector twos and [ __ ] though? Like how do I How do I do? Well, first of all, let's do this. Draw debug sphere.
Oh, I don't even have don't even have a world.
Um, I don't even know if there's anything on here that I can use. There's a data object, right? There's a data object. I can use that to get the world.
Or I can just use like the editor world, right?
Yeah, use that.
Just show me that. Let's just make sure like the world location is correct. I will want to Z offset. That's something I didn't add. I will want to Z offset it by uh the the capsule.
I guess maybe could be screen space offset, although I would like it to be world space.
What are you mad at here?
The G the G editor.
Isn't there like a I use this somewhere, right?
Is that it?
Does that work better? Do you like that?
That what I'm Is that what I'm thinking of G engine world?
Are the indicators uh components of the actors? No. The Lyra system does uh like slate widgets so kind of decoupled from that but more performant because there are no there are no components. Then I'm taking that even a step further with my rewrite of it.
Usually you just add like a name plate source component which is just kind of like a doesn't do anything. It's just there to like add the indicator.
Okay, I'm seeing no debug drawing.
What is your actual like world location here? Is this even the I wonder if You know what? Just to make absolutely sure this is the right world.
Get data object. Get world. Okay, we'll just make sure that that's the right world cuz this uh this Z looks reasonable. Or not Z, this location.
Looks reasonable.
Oh, that's uh that's me. That is uh that's supposed to be skipping me.
I thought I was supposed to be skipped player entity. I don't even I don't even think I'm added as a name plate source.
Am I just using the wrong location here?
No, I mean that should be the uh Yeah, I should be being skipped. Why is it on my head?
Let's let that tick for a second. There we go.
I have the player entity there.
Uh 7341492.
Yeah. So, I'm not even I don't even show up there.
Yeah. Okay. So, the player is never showing up in these in these views.
So, so why then is my I mean, we should be getting here, right? Yeah.
Oh, world location is I mean, the component should be null now.
Oh, you know, we may still be there. We may still be adding one that it that we don't need to.
Yeah, there there is a name plate source on the player.
Okay, delete that.
Delete that. And then let's make this uh let's make this debug drawing a bit bigger so we can find it in the world.
Figure out what the [ __ ] going on here.
50 Okay, there is no longer one over my head. We love that for me. We We love that for me. Okay, are we getting here?
No. No, we are not. Okay, so that explains that.
See, do we spawn one? We do spawn one.
Do we remove it ever?
Sorry, he had to run up the tree there for a second.
Okay, so we didn't remove it.
Okay, we're not even like not even calling this Is there something else I was missing?
Missing doing add indicator.
Well, I mean that's that's it.
Let's see if those get hit. Okay, we're are getting to paint.
It does have an indicator as a child. It is visible content and canvas host are null pointer. There's got to be somewhere where because it doesn't have a component, it's getting like skipped or whatever. Let me check that.
Oh, because it doesn't have a uh Oh, yeah. Let's change that to false then because yeah, if there's no component for it to like attach to.
It is visible if the scene component is valid and be is visible.
Okay. And that's interesting because it was marked as visible. But yeah, that scene component is not valid. So I would expect visible to actually be false there.
Reds and variables.
Okay, I'm just rebuilding. That is taking way too long.
Far too long.
Excuse me.
Am I using Lyra to learn on? No, I just took their indicator system.
just tuning in the contact. Yeah. No, you're free to free to ask questions. Uh no, I just took the the indicators cuz it's a good it's a nice little compact isolated system. I'm just taking that and adapting it to my needs.
Um, are we are we getting to update canvas ever here? Where is the dude at?
Where did Where the [ __ ] did he go?
Okay, there he is.
It's [ __ ] 10:00 a.m. and I've sneezed a 100 times.
I got 99 problems and allergies are about 98 of them, I think. Where's that on paint method?
There it is.
Oh, this is a it's in inactive.
Okay. I did not notice that before.
What is the condition with which we add here?
Oh, we just we just always put it there.
Okay. Put it Put it straight [ __ ] there. Huh?
Add indicator for entry and then we I guess we we remove it.
Ragweed does that. Dude, I'm allergic to trees and grass.
Like what what happened in my ancestors evolutionary line that that didn't get weeded out, you know?
Guard here.
Uh wait, can I?
Yeah. Yeah. Yeah.
I'm in the Midwest.
you you know Unreal Engine source code and they're they're what are you doing?
Got cable everywhere.
Anyway, they're they're they're Unreal Engine devs are like allergic to guard clauses or guard conditions.
Everything is just like super [ __ ] nested and you make it more difficult to read.
Here's another one.
which like does does this ever even return null.
Uh yeah, I guess it could. Okay.
We allowed to early out in UI. Yeah.
contrary to what the source code would have you believe.
Okay, now that this is a bit more readable.
Um, yeah, let's see if we get to that one.
Uh-oh. Who is that?
Megatron.
in.
How's the stream? It's been a minute.
Welcome in, Raiders.
Tell me what you were working on.
Good to
Related Videos
Agentforce NOW AMA: Build with React and Salesforce Multi-Framework
SalesforceDevs
490 views•2026-05-28
How agent o11y differs from traditional o11y — Phil Hetzel, Braintrust
aiDotEngineer
450 views•2026-05-28
WEB TECHNOLOGIES UNIT-2 | Degree 4th sem BCOM Computers web technologies unit-2 full explanation💯✅
LearnwithSahera
1K views•2026-05-29
More tests are always better? How to use AI to identify tests that bring little value
Alliance4Qualification
335 views•2026-05-29
Search Algorithms Explained in 60 Seconds! 🤖💨
samarthtuliofficial
218 views•2026-06-01
People of Game of Thrones using JavaScript DOM
AltCampus
296 views•2026-05-30
Introduction to Problem Solving Part - 1 | Lecture 1 | Intermediate DSA
ascensionix
107 views•2026-05-29
🚀 BCS613C Compiler Design | Module 1 to 5 Schema Evaluation 🔥 | VTU 6th Sem 💯 #VTU #bcs613c #exam
Pranavaa-y4y
104 views•2026-06-02











