Dynamically update rendering order based on position? (SOLVED)

Hello!

What I would like to do is basically update the rendering order of game objects according to their position. So for example, as shown in the image below, certain objects should appear in front of other objects when they are lower than them on the Y-axis, but behind them as they move higher on the axis.
Think of tall characters who stand in front of trees, but then may move behind them.

Untitled

(sorry for the ms paint illustration)

So what would be a good way to approach this in Defold? With a quick search I saw that it may need to be handled in the render script, but any pointers in the right direction will be much appreciated :slight_smile:

You can sort the items based on y value and then assign the z component of the gameobjects based on the order.

Sort all game objects in the world on every cycle? Doesn’t sound like it would go to well…


Alright so if Defold doesn’t already have a way of handling this, would something like this work?

function update(self, dt)
    z = -y
end

And then make sure that background elements are somehow on the minimum z.

You can just use the z component of game objects and tilt the camera the way you want it.

1 Like

As @jhonny.goransson suggests, I’ve only ever heard of this being solved by sorted the objects based on increasing y values and increasing x values, translated into a final z value. If nothing moves during a frame, there’s no need to resort. If only a couple of objects move, you may not need to resort every object in the scene, just the ones surrounding the object that moved.

1 Like

In outline you don’t need to sort objects, cause it makes an engine in render, you need to set z value only. For example you may check this sources https://github.com/Dragosha/slasher-prototype

1 Like

Thank you for the suggestions.

What I ended up doing is I basically created this script:

typedef DynamicZAxisProperties =
{
	@property(0.0) var z_min: Float;
	@property(0.1) var z_max: Float;
    @property(3.4e+6) var y_range: Float;
}


class DynamicZAxis extends Script<DynamicZAxisProperties>
{
    override function update(self: DynamicZAxisProperties, dt: Float) 
    {
        super.update(self, dt);

        var position: Vector3 = Go.get_position();

        var zMiddle: Float = (self.z_min + self.z_max) / 2;
        var zRange: Float = self.z_max - self.z_min;

        position.z = zMiddle + (-position.y / self.y_range) * (zRange / 2);

        Go.set_position(position);
    }
}

I attach this script to all objects that I want sorted on the Z axis according to their Y coordinate, and I can also specify the range of Z-values on which they will all exist.

And as you can see it seems to work ok:

z_axis

Seems more efficient than sorting objects around, no?

The problem with this implementation is that y_range can’t really be more than e+06, because then the precision is not enough to differentiate nearby objects. So this will break for absolute Y values greater than e+06.


I marked the thread as solved now, but I would still like any feedback on my approach, still learning the engine :slight_smile:

2 Likes

Cool. Is that Haxe?

1 Like

Yup!