Draw.Text multiple times in same frame has same string?

Avatar
  • updated
  • Unity's Fault

Hi there,

Not sure if this is a known issue, but it seems like calling Shapes.Draw.Text() multiple times in the same frame results in the same string being drawn at each position.

Tried to reduce to a fairly simple test case, eg.

Camera.onPostRender += (Camera cam) => {
Draw.ResetAllDrawStates();
Draw.FontSize = 100;
Draw.TextAlign = TextAlign.Left;
Draw.Text(new Vector3(0, 0, 0), "Hello");
Draw.Text(new Vector3(0, 10, 0), "Goodbye");
};

I also tried adding a few extra "update yourself now" calls on the TMP object within Draw.Text() but the only thing that seemed to actually help was calling DestroyImmediate on the ShapesTextDrawer.Instance after each draw call.

I was originally on TMP 3.0.1, and upgraded to 3.0.3 but looks like it's still happening. Not sure if it's a newly introduced bug in TMP, or if there are now some extra things you need to do to flush if re-using the same TMP component's mesh in the same frame (since I noticed Shapes' min TMP version is 1.4.1)

Reporting a bug? please specify Unity version:
2020.1
Reporting a bug? please specify Shapes version:
2.3.1
Reporting a bug? please specify Render Pipeline:
Pinned replies
Avatar
Freya Holmér
  • Answer
  • Unity's Fault

well, that is super bizarre :c

it's almost certainly a bug on Unity's end then, though it would be nice if there was a workaround

Avatar
Freya Holmér
  • Under Review

Hm, yeah this has never happened to me in 2018 or 2019, so it might be something new with 2020, I'll look into it

Avatar
Geordie Hall

I just discovered that disabling/enabling the TMP component seems to have the same effect as totally destroying the object, so am now doing that instead, which is much more performant :)

eg.

Avatar
Freya Holmér

ah, good find! I'll look into this soon, I've been super busy moving apartments as of late, so apologies for the lack of updates!

Avatar
Geordie Hall

Oh yeah no problem at all, just thought I'd mention cause probably lowers the priority of this one for you :)

Avatar
luke underwood

hey! fwiw, i am seeing this bug also, but the `tmp.enabled` toggle trick didn't seem to work for me. however, i was able to get it working by just changing the one DrawMeshNow line from

Graphics.DrawMeshNow( tmp.mesh, mtx, sm );
to
Graphics.DrawMeshNow( GameObject.Instantiate(tmp.mesh), mtx, sm );

which i thought was interesting. it seems like it should be the same data whether or not it's a clone. i'm pretty new to unity though so maybe that's expected.

Avatar
Freya Holmér
Quote from luke underwood

hey! fwiw, i am seeing this bug also, but the `tmp.enabled` toggle trick didn't seem to work for me. however, i was able to get it working by just changing the one DrawMeshNow line from

Graphics.DrawMeshNow( tmp.mesh, mtx, sm );
to
Graphics.DrawMeshNow( GameObject.Instantiate(tmp.mesh), mtx, sm );

which i thought was interesting. it seems like it should be the same data whether or not it's a clone. i'm pretty new to unity though so maybe that's expected.

it's worth noting that this method will leak meshes every frame you draw, since you don't destroy the instantiated meshes

this should all be fixed in the upcoming 3.0.0!

Avatar
luke underwood

hey! wanted to give an update that unfortunately this still seems to happen on v3.0.0. I can create a new issue if you'd prefer to track the v3 bug separately.

cloning `tmp.mesh` before it is passed into the new `IMDrawer` appears to still fix the issue (outside of it leaking memory of course). 

Avatar
Freya Holmér
Quote from luke underwood

hey! wanted to give an update that unfortunately this still seems to happen on v3.0.0. I can create a new issue if you'd prefer to track the v3 bug separately.

cloning `tmp.mesh` before it is passed into the new `IMDrawer` appears to still fix the issue (outside of it leaking memory of course). 

does this happen even when using Draw.Command? (check the docs for usage!)

because internally it should actually clone the mesh (and later delete it)

Avatar
luke underwood

that did it, thanks! sorry should have checked for new docs first 😅

Avatar
Freya Holmér
Quote from luke underwood

that did it, thanks! sorry should have checked for new docs first 😅

oh I mean, it should still work without using Draw.Command, so I'll still look into this :)

Avatar
Freya Holmér

I can't reproduce this - it seems fine for me in 2020.1

does anyone have some code that will 100% repro in 3.0.0?

Avatar
luke underwood

I'll try to put together a minimal reproduction case and push to github over the next day or so.

Avatar
luke underwood

ok, I put together an example that reproduces this in 2020.1, but it may be that this is actually expected behavior in shapes 3 since it uses `endCameraRendering`.

the gist is using URP and

using UnityEngine;
using UnityEngine.Rendering;
using Shapes;

public class GameManager : MonoBehaviour {
  public void OnEnable() {
    RenderPipelineManager.endCameraRendering += OnEndCameraRendering;
  }

  public void OnDisable() {
    RenderPipelineManager.endCameraRendering -= OnEndCameraRendering;
  }

  private void OnEndCameraRendering(ScriptableRenderContext context, Camera cam) {
    Draw.Text(Vector2.up, content: "One", fontSize: 24, color: Color.red);
    Draw.Text(Vector2.down, content: "Two", fontSize: 24, color: Color.red);
  }
}

This reproduces the bug, but uses "endCameraRendering". When I use `beginCameraRendering` like the docs say in v3, then it doesn't seem to draw anything until I wrap it in a `using (Draw.Command(cam)) {}` block, but then it works totally fine.

I'd imagine this is all expected behavior, so sorry for the false alarm!

Avatar
Freya Holmér
Quote from luke underwood

ok, I put together an example that reproduces this in 2020.1, but it may be that this is actually expected behavior in shapes 3 since it uses `endCameraRendering`.

the gist is using URP and

using UnityEngine;
using UnityEngine.Rendering;
using Shapes;

public class GameManager : MonoBehaviour {
  public void OnEnable() {
    RenderPipelineManager.endCameraRendering += OnEndCameraRendering;
  }

  public void OnDisable() {
    RenderPipelineManager.endCameraRendering -= OnEndCameraRendering;
  }

  private void OnEndCameraRendering(ScriptableRenderContext context, Camera cam) {
    Draw.Text(Vector2.up, content: "One", fontSize: 24, color: Color.red);
    Draw.Text(Vector2.down, content: "Two", fontSize: 24, color: Color.red);
  }
}

This reproduces the bug, but uses "endCameraRendering". When I use `beginCameraRendering` like the docs say in v3, then it doesn't seem to draw anything until I wrap it in a `using (Draw.Command(cam)) {}` block, but then it works totally fine.

I'd imagine this is all expected behavior, so sorry for the false alarm!

running that code in 2020.1 URP endCameraRendering for me seems to work just fine on my end



(and switching to beginCameraRendering will not work in general since URP will clear the render target after that event)

Avatar
luke underwood

huh, well I'm happy to call it fixed, but if you're curious I pushed up the code to this private repo here and tried to add you as a collaborator https://github.com/veryeasily/TextRepo . the reproduction is inside the scene named "Main".  (I am still vague on how I could add shapes to a public unity github repo and not expose the code)

Avatar
Freya Holmér

opened your project in your version of Unity, and it seems to work fine


I'm on windows - are you on osx or something?

Avatar
luke underwood

Yeah, I'm on MacOS 10.14.6 (Mojave), so that seems super likely what it is.

Here's my screenshot, but yeah sounds like this is a mac vs windows thing

:

Avatar
Freya Holmér
  • Answer
  • Unity's Fault

well, that is super bizarre :c

it's almost certainly a bug on Unity's end then, though it would be nice if there was a workaround