Nez: free, open source 2D framework

Sorry, didn’t see anything regarding those things. I just searched github for ie. nez and camera to figure out how the followcamera is set up

After finally circling back to this issue and spending another hour with FollowCamera, deadzone, lerp, trying to round the player position, etc. and noticing that the Ninja example also stutters, I’ve started to write my own FollowCamera,… which has the same stutter. I think it’s due to the time when the camera get’s updated, seems to lag behind a little. So my player now directly updates the camera and the problem is gone.

1 Like

Same thing, I’ve using FollowCamera with the same problem and tried tweaking deadzone, lerp, trying to round the player position, etc. And I’ve also tried updating the camera directly but I still see the stuttering problem.

public void update()
        {
            var moveDir = Vector2.Zero;

            if (Input.isKeyDown(_inputs.Up))
                moveDir.Y = -1f;
            else if (Input.isKeyDown(_inputs.Down))
                moveDir.Y = 1f;

            if (Input.isKeyDown(_inputs.Left))
                moveDir.X = -1f;
            else if (Input.isKeyDown(_inputs.Right))
                moveDir.X = 1f;

            var deltaMovement = moveDir * speed * Time.deltaTime;
            var nextPosition = entity.position + deltaMovement;

            entity.transform.setPosition(nextPosition);
            _camera.transform.setPosition(nextPosition);
        }

Could you share your repo that solves this issue? Thanks.

Manage to smooth the jitter making sure that the updated position is rounded.

var deltaMovement = moveDir * speed * Time.deltaTime;
var nextPosition = entity.position + deltaMovement; // updating with this position now, will cause jitter

nextPosition = nextPosition + _overflowVector; // sum previous remainder
_overflowVector = new Vector2(nextPosition.X % 1.0f, nextPosition.Y % 1.0f); // get new remainder
nextPosition = new Vector2(nextPosition.X - _overflowVector.X, nextPosition.Y - _overflowVector.Y); // round

entity.transform.setPosition(nextPosition);
entity.scene.camera.setPosition(nextPosition);

I ran into this issue as well.

I believe this is happening because scene objects (which is where the camera lives) are updated before entities. It was causing horrible stutter for me when my design resolution was set to something low (480x360)

I scaled everything up 3x and am now running at a higher design resolution of 1920x1080 and the stuttering is gone.

I’m not sure how to fix the stutter in row resolution without serious modification to the way Nez does rendering internally. I’m not sure if the above solution of rounding the position up will work well on a tiled map following a character who is moving via the tiledmap function… but if someone gets that (or anything) fully working I’d love to read about it.

Prime31 made additions to movement code to account for a subpixel movement, I have tried it in my own project and it works like a charm. Checkout the latest nez version and give it a try.

I am using Nez and having some issues with the boxcastBroadphase method in Physics. I have create an entity that attaches a collider to itself, like this
public Solid(int x, int y, int width, int height) { this.Collider = new BoxCollider(width, height); Flags.setFlagExclusive(ref this.Collider.physicsLayer, 10); this.transform.setPosition(x + (width / 2f), y + (height / 2f)); this.addComponent(this.Collider); }

but when I use this to get the colliders with the same mask, it does not return any of the colliders

this.BroadphaseSolids = new HashSet<Collider>(Physics.boxcastBroadphase(this.camera.bounds, 10));

From what I understand from the documentation, this should give me all of the colliders with the layer mask 10 that are inside or intersecting the camera bounds. If I remove the 10, and just ask for all of them, I get 26. When I add the layer mask, I get none. Is there something I am missing?

I believe the Broadphase message takes a mask, not an individual layer.

Thanks for the quick reply. It looks like that was the problem. I haven’t had much experience with layer masks.

yeah, the physics system in Nez isn’t super intuitive. It took me a bit of time to wrap my head around it but now that I understand it, I really like it.

Hey, I am using Nez to make my own Tile Engine and am struggling to get the layerDepth to work when rendering my tiles.

I have one component called TileMapComponent, which implements IRenderable and takes care of rendering all of the tiles on the map through a for loop which calls Batcher.draw(). For some reason, specifying a layerDepth in the draw() method doesn’t do anything, it seems that it only worries about draw call order.

I have found a “hack” to get it working by manually sorting all of the tiles that are at the same position but on different layers and then calling them in order. But then it still doesn’t work with any external entities (say I have a player entity that is on the 1.0f depthLayer, it renders behind the 0.5f tiles simply because it is declared/called before them). I’ve even tried inverting the depthLayer, setting the DepthStencilState, etc. Nothing worked.

So does Nez’s Batcher not support depthLayer? or am I misunderstanding something?

Here’s a small code sample which shows my draw calls.

Note: Since all of the tiles are rendered by one component, the renderableComponentList only includes ONE component when I try to debug.

Thanks!

If you trace through the Batcher code you will see that layerDepth works exactly like SpriteBatch. There is no difference at all.

Here’s a video using a simple test RenderableComponent showing the issue.
(As you can see in the video, simply switching the two lines changes the render order even if I have specified the layerDepth as 0.5f and 1.0f, ideally the NotFoundTexture would always render on top).

The only things in my Scene class are these in the initialize() method:

public override void initialize() {
    clearColor = Color.LightGray;
    addRenderer(new DefaultRenderer());
    Entity test = createEntity("test");
    test.addComponent(new TestRenderComponent(content));
    Core.debugRenderEnabled = true;
}

It seems to me like it’s an issue with MonoGame or Nez’s Batcher, not sure tho.

EDIT: I have also tried setting the renderer’s material.depthStencilState to DepthStencilState.DepthRead but it did not change anything.

EDIT2: Saw that I forgot to change the sourceRectangle parameter for NotFoundTexture in the video, but that doesn’t matter since they are both the same size and position. Question/issue still stands.

Did you enable depth test? Nez by default doesn’t use it because when you use Nez RenderableComponents the “Nez way” (is not trying to write two layers one after another) Nez will sort the calls before sending them to the GPU.

I’m not sure what you mean by “depth test.”
But if you’re saying that (by default/“Nez way”), Nez will sort the draw calls based on depth, then shouldn’t my draw calls be sorted then?

You have two calls happening one after another and you are overriding the layer depth. Nez can’t sort that. Do your two draws in separate RenderableComponents and then it can sort it. Have a look at the Nez.samples repo for lots of examples of sorted calls based on layerDepth and renderOrder.

So what you’re saying is that multiple layerDepth don’t work inside one RenderableComponent?
I was trying to render all of my tiles on one RenderableComponent to avoid creating entities for each tile. Is that just not possible then?

I guess what I could do it is to write some sort of wrapper that takes all of the “draw calls,” sorts them by layer, then actually calls the batcher.draw(). Would that be the only way?

By default, DepthStencilState is set to None. Nez doesn’t use or need a depth buffer because it sorts everything itself. What you are trying to do by just rendering stuff with no specific order requires the depth buffer to be enabled. You can of course make your own Renderer that doesnt sort and enables depth testing. The “Nez way” of doing this would be to just add multiple RenderableComponents on a single Entity if they are all related. Just let Nez handle the sorting and render order for you by setting RenderableComponent.layerDepth/renderLayer.

Alright, finally got it working. I ended up using one RenderableComponent for each layer, and have a main Component that sends the tiles to be rendered to their corresponding layer.

Thanks for all the help (and sorry if I was kind of pushy).

Hey!
After looking more into the rendering code, I found a much simpler way to fix this issue. The only reason why Nez can’t handle the depth layer is that DefaultRenderer uses Material.defaultMaterial, which has its DepthStencilState set to None.

So I created a custom Renderer with this line in the constructor

this.material.depthStencilState = DepthStencilState.Default;

that was enough to fix all of the issues and for the Batcher.draw() method to accept/use the depthLayer.

I was wondering, do you want me to submit a Pull Request to add this to the DefaultRenderer? Or perhaps add a new Renderer that fixes that issue? Or maybe add it to the docs? Just think it might be useful for others in the future.