Having a central ImmediateModeShapeDrawer

Avatar
  • updated

In the doc it says, "I recommend having only one central ImmediateModeShapeDrawer in your scene, then have that call functions in other objects, in order to have full control over draw order." which I didn't quite understand. Should I make a game object and reference each component in the scene that draws a shape and call its draw function? What is the best way to have a central ImmediateModeShapeDrawer?

Thank you 🙏

Reporting a bug? please specify Unity version:
Reporting a bug? please specify Shapes version:
Reporting a bug? please specify Render Pipeline:
Built-in render pipeline
Avatar
Yaniv Avrahami
Quote from Freya Holmér

What is "best practice" really depends on how you want to structure your code, there's not really anything special about Shapes in this regard, so it's more of a general question about code structure that you'll have to decide for your project.

There are many approaches - you can have a type that adds itself to a list in the centralized drawer in OnEnable, and removes itself in OnDisable, if you want to draw everything from one place, but still have the actual drawing code in the objects themselves.

You can directly reference all the objects from the central manager, and nullcheck in case it might not exist, etc

Though keep in mind that sorting and draw order might not behave the way you expect with immediate mode, and sometimes it's more performant to use the components :)

As for tutorial videos, I don't have any out at the moment!



Thank you.

Avatar
Freya Holmér creator

What is "best practice" really depends on how you want to structure your code, there's not really anything special about Shapes in this regard, so it's more of a general question about code structure that you'll have to decide for your project.

There are many approaches - you can have a type that adds itself to a list in the centralized drawer in OnEnable, and removes itself in OnDisable, if you want to draw everything from one place, but still have the actual drawing code in the objects themselves.

You can directly reference all the objects from the central manager, and nullcheck in case it might not exist, etc

Though keep in mind that sorting and draw order might not behave the way you expect with immediate mode, and sometimes it's more performant to use the components :)

As for tutorial videos, I don't have any out at the moment!



Avatar
Yaniv Avrahami
Quote from Freya Holmér

So, this only applies for immediate mode, it doesn't apply to shape components in general!


But yes, each Draw.Command will issue a separate command buffer, so if you can keep all your drawing in the same command buffer, it would be more performant. you can definitely call functions in other scripts from within the Draw.Command scope of your immediate mode shape drawer if you like!

Thank you for your answer. can you please give me a simple example of how to implement this best practice?

I'm developing a VR tabletop game (Chess, Checkers and Go) for Q2. So I made a SnapPointGrid game object attached with a SnapPointGrid script that inherits ImmediateModeShapeDrawer. I override DrawShapes and draw the graph inside the SnapPointGrid like so:

public override void DrawShapes(Camera cam)
{
    using( Draw.Command( cam ) ){
        Draw.Matrix = transform.localToWorldMatrix;
        DrawExtensions.Grid(snapPoints);
    }
}

now, to apply your best practice here, should I make a game object called ShapesManager with an ImmediateModeShapeDrawer that overrides DrawShapes and draw the graph? How do I know if the graph exists or not, should I reference each grid, in general, any MonoBehaviour that needs to draw? Where does the drawing logic reside?

Also, although this package is super easy and intuitive, do you have tutorial videos about Shapes?

And sorry for my bad English, I know 4 languages and English is not my native🙏

Avatar
Freya Holmér creator

So, this only applies for immediate mode, it doesn't apply to shape components in general!


But yes, each Draw.Command will issue a separate command buffer, so if you can keep all your drawing in the same command buffer, it would be more performant. you can definitely call functions in other scripts from within the Draw.Command scope of your immediate mode shape drawer if you like!