Terrible performance in comparison to vanilla Gizmos

Do you have any updates on this?

Hi

Sorry, I have had a really busy week and I haven’t had time to look at it yet. I’ll do it as soon as I can.

No problem. I just wanted to remind you that the download link to my project I sent you lasts for 7 days since I sent the message. So you should download it ASAP.

Sorry. I missed the download window :frowning:
I tried to replicate the issue with the URP package, but not matter what settings I changed, I couldn’t get it to not work.
Would you mind uploading your project again? :slight_smile: Sorry for the inconvenience.

Sure, will send it to you in DMs.

Aha! I found the issue!
It was a stupid thing.

The A* Pathfinding Project also uses ALINE internally. Both load the required materials using Resources.Load using exactly the same names. Since ALINE used the same name it would load the material used by APP instead of its own material. This caused it not to work since the APP used an different shader.

Took me a while to figure out why the A* graphs weren’t showing, though. Turns out you had set the opacity of the graph to 0 manually :stuck_out_tongue: .

I’ve published a new version of ALINE that fixes this (1.5.2). It should hopefully be up on the assetstore in a few hours.

Awesome, thank you! I’ll try the new version in the upcoming days.

Hahaha yeah, I usually keep it at 0 unless I explicitly need to see all the heavy gizmos. Probably should’ve mentioned that, sorry! xD

1 Like

Tested out 1.5.2. For now, everything seems to work. I’m getting 62-67 FPS, which is about 10% lower than vanilla gizmos which ain’t bad.

I’d just like to ask one more time about what I asked before:

“Additionally, I’ve noticed (and you can see this in the images) that the Unity gizmos when zooming out start fading away and getting thinner (as they should), but ALINE rectangles seem to keep this “minimum thickness” and you can see the entire map is very green compared to Unity gizmos. How can I fix this? I want the lines to remain small when the player zooms out the camera.”

You suggested that I’d have to adjust the color I draw my lines with, but that would be artificially lowering the opacity as I zoom further out. It makes no sense to me the when zoomed in you can see plenty of room between the gizmo lines, like here:

But then when fully zoomed out, it’s like the gizmo lines maintain a minimum thickness (like they always have to be atleast 1px thick) and as you zoom out there is nothing to see other than the lines themselves, like so:

Screenshot_2

Isn’t there any workaround for this? Is my only option to change the opacity as I zoom out?

ALINE always draws lines as 1px wide. Unity also draws their gizmos 1px wide, though they seem to reduce the opacity at some predefined distance. I don’t want to build an arbitrary distance like that, though I could potentially add something configurable.
Your best bet right now is to modify the alpha in your code.

It would be very helpful if you could add this as a feature and if we could control this through code. I’m sure some other people might have a use of this too. Would you consider adding this (doesn’t seem that difficult to implement) or should I add this myself, just so I know whether to expect this as a feature or not? Thank you!

Hi

I have it on my todo list, but it’s big… So don’t expect the feature very soon.

Thank you, I’m eagerly awaiting it. By the way,

" 1. The WireRectangle is not a primitive in ALINE. Instead, it will just draw 4 lines in the C# code. I’ve changed this in my dev version now which improves performance quite a lot."

Has this been implemented in version 1.5.2?

Has this been implemented in version 1.5.2?

Yes. Quoting the changelog:

Improved performance of Draw.WirePlane and Draw.WireRectangle by making them primitives instead of just calling Draw.Line 4 times.

I have one more question for functionality that I’m not sure exists / can be achieved. I need to be able to draw all tiles that are part of a “room”. However, the rooms aren’t always perfect squares and might exclude some tiles. Here’s an example - there is a blue overlay over all tiles except for the water body:

foreach (string regionID in selectedRoom.RegionIds)
        {
            foreach (Vector3Int node in RegionManager.Regions[regionID].Nodes)
            {
                using (Draw.WithColor(roomColor)) { draw.SolidPlane(new Vector3(node.x, node.y, 0), Rot, new Vector2(1, 1)); }
            }
        }

The problem is that my framerate dips from about ~160FPS to ~14FPS, because each solid plane is drawn separately. Would there be any way of batching or merging these solid planes into one “object” or “body” with combined vertices so I can improve performance, or is this something that I just have to live with?

Thank you!

Hi

They are already rendered as a single mesh.
For additional performance you could cache the resulting mesh:

This is a pretty undocumented feature at the moment, but you can do this:

var hasher = new Hasher();
// Hash something that will change whenever this group of rooms/the map changes
hasher.Add(...);
// If something with the same hash was drawn the previous frame, this function will return false
// and you won't have to re-issue all drawing commands. A cached mesh will be used instead.
if (DrawingManager.instance.gizmos.Draw(hasher)) {
    using(var draw = DrawingManager.GetBuilder(hasher, false)) {
        foreach (string regionID in selectedRoom.RegionIds) {
            ...
            draw.SolidPlane(...)
            ...
        }
    }   
}

See also Drawing in a game - ALINE and Draw - ALINE

Also. For extra performance, don’t use foreach. It’s significantly slower than a regular for loop. And you can also move out the WithColor scope outside the loop to avoid some overhead.

Hey,

Thanks for the helpful tip! This sounds like it would solve my problem exactly. However, I’m having an issue - nothing is being drawn. No new vertices are being created. Have I done something wrong?

Here’s what my code now looks like:

private static void DrawRooms()
    {
        Vector3Int gridNode = Map.GridPosFromMousePos();

        if (!RegionManager.GetRegionFromNode(gridNode, out Region selectedRegion)) { return; }

        Room selectedRoom = selectedRegion.Room;

        var hasher = new DrawingData.Hasher();
        hasher.Add(selectedRoom);

        if (DrawingManager.instance.gizmos.Draw(hasher))
        {
            using CommandBuilder hashDraw = DrawingManager.GetBuilder(hasher);

            foreach (Region region in selectedRoom.Regions)
            {
                foreach (Vector3Int node in region.Nodes)
                {
                    hashDraw.SolidPlane(new Vector3(node.x, node.y, 0), Rot, new Vector2(1, 1), Color.cyan);
                }
            }
        }
    }

For simplicity reasons, I’m passing the color directly instead of the scope. This method is being called as such:

public override void DrawGizmos()
    {
        if (!Application.isPlaying || QuantumConsole.Instance.IsActive) { return; }

        if (Keyboard.current[Key.V].isPressed) { DrawRooms(); }
    }

As for the comment to use for instead of foreach, I am aware, but in this case I can’t since I’m dealing with HashSets instead of lists.

Again, thank you!

Hmm. Are you sure about that using statement? I think you need brackets.

I’m sure. That’s just the IDE offering a refactoring solution that looks nicer. Basically just syntactic sugar. I tried with the brackets before - still didn’t work.

Sorry, I made a typo. That should have been

if (!DrawingManager.instance.gizmos.Draw(hasher))

(note negation)