• 🏆 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!

Making special effect blend from animation a to b.

Level 14
Joined
Jan 16, 2009
Messages
716
When using special effects I noticed something interesting.
In my bare bone project, my special effect would not blend when changing animation.
For instance if the model was standing and I issued it to play a walk animation, it would instantly switch to the walk animation without blending from its current skeleton to the walk animation skeleton.
However in other bigger projects it would blend just fine.

I managed to find a reliable way to "activate" blending for special effects.
You simply need to have created a unit with the same model as the one you want to use before creating a single special effect of that model.
If you create a special effect with the model before the unit, the special effects seems to never blend.
Funny thing is that this will also make the unit's model not do any blending between animations - though that something you could achieve by lowering the blend time field to 0 I believe.

I was wondering if anyone knew of a better way to activate blending for special effects?
That is, a better way than having to create a unit type for each model that wants animation blending when used as a special effect.

Here is some demo code and a demo map.
JASS:
// Globals requires enabling Jasshelper.
globals
    boolean        do_blending        = false
    //
    integer        my_model_count     = 0
    effect   array my_models
    animtype array my_model_animtypes
endglobals


function do_periodically takes nothing returns nothing
    local integer i = 0
    loop
    exitwhen i == my_model_count
        if my_model_animtypes[i] != ANIM_TYPE_WALK then
            call BlzPlaySpecialEffect(my_models[i], ANIM_TYPE_WALK)
            set my_model_animtypes[i] = ANIM_TYPE_WALK
        else
            call BlzPlaySpecialEffect(my_models[i], ANIM_TYPE_STAND)
            set my_model_animtypes[i] = ANIM_TYPE_STAND
        endif
    set i = i + 1
    endloop
endfunction

function do_test takes real x, real y returns nothing
    set my_models[my_model_count] = AddSpecialEffect("Units\\Human\\ArthaswithSword\\ArthaswithSword.mdx", x, y)
    set my_model_animtypes[my_model_count] = ANIM_TYPE_WALK
    call BlzPlaySpecialEffect(my_models[my_model_count], ANIM_TYPE_WALK)
    call BlzSetSpecialEffectColorByPlayer(my_models[my_model_count], Player(my_model_count))
    set my_model_count = my_model_count + 1
endfunction

function initialize_demo takes nothing returns nothing
    call CreateUnit(Player(0), 'hfoo', 0, 0, 0) // A footman for vision.
    if do_blending then
        // This will create Arthas with Frostmourne.
        call CreateUnit(Player(0), 1214345830, 128, 0, 0)
    endif
    call do_test(0, 0)
    call CreateUnit(Player(0), 1214345830, -128, 0, 0) // This will not make the second model blend if `do_blending` was false.
    call do_test(0, 256)
    call TimerStart(CreateTimer(), 0.5, true, function do_periodically)
endfunction

function InitTrig_Untitled_Trigger_001 takes nothing returns nothing
    set gg_trg_Untitled_Trigger_001 = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Untitled_Trigger_001, function initialize_demo )
endfunction
 

Attachments

  • model_blending_demo.w3m
    17.6 KB · Views: 2
Last edited:
Level 14
Joined
Jan 16, 2009
Messages
716
Another experiment, if you're on Reforged, is to use the BlzSetUnitModel API, hopefully achieving the same effect without having to create a bunch of native unit models in Object Editor/Object Merger
I don't think there is a BlzSetUnitModel(). However there is a BlzSetUnitSkin() but that takes the id of another existing unit type so you still have to create an unit type.
 
Level 14
Joined
Jan 16, 2009
Messages
716
I tried ITEM_SF_MODEL_USED and ConvertUnitStringField('umdl') but they don't seem to affect the item or the unit, which is consistent with my memories of it. I guess that field is just not read after the widget has been created. Maybe there is a way to trigger a "refresh" but I kinda doubt it.

UNIT_SF_SHADOW_IMAGE_UNIT didn't do anything either.
 
Top