GMS 2 Asset Layer Equivalent of depth=-y

DarthTenebris

Definitely not a Sith Lord
Hello everybody,

Title says it all, is there an equivalent to an object's depth=-y for asset layers? I'm making a 2.5d-ish game, and sometimes I'd like to let the player walk behind objects, however the asset layers are screwing this up.

Thank you for your time.
 

Binsk

Member
Sort the render order yourself. I think that's all we've got.

You should technically be able to still do the depth=-y trick, its just less efficient now.
 

NightFrost

Member
Yes the depth = -y should still work without problem. It just causes extra work for GMS as under the hood it will generate and destroy (as necessary) anonymous layers to hold the instances. One solution presented here was to programmatically generate a large number of layers and have the instances assign themselves to them according to their desired z-depth. It was, according to the post, a very fast method. (Can't find it right now, I thought I had it bookmarked.)
 

chamaeleon

Member
Yes the depth = -y should still work without problem. It just causes extra work for GMS as under the hood it will generate and destroy (as necessary) anonymous layers to hold the instances. One solution presented here was to programmatically generate a large number of layers and have the instances assign themselves to them according to their desired z-depth. It was, according to the post, a very fast method. (Can't find it right now, I thought I had it bookmarked.)
You're probably thinking of the system mentioned in https://forum.yoyogames.com/index.p...d-for-gms2-objects-sprites.42868/#post-398498.
 

DarthTenebris

Definitely not a Sith Lord
Sort the render order yourself. I think that's all we've got.

You should technically be able to still do the depth=-y trick, its just less efficient now.
How would I go about doing that? I can't seem to find a way to address assets on an asset layer.
Yes the depth = -y should still work without problem. It just causes extra work for GMS as under the hood it will generate and destroy (as necessary) anonymous layers to hold the instances. One solution presented here was to programmatically generate a large number of layers and have the instances assign themselves to them according to their desired z-depth. It was, according to the post, a very fast method. (Can't find it right now, I thought I had it bookmarked.)
So I just have to generate all the layers myself:
Code:
for(var i = 0;  i < room_depth; i++) {
     layer[i] = layer_create();
     layer_depth(layer[i], i);
}
Like this?

Thank you for your time.
 
Last edited:

rIKmAN

Member
How would I go about doing that? I can't seem to find a way to address assets on an asset layer.
This came up in another thread last week, the tutorial links I posted there will be helpful to you if you want to manually sort and manage depth yourself using layers.
https://forum.yoyogames.com/index.p...oved-over-to-gm2-yet.38689/page-7#post-416394

However unless you are using a massive number of instances then just using depth = -y as you did in 1.4 and letting GMS2 manage the layers itself will work fine and you won't notice any performance issues - it's very likely that other areas of your game will be the cause slowdown before this became the main thing that needed optimising.
 

DarthTenebris

Definitely not a Sith Lord
This came up in another thread last week, the tutorial links I posted there will be helpful to you if you want to manually sort and manage depth yourself using layers.
https://forum.yoyogames.com/index.p...oved-over-to-gm2-yet.38689/page-7#post-416394

However unless you are using a massive number of instances then just using depth = -y as you did in 1.4 and letting GMS2 manage the layers itself will work fine and you won't notice any performance issues - it's very likely that other areas of your game will be the cause slowdown before this became the main thing that needed optimising.
Yes that's what I'm trying to do. The problem is that sometimes I'd like to have my character be able to walk behind something, and while the collision works, the sprite doesn't - the sprites are drawn incorrectly. My objects only serve as collision boxes, aside from the player, all the graphics are done on an asset layer. If I remember correctly tiles can be addressed individually by code and have their depths set according to their y value, however the reason I switched over to asset layers is I read they have a more versatile animation department, being able to handle variable animation speeds whereas a tile layer can only have a constant animation speed for that entire layer. So my main question I guess is: how can I address every asset on an asset layer and set their depths according to their y value?

Thank you for your time.
 
Last edited:

rIKmAN

Member
Yes that's what I'm trying to do. The problem is that sometimes I'd like to have my character be able to walk behind something, and while the collision works, the sprite doesn't - the sprites are drawn incorrectly. My objects only serve as collision boxes, aside from the player, all the graphics are done on an asset layer. If I remember correctly tiles can be addressed individually by code and have their depths set according to their y value, however the reason I switched over to asset layers is I read they have a more versatile animation department, being able to handle variable animation speeds whereas a tile layer can only have a constant animation speed for that entire layer. So my main question I guess is: how can I address every asset on an asset layer and set their depths according to their y value?
Individual tiles cannot have depth, and neither can sprites on an asset layer - they have the depth of the layer they are on.

To use the typical depth = -y system you would use instances for the objects that need to have depth (ie. can be walked in front of / behind) with static objects (ie. things that never move like walls, fences, tables) having their depth set to -y in the Create Event and dynamic objects (ie. things that move around like characters) having it updated in a Step Event so it changes as it moves within the game.

Remember you do not have to use one system or another, you can mix and use them all as needed - I use a mix of tiles, sprites and instances with depth = -y as needed and it works fine with characters walking behind walls, tables and any other object I decide needs to be a part of the depth system and be able to be walked in front of / behind.

It sounds like you are overcomplicating things - is there a reason you can't just use the Draw Event of the instances to draw the associated sprite?
Thank you for your tie.
Leave my tie out of this, I only wear it once a year at Xmas.
 

DarthTenebris

Definitely not a Sith Lord
It sounds like you are overcomplicating things - is there a reason you can't just use the Draw Event of the instances to draw the associated sprite?
The game is a 2.5D-ish, top down perspective. The collision objects are smaller than the sprites. Sometimes the objects are stretched manually in the room editor to cover spaces that don't play nicely with the size of my collision objects. I only have 1 collision object, making them draw the graphics of the room is going to be hard. Either I set every single one of them to draw the correct sprite, or I basically rewrite autotile but in GML. Either way, not very fun. Can stretched objects still draw sprites correctly, unaffected? Do I get to keep my current setup of only using 1 collision object instead of multiple objects with different sprites?

Leave my tie out of this, I only wear it once a year at Xmas.
Thank you for your time.
 

rIKmAN

Member
The game is a 2.5D-ish, top down perspective.
Yep, same as the typical RPG viewpoint which is the same as the project I use this system in.
I only have 1 collision object, making them draw the graphics of the room is going to be hard.
I'm not sure what you mean, why would your collision object be responsible for drawing the graphics for everything in the room?
Can stretched objects still draw sprites correctly, unaffected?
I'm confused at the question - if you want it drawn normally why would you stretch it in the first place?
You can manually draw sprites using draw_sprite_ext() and pass in a value of 1 for xscale and yscale, but that will introduce a difference between what you see in the Room Editor and what you see in the game - and why not just have them at that scale to start with?
Do I get to keep my current setup of only using 1 collision object instead of multiple objects with different sprites?
I use tile based collision in my project, but having a single collision object has no relation to the sprites displayed by other instances.
It sounds like it does it your case because you have the collison object responsible for drawing everything else, which doesn't seem like a good way to do things.

Maybe I've misunderstood, and if so then it would be good if you could provide more info on your setup and maybe some screenshots (use spoiler tags please).[/QUOTE]
 

DarthTenebris

Definitely not a Sith Lord
I'm not sure what you mean, why would your collision object be responsible for drawing the graphics for everything in the room?
Sorry, I didn't mean the solid objects were to draw the entire room, just their part. The solid objects make up the walls, and occasionally stuff. The floor doesn't exist as an object, it can probably stay on the asset layer.
I'm not sure what you mean
I only have 1 wall object, however not all of the walls have the same sprite. I didn't mean for the wall to draw the entire room.
I'm confused at the question
The solid objects are squares, but sometimes they leave gaps that can't be perfectly filled by another square. Therefore, I stretch the previous square into a rectangle. This probably causes the origin to shift, and might mess up drawing the sprite.
maybe some screenshots
That's probably easier.
Grids are 16x16.

Room editor, asset layer:
upload_2019-12-22_21-49-25.png
Room editor, instance layer:
upload_2019-12-22_21-53-31.png

Thank you for your time.
 

rIKmAN

Member
If you already have a grid and are working to one - why not just use tiles?

Using tile layers for this is what they are designed for and although collision is a little more difficult to setup initially, once you have done it you can literally forget about it and just worry about what should happen when the player collides with a particular type of tile.

If those wall sprites in the screenshots are actually instances then you aren't even using the old 1.4 trick of stretching the walls to cover more distance to reduce instance count.
Is this what you were trying to say earlier when you were mentioning stretching?

In general the wall instances in the in 1.4 method you are trying to use are used just for collision checking and placed where you want to collision to be over any solid object.
They aren't meant to manage drawing the correct sprite for each object they are providing collision for.

I just knocked up a quick example using sprites cut from your images.
It uses tiles / tile layer for collisions but the bed and the chest are actually instances with depth = -y in their Create Event as they would be static objects as I explained earlier.

When you add a character to move around, with depth = -y in the Step Event (because it moves around and needs updating each frame), it looks like this:


I resized your images, but the tile layer used for collision looks like this:


Notice how the top part of each instances sprite is not covered - this is so that the character (with the origin between his feet) can "walk behind" them - as if the entire object was solid the feet would hit the top of the sprite and stop, making him unable to go behind it which is the effect you want to try and give it a bit of depth.

This is a basic example, but honestly from what I've understood from your messages, it sounds like you are really overcomplicating things and trying to work around issues that don't really exist if you used the tools provided to you to do the correct job they were intended for.
 

DarthTenebris

Definitely not a Sith Lord
Well ok, so if I were to keep my setup, but switch back to tiles, how would it go? Can I create a layer (layer_create() followed by layer_tilemap_create()) for every depth from 0 to -room_height and move individual tiles to their required depths? I read the manual trying to find how to address individual tiles on the default tile layer and move it to a different layer at a different depth, however I don't seem to be able to understand how to address those individual tiles in the first place.

Thank you for your time.
 

rIKmAN

Member
Well ok, so if I were to keep my setup, but switch back to tiles, how would it go? Can I create a layer (layer_create() followed by layer_tilemap_create()) for every depth from 0 to -room_height and move individual tiles to their required depths? I read the manual trying to find how to address individual tiles on the default tile layer and move it to a different layer at a different depth, however I don't seem to be able to understand how to address those individual tiles in the first place.

Thank you for your time.
I didn't mention creating a tile layer for every y-position anywhere in my post, manual depth sorting isn't needed for such a simple setup and you wouldn't normally do it with tile layers anyway but with instances that move and have their depth updated in a Step Event each frame.

If you re-read my post I used a single tile layer for collision (the red tiles) and the objects you want to walk behind are instances using depth = -y set in their Create Event (as they are static and won't be moving). You don't need anything more complex than that.

If you want to have tile layers that you walk behind as well (walls for example) then add them on a tile layer and manually set the depth of the layer at the start of the game to a value that will always be above the player (who's depth will change to between 0 and -room_height as he moves around).

You cannot "move" tiles between tile layers, you would remove the tile from one layer and then add a tile to another, but this would require the layers to have the same tileset which wouldn't make any sense in this case.

To find the tile at an x/y position within a room you can use tilemap_get_at_pixel(), to retrieve the cell at an x/y position within the room you would use tilemap_get_cell_x_at_pixel() and tilemap_get_cell_y_at_pixel().

It seems you are familiar with using 1.4 and the depth = -y method so use it here as well.
Just because GMS2 has layers doesn't mean that you need to find a workaround, it still works just fine it's just a little slower (you won't notice this) and you have to think a little about other layers and set their depth manually (ie. the walls on a layer set to always be above the player as I mentioned above).


Again, I think you are thinking too hard about this and overcomplicating things to try and solve issues that you don't yet have and likely won't encounter with such a simple setup.

Have a play around in the IDE with the setup I mentioned and I think you'll find it easier to grasp than reading my text descriptions as it sounds much more complicated than it is when written down.
 
Last edited:

DarthTenebris

Definitely not a Sith Lord
If you already have a grid and are working to one - why not just use tiles?

Using tile layers for this is what they are designed for and although collision is a little more difficult to setup initially, once you have done it you can literally forget about it and just worry about what should happen when the player collides with a particular type of tile.

If those wall sprites in the screenshots are actually instances then you aren't even using the old 1.4 trick of stretching the walls to cover more distance to reduce instance count.
Is this what you were trying to say earlier when you were mentioning stretching?

In general the wall instances in the in 1.4 method you are trying to use are used just for collision checking and placed where you want to collision to be over any solid object.
They aren't meant to manage drawing the correct sprite for each object they are providing collision for.

I just knocked up a quick example using sprites cut from your images.
It uses tiles / tile layer for collisions but the bed and the chest are actually instances with depth = -y in their Create Event as they would be static objects as I explained earlier.

When you add a character to move around, with depth = -y in the Step Event (because it moves around and needs updating each frame), it looks like this:


I resized your images, but the tile layer used for collision looks like this:


Notice how the top part of each instances sprite is not covered - this is so that the character (with the origin between his feet) can "walk behind" them - as if the entire object was solid the feet would hit the top of the sprite and stop, making him unable to go behind it which is the effect you want to try and give it a bit of depth.

This is a basic example, but honestly from what I've understood from your messages, it sounds like you are really overcomplicating things and trying to work around issues that don't really exist if you used the tools provided to you to do the correct job they were intended for.
Mind sending me a copy of that project? Perhaps taking a look at it for myself can help.

Thank you for your time.
 

rIKmAN

Member
Mind sending me a copy of that project? Perhaps taking a look at it for myself can help.

Thank you for your time.
You’re a day too late, I’m away from home til the New Year now and don’t have access to my machine.

However it’s not difficult to reproduce:

1) Create a player object, add a sprite, add movement control with keys or mouse and add depth = -y to its Step Event.

2) Creat some static objects that you want to be able to walk behind and in front of.
Add sprites and put depth = -y in their Create Events

3) Add them all to an Instance Layer in the room, move the character and see that it can go behind and in front of objects as it moves.

4) Add a tile layer, paint in some floor tiles.

5) Add another tile layer, paint in some wall tiles

6) In the Create Event of a new controller object (or the player object for now just to test) use layer_set_depth() to set the depths of the tile layers so that the player walks on the floor tiles and goes behind the wall tiles.

That’s literally it, just extrapolate out from that once you have your head around it, add a tile collision layer and you have everything you need to make the base of your game.
 
Last edited:
Top