Seperating y-sort from global_position

Godot Version

Godot version 4.7.1 stable win64

Question

I am trying to make a pixel-based game for fun, and I have a grid-based level. I can build buildings during runtime, so I usually pick the tile I want to spawn my building on, convert that tile to a global position and pass it to my instanced building before adding it as a child.

The origin point for the y-sorting looks weird though: it’s in the middle of the building. I would like to move that down to the bottom of the building, but without actually changing the visual placement of my building. But the only way I have figured out how to adjust the y-sorting of my building is to go to the building scene and manually move the sprite upwards. But when I then spawn it in during runtime, the entire building has moved upwards which I dont want.

Is there a way to move the y-sorting point without having to move the entire buildings visual placement? One idea is to change the global position of the building, and then offset the sprite in the opposite direction, but that seems like a very fragile solution.

Well shift the spawn positions downwards. You don’t need a whole scene per building though. Sprites have the offset property.

My issue with shifting the spawn position one way and offsetting the texture the other way is that idk, it feels fragile? Like the buildings will spawn stuff and interract with things, so having the actual global position shifted feels like it would cause issues. Is there no way to move the y-sorting anchor or origin or whatever without shifting the global position itself?

Also what do you mean I dont need a whole scene per building? Dont I need to make a new instance of myt building scene every time I want to “build” one during runtime?

The sorting anchor is always at local 0, 0. I think you’re just getting confused by the relativity of positions.

If you need a scene per building use it, but you can get away only with a single sprite.

If you have a scene, its sorting position as well as its spawn position will always be at its local origin. So just move the scene graphics up so that the local origin is at the the building’s visual base.

So when I go to that specific building scene and move the graphics in the sprite2d node, the y-sorting origin indeed changes the way I want. But my issue is that at the same time, when I then spawn that building on say grid tile_mouse_pos = (2,2) using TileMapLayer, my code is something like

(I can’t figure out how to post the code in a reply here in codeform)

var tile_mouse_pos : Vector2i = TileMapLayer.local_to_map(local_mouse_pos)

instance_goblin_hut.global_position = grid.map_to_local(tile_mouse_pos)

But if I moved the texture in the scene to make the origin point for y-sorting fit, when I then place it on the map during runtime the texture is also moved upwards. But I liked how the texture was previously positioned. Is the only fix to move the texture and then change the global position correspondingly?

Y-Sorting can be replicated via code, just set ordering based off position higher ordering means it will be rendered on top of everything, lower means it will be rendered below everything

As in I can do something like

instance_goblin_hut.y_sort_anchor = instance_goblin_hut.global_position + 60?

I cant find any examples of this online, what is the syntax? Or do you mean “which object you place on top” 100% of the time"? Because what im looking for is dynamic y-sorting depending on the position of the player compared to the object/building, but seperated from the global positioning

I say about ordering, it’s property of what’s rendered before everything else, you can change it via code, and make custom Y-Sorting this way