Depth Problem With Z Axis [SOLVED]

Z

Zephyr Schwarzwolf

Guest
Hi everyone !

I'm still struggling with my depth system for my top-down game in "fake" 3D.
So, here's the situation :
I set a z axis for "height" and created several collisions objects for my different levels. (My levels are based on a 32 pix height per "z unity")
My depth system's like depth = - y - (z*room_height).

You may ask "Why z*room_height" ?
When my playable object is not jumping, (only moving on x and y axis), things work pretty well. It's a simple "depth = - y".
When it jumps on a platform which is set at (z + 1 for example. 32 pix higher) lowers objects on z axis are drawn behind it. WHATEVER HAPPENS !
I know that depth system is not perfect at all, but I couldn't find a better one...

So. here's my problem :
For an object, the depth is set on the origin. Imagine a cube (32*32*32) : When my Player object is in front of this cube, there is no problem. When it jumps over it, there is no problem. When it stand behind it, there is no problem... BUT if it jumps while it stands behind the bloc, it will be drawn over the bloc before its feet reached the top of the bloc.

How could that be possible ? That's because my y_scale is not the same than my z_scale... When my player jumps then gains 32 pix in y, it gains only one unity on the z axis... That's because of that *%*$^p depth limit. With my depth system, each z unity costs a "room_height" in depth... For a 800 height room, I can ONLY set 20 levels. Imagine if I had set my z_scale on the same as y... That couldn't be possible.

If you know what can solve my problem or if you know a different depth system that could be mine, it could be sooo precious.
I've already watched for this : https://www.yoyogames.com/blog/458/z-tilting-shader-based-2-5d-depth-sorting
It could be great, but I have some troubles with the method. (Ok, excepted the shader himself, I have NO idea of how I could use it).

Thank ya in advance !
 
Z

Zephyr Schwarzwolf

Guest
Hi TheouAegis !
What about z depth ? I just tried that code. When I jump, whatever the level, all objects with a z value > 0 are drawn in front of my main object...
May I change something else to make it work ? By the way, I'm not sure to fully understand how that code is supposed to work. Could ya explain me shortly ?
Thank you.
 

johnwo

Member
I think that what he means is to set depth=-y; in the a step event, then in the draw function use:
Code:
y-=z;
draw_self();
y+=z;
However, in that context, I'm not sure what z would be referring to.

Further information such as: Is it viewed isometrically, how do you draw the cube, e.g. would help.
 
Z

Zephyr Schwarzwolf

Guest
Hi ! I understood what he means. The code seems to be the problem because it doesn't affect depth for z...
To answer your question, that's not an isometric view. The depth system I'm seeking for is the same than in Alundra PS1 :
I still wonder how they managed to do that... :D
I found an asset here : https://marketplace.yoyogames.com/assets/2422/top-down-depth-engine
My account is a free account, I won't be able to purchase it. (Moreover, that's not for GMS2. I don't know if the code and functions are exactly the same) But that's what I want to do.
The system appears so natural that it seems almost easy to do. I feel like I coded a complicated and limited system for nothing...
 
A

Alan Chan

Guest
Hi @Zephyr Schwarzwolf , I think you should not use the Z Tilting shader from this link unless you are very good at a confusing 2.5 visual effect math. Even though I am not very that good at a confusing 2.5 visual effect math.
https://www.yoyogames.com/blog/458/z-tilting-shader-based-2-5d-depth-sorting

I rather suggest you to use the only one z variable depth from this link.
https://docs2.yoyogames.com/source/...instance_functions/instance_create_depth.html

@TheouAegis , you forgot that you will need to store a number variable value inside the z variable, all else it will reads nothing at all.
You could just use depth=-y and in the draw event have

y-=z;
draw_self();
y+=z;
You should put your object0 with this Draw event code.
Code:
z = -1;
instance_create_depth(x, y, z, object0);
draw_self();
Then, you should put your object1 with this Draw event code.
Code:
z = 0;
instance_create_depth(x, y, z, object1);
draw_self();
Then, you will see your object0 is always behind your object1 because of your different stored z variables.
 

TheouAegis

Member
z, height, z_depth, whatever he wants to call it.

The lowest point on an instance is either bbox_bottom or y+sprite_height-sprite_yoffset, or some variation depending on how you set your sprite up (but typically those values). No matter what height/z an instance is at, the depth of the lowest point of an instance should never change, so you should set depth based on that value ideally. If bbox_bottom is 128, depth would be -128. Even if you had a z/height value of 10 which would result in bbox_bottom being DRAWN at 118 (128-10), the depth never changes because the bbox_bottom value should never change -- it stays at 128 physically.

That was basically the gist of what my unexplained snippet of code was about. You apply the height variable to the y-coordinate, draw the Sprite, then remove the height variable from the y coordinate. Or you can use draw_sprite_ext() and do everything in one line.
 
Z

Zephyr Schwarzwolf

Guest
Then, you will see your object0 is always behind your object1 because of your different stored z variables.
Hi Alan Chan !
I don't want my main object to be behind or in front of a layer. On the contrary, I want it to navigate through layers !
@TheouAegis I'm not sure to understand what you mean... If my depth is always constant, that means everything is "flat" and it's pure 2D, not fake 3D, right ?
What I call "z" is not my "depth". It's another axis mingled to the "y" axis (That's why I call it fake 3D). I need to handle my depth in function of these two axis (y and z).
Can someone explain me how they did that in Alundra or in the asset ? I'm lost... My system works, but I feel limited by the functions GMS2 proposes...
Thank you in advance.
 
A

Alan Chan

Guest
Hi @Zephyr Schwarzwolf , then you can set all of the instance_create_depth( x, y, 0, any_object_name ); with all of the z into an all 0 z depth object. Or do not use any instance_create_depth() codes at all, if you do not know how to create a 2.5D visual effects with their own special 2.5D math. But, most likely you will need to use the instance_create_depth() codes if in case you have overlapped the multiple other 2D objects inside your same room areas.
Hi Alan Chan !
I don't want my main object to be behind or in front of a layer. On the contrary, I want it to navigate through layers !
@TheouAegis I'm not sure to understand what you mean... If my depth is always constant, that means everything is "flat" and it's pure 2D, not fake 3D, right ?
What I call "z" is not my "depth". It's another axis mingled to the "y" axis (That's why I call it fake 3D). I need to handle my depth in function of these two axis (y and z).
Can someone explain me how they did that in Alundra or in the asset ? I'm lost... My system works, but I feel limited by the functions GMS2 proposes...
Thank you in advance.
 

TheouAegis

Member
I'm saying don't use depth to base the third dimension on. Make a third dimension under the hood. Your game is still running into Dimensions, you are just applying an effect of 3D.

Alundra didn't use Game Maker, so if you want to think outside Game Maker terms, that might help.
 

NightFrost

Member
Maybe you should give the z-tilting another go? I've tested it out and it seems a pretty good solution. The basic idea goes like this: consider each height level of your map as a cutout, hovering above previous layer by amount of your grid size. Imagine them as paper cutouts if you will, hovering on your table and viewed directly from above. Entities that move around the map have the bottoms of their sprites rooted on the layer they're walking on, but their tops are tilted upwards on z-axis by 45 degrees. This tilt actually stretches them vertically too, so that the y-location of their top does not change. However since you're looking at them directly from above, you cannot notice this stretch. When a z-tilted entity walks in front of a wall, since the top of their sprite is on higher z-axis position that the wall top's depth, it will appear in front of the tiles instead of being obscured by them. Similarily, when a z-tilted entity walks behind a wall, their bottom is still on their normal elevation and will be obscured by the top of the wall that is at higher depth. The GPU takes care of all the related fiddling and logic.

Attached image might explain this little more clearly.
 

Attachments

Z

Zephyr Schwarzwolf

Guest
Hi NightFrost !
Thank you, but I think the z-tiling would cause more issues compared to things it can solve... I'm sure there's a better way to do what I want !
I tried another system, but I need to use another variable than depth to sort my layers. Is it possible ? The aim is to give my main object two depth systems depending on the object (horizontale or verticale). Is it possible ? With a priority queue or, I don't know... I really want to find a system as simple and natural as possible.

Thank ya in advance !
 

NightFrost

Member
Well, I thought z-tilting is a relatively simple solution to multiple terrain depths, but I don't know what the specific requirements of your project might be, so it could be difficult to implement. You can change layer's depth on the fly with layer_depth, but using two depth systems sounds like giving the system lots of complexity. Priority queue is a simple way to put stuff in order; you throw everything in and they'll come out in order of their assigned priorities.
 
Z

Zephyr Schwarzwolf

Guest
Hi Nightfrost !
I finally tried the tilting shader. It seems to be a good solution indeed.
However, I'm having some issues applying it to my layers. (I think the problem is some layers have the same depth).

Here are my layers :
- Several backgrounds with high depth (seem not to be a problem) Grouped together.
- Several tile layers "horizontale" (0, - 32, - 64... depth) Grouped too.
- Several object layers "verticale" (0, - 32, - 64... depth) Grouped too.
- My main object layer with a default depth set on 0.That one is a single layer.
Obviously, I only want my objects and my main object to be tilted.

I tried to apply the effect layer per layer :
Code:
// Layer to tilt

tilted_layer = layer_get_id("TheLayer")
layer_script_begin(tilted_layer, scr_tilt)
layer_script_end(tilted_layer, scr_untilt)

// Do the same for all other layers
But it doesn't work. I think they have to be tilted exactly at the same time for the effect to work. But, if I tilt them all together, my tiles are tilted too ! But I don't want to change their depth...!

Do ya think you can help me ?
Thank you in advance.
 
Last edited by a moderator:
Z

Zephyr Schwarzwolf

Guest
Ok... I just realised that the shader doesn't affect tiles...
But that's because I have a problem with height !
I added a 3D cam to see what happens, exactly.
So, all my sprites are not tilted with the same angle ! (How can that be possible...? That happens only with me... :D).
Moreover (worst part), there's a sort of "distortion" with the z length. It's not equal to my sprites height (looonger than original size. More than twice longer).

Does someone know how to solve my problem ?
Thank you in advance.
 
Top