• Hello [name]! Thanks for joining the GMC. Before making any posts in the Tech Support forum, can we suggest you read the forum rules? These are simple guidelines that we ask you to follow so that you can get the best help possible for your issue.

Question - Code How to draw a sprite-track-only Sequence (no objects) to the GUI layer ?

Hello.

I have a HUD object already drawing sprites through its Draw Gui event, to display my, well, game's HUD.
Nothing fancy codewise, it just get some values from the player object and display them. (Ok. I have a carrousel animation effect in gml triggered at update, but whatever)

What I want to do is :

1. Using some of those sprite in a Sequence asset I'll use under some conditions (like no energy, etc)
2. Swaping the sprites with the Sequence, I then stop drawing them individually and draw the Sequence instead.
3. Once the Sequence ends, I go back to draw those sprites.

The issue is I use the GUI layer to draw the HUD and sadly, setting the position of an Sequence instance is done at its creation with layer_sequence_create() and then can be moved with sequence_x and sequence_y, but those are relative to the room coordinate.

The two easiest workaround I can think of are also the ones I would like to avoid :
  • Create an object for each sprite I want to use in my Sequence in order to use their own Draw Gui event. Thing is it's overkill in my case because I don't need all the feature of an Object Assets (varaibles, events and Co) and that's nullify the point of just using sprite for a basic HUD.
  • Update the position of the sequence in the room relative to my camera view like good'ol day GM8 which nullify the use of having a Draw Gui event and, actually, is just plainly disappointing and boring to do XD
So is there another workaround or an incoming feature addition to the Sequence feature which will adress that ?
Any ideas ?
 
Last edited:

Ulysse

Member
I have the same situation. Sequences made of sprites that should display as part of the UI. And I can't use any of those two work-arounds:
- I am modifying the sprites at runtime, and you can't do the same with objects (you can't access the objects to change their sprites).
- I need the sequence to be on top of some other GUI elements, so even if I modify the position, it won't display correctly.

I had a look around but can't find any solution there short of basically redoing your own sequence system.
Sounds like a feature request...
 

Ulysse

Member
Thank you very much Shut for redirecting me there. It works almost perfectly.

The only issue is that drawing to a surface is not the same as drawing directly to the application surface. The intermediary surface needs to be cleared to transparent, and that means you are blending into transparent once before blending into the application surface.
I've toyed a bit around with the blend modes, and came up with the following setup in the Create event of my UI controller:
GML:
memb_animationSurface = -1;
layer_script_begin(layer_get_id("Animations"),method(self, function(){
    if (event_type == ev_draw)
    {
        if (event_number == 0)
        {
            // create surface
            if !surface_exists(memb_animationSurface) memb_animationSurface = surface_create(RESOLUTION_WIDTH, RESOLUTION_HEIGHT);
        
            // set target
            surface_set_target(memb_animationSurface);
            draw_clear_alpha(c_black, 0);
            var bm = gpu_get_blendmode_ext_sepalpha();
            bm[2] = bm_one;
            gpu_set_blendmode_ext_sepalpha(bm);
        }
    }
}))

layer_script_end(layer_get_id("Animations"),method(self, function(){
    if (event_type == ev_draw)
    {
        if (event_number == 0)
        {
            surface_reset_target();
            gpu_set_blendmode(bm_normal);
        }
    }
}))
(Not shown: freeing the surface in the Clean Up event of the object.)

It really only works because I don't have that much overlapping half-transparent effect. When I start having those, the result is not exactly as expected.

I feel the only solution would be to tell the GPU to have a different blending based on whether the pixel was already written to. If it wasn't written too, ignore the destination value and just write the source value. It is was already written to, do normal blending. I guess that would remove the influence of the intermediate surface, but I don't think GMS have this kind of handling for user-created surfaces.

Anyway, that's at least a decent work-around and I can proceed. Thanks again.
 
Top