• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Recycling Units - Is this even worth it? (Lua)

Status
Not open for further replies.

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,538
Hey guys, I wanted to implement a unit recycling system into my map and I'm not sure if this is even worth it in terms of performance. So the basic idea is this:

All of my units have a hidden Reincarnation ability. This ability has a 0 second cooldown/delay/cast time so when a unit dies it is instantly reincarnated.

Then I use the "undefend" trick to detect when a unit dies (since it has reincarnation it technically never "dies") and run the code below. This code hides the dying unit, creates a Special Effect of the dying unit on it's position, and plays the special effect's death animation before fading away a few seconds later. Because of this I can get around having to use "CreateUnit" and instead re-use my "dead" units.
  • Unit Death
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Issued order) Equal to (Order(undefend))
    • Actions
      • Custom script: UnitDeath()
Lua:
function UnitDeath()
    print("death")
    local u = GetTriggerUnit()
    local p = GetPlayerId(GetTriggerPlayer())
    local x1 = GetUnitX(u)
    local y1 = GetUnitY(u)
    local facing = GetUnitFacing(u)
    local yaw = Deg2Rad(facing)
    local alp = 255 --This is the alpha used later on to make the corpse fade away

    --Create a "death animation" special effect
    local sfx = AddSpecialEffect('units\\human\\Footman\\Footman.mdl', x1, y1)
    BlzSetSpecialEffectYaw(sfx, yaw)
    BlzSetSpecialEffectScale(sfx, 0.95)
    BlzSetSpecialEffectColorByPlayer(sfx, Player(p))
    BlzPlaySpecialEffect(sfx, ANIM_TYPE_DEATH)

    --Hide the dying unit and add it to the recycling system (Haven't implemented one yet)
    ShowUnit(u, false)

    --After 5.00 seconds the corpse (special effect) begins to fade away before being destroyed
    TimerStart(CreateTimer(), 5.00, false, function()
        PauseTimer(GetExpiredTimer())
        DestroyTimer(GetExpiredTimer())
        TimerStart(CreateTimer(), 0.05, true, function()
            alp = alp - 12
            BlzSetSpecialEffectAlpha(sfx, alp)
            if alp <= 0 then
                BlzSetSpecialEffectPosition(sfx, game_Bounds, game_Bounds, -500)
                DestroyEffect(sfx)
                PauseTimer(GetExpiredTimer())
                DestroyTimer(GetExpiredTimer())
            end
        end)
    end)
end

So this actually works pretty great, at least for a Footman. The footman dies, revives, and is hidden all at once. Visually it looks like a normal death animation and thanks to this setup I can re-use the hidden Footman immediately. There's no decay/corpse but I could add that in if I wanted.

Anyway, the sole reason for doing this is to avoid having to create a new unit. And the question is, is it even worth going through all of the trouble to do so? I heard that recycling units can improve map performance but I'm not sure if it's true or worth it. The amount of units being created/dying in my map will be similar to maps like Footmen Frenzy.

Edit: I'm currently facing a weird bug. The code is repeating twice even though I'm only detecting one order of "undefend" when a unit dies. I'm doing this in the Reforged Editor so maybe that's the issue.
 
Last edited:
Status
Not open for further replies.
Top