GameMaker Auto-Depth System

Fixer90

Member
To start off, I have an object called settings which is a persistent object that is there at the very start of the game. Is there a way I could set it up to automatically and constantly update every object's depth, such that objects that are lower in a room have a slightly lower depth, making them above objects of their own depth if they are lower in the room? Doing this to each individual object looks something like this:
Code:
depth = [whatever the depth is] - clamp((y / room_height), 0, 0.9999);
EDIT: My guess is that it would have something to do with adding code in a Step or End Step event in setting's code, but I'm not sure how I would implement it.
 
Last edited:
In my experience you will face issues with this method if you are using the built in depth variable in GMS 2

Assigning a value to the depth variable will put the object on a managed layer ( not one assigned to the room by yourself ). As layers have integer depth values, the number you are assigning in the formula above will be rounded to the nearest integer value, and you will end up with instances still occupying the same layer, even though you've given them slightly different depth values.

As they are on the same layer, they will not be rendered in a guaranteed order that you want.

You would need to use your own custom depth variable, and then render the instances yourself from back to front in order to achieve what you want.

I have a parent object for all rendered instances, and I use:

End Step Event:

Code:
with ( parent_object )
{
    // [ Add all objects to a sorted ds_list based on their custom depth value ]
}
Then in the Draw Event, I draw all the objects in the list in order.

You could use the code you listed above, but also bear in mind if you are constantly shifting the depth value every End Step, you will be shifting all the instances depths by a small amount every frame.

There is a good discussion about depth sorting in GMS 2 here:

https://forum.yoyogames.com/index.p...rity-list-nested-list-grid-binary-list.13425/

All my instances have a variable called z_3D, which is their custom depth.

The code I use in my persistent object for managing this is :

// End Step Event
Code:
with ( o3D ) // All instances with depth have the object o3D as their parent.
{
    var _sort_depth = id | z_3D
    ds_list_add(o3DCamera.draw_list, _sort_depth)
}

ds_list_sort(draw_list, false);
Then in the Draw Event:
Code:
var _list_size = ds_list_size(draw_list)

for ( var i = 0; i < _list_size; ++i )
{
    var oID = draw_list[| i] & $ffffffff;
   
    with ( oID )
    {
        event_user(0)   // Objects draw code is contained in user event 0
    }
}
 

Fixer90

Member
I'll definitely look into that Indiana, thank you!

Though I do have another idea — and tell me if this would work: I could make the settings object, in the End Step event, do as I previously said, but it would first multiply all of the depths of my objects by 1,000 or 10,000 perhaps, then adjust their depths by 1 based on their position instead of by a decimal.
 

vdweller

Member
I am using the legacy depth variable in an imported from 1.4 zelda-esque game which is the very definition of having lots of instances with different depths. In earlier versions of GMS2 there were some issues like flickering but I guarantee that everything runs ok now. If this system works with a game like that, I really don't see the problem using it. Just use also layer_force_draw_depth and you'll be ok.
 
I'll definitely look into that Indiana, thank you!

Though I do have another idea — and tell me if this would work: I could make the settings object, in the End Step event, do as I previously said, but it would first multiply all of the depths of my objects by 1,000 or 10,000 perhaps, then adjust their depths by 1 based on their position instead of by a decimal.
Yep, no harm in trying that to see if it works for you. As @vdweller said, you'll probably have to use layer_force_draw_depth(), as GMS 2 only draws layers from -16000 to 16000. If you are multiplying by 10000, you may find you have instances outside of that range. Forcing the draw depth ensures that all instances get drawn, regardless of what layer they are on.
 
Top