How do I make floating combat text (aka floating number over actor)

The concept is very simple. Player Cause Damage to another actor, and player which caused damage can see floating number over damaged actor.

Concept is simple but proved to be much more challenging to me, that I anticipated.

Part I got so far is displaying number over actor, but there are several issues right now:

  1. Numbers can be displayed only over single actor. If I damage another actor everything is teleported to new one. Including damage number which might be going on old actor.

  2. When dealing Radial Damage, damage numbers, are displayed only over last hit actor.

Expected behavior is, that each actor will get their own numbers and they will fallow him.
My last resort here, is to just create billboard component, over which I can draw directly and display it to player.

Any ideas how to best handle it ?

I would probably keep a list of currently active damage text entries. Every frame I would iterate over the list and update their position so that they float up. If a text has been floating for a given amount of time, I would remove it from the list. When new damage occurs, I would add the text to the list. You could also do this using Canvas drawing. Does this help?

Although I did this in BP, I made a CombatText actor (So that it actually has a position in 3d space) with properties like Text, Colour, Scale, ScaleRate, Lifetime, etc, and spawn that when damage occurs.
The actor doesn’t actually render anything, but in my HUD I get all CombatText actors and draw them depending on their properties and position. Works really well.

If you want to display it only over a single Actor, I’d store all of them in the actor like crackpots said.

Thanks, Yeah I had this idea on start, but as I started working on it, the idea was crushed, My main issues here:

  1. All damage is calculated only on server.

  2. Only server know which actors are damaged.

  3. So I would have to prepare list of damaged actors on server, and then replicate it back to client. Then server would have to track it, and remove old actors as they move back on the list, replicate again… you got the idea. To much excessive replication back an forth on something that is cosmetic feature.

I’d rather have just replicated damage, and maybe position of where damage was appiled, and based on that draw it on client.

Although I have been looking at UT sources, and I think there is feature I need implemented

Everything you said makes sense. But I think you’ll still need to keep an active list for cosmetic purposes. Each entry would have the time that damage animation started and the damage value. You’d need to track the time so that you can play some sort of animation (damage text floating up), or at least fade out the the damage values. And you might need a stack of them per actor, in case a lot of damage is done. Still not difficult to write.

You are right. It will be good opportunity to actually clean up my damage code in any case.

Anyway, I looked at UT sources, and there is indeed, almost exactly what I need implemented in using Canvas. I took courtesy of reimplementing it, in my game with some animations and Canvas->Project to display it in world.

Although I would rather do it using Slate, I had almost everything working in Slate, expect part of displaying widget in proper location.
It would be much easier if Slate widgets would directly support something like Canvas->Project/Deproject.

But thanks for setting me on track! (;.

As for question, why you want to do it in Slate. Well:

  1. To learn it :wink:

  2. Because I have everything else in Slate, so I would be more consistent.

Actually, what you are asking for is also doable, and we do this in Fortnite. We make a slate panel that arranged its children relative to actors. So its slot property is an actor and where the widget should appear relative to the actor. However, the math gets a little messy because Slate’s transform hierarchy is wonky. We’re in the process of cleaning up all the transform math, and also adding arbitrary 2D transforms to every widget (it’s going to be pretty neat!) So, I would say that the Canvas approach is going to be cleaner for now. And also it won’t clash with changes we are making for UMG.