How to Create a UI System Using SpriteRenderer Instead of Canvas?

I’m working on a Unity project where I want to create a UI system without using the Canvas component. Instead, I plan to use SpriteRenderer for buttons, panels, and other UI elements.

I have set up basic buttons using SpriteRenderer and BoxCollider2D to detect clicks using OnMouseDown(), but I’m looking for best practices and optimizations for:

  • Handling different screen resolutions and aspect ratios.
  • Animating sprite-based UI elements (e.g., button press effects).
  • Efficient rendering to avoid performance issues (e.g., draw calls).
  • Managing UI states without Unity’s built-in Event System.

Are there any best practices, packages, or alternative approaches for implementing a fully sprite-based UI? I’d love to hear any insights or recommendations from others who have tried this approach.

Thanks in advance!

I would really recommend not trying this as it’s going to be a nightmare. For example, even a text component requires a Canvas so you’d also need to make your own text engine (or have a canvas for each text). I’ve never seen anyone attempt this after Unity added UGUI. If I was really forced to I’d probably try using an existing layout engine like Yoga (made by facebook and the same layout that UIToolkit uses) demo. This also helps group textures to improve performance e.g. flat rather than nested. I remember back when I was using direct x that some of the demos would render fonts to render textures for text. Not sure how BoxCollider2D handles overlapping values e.g. button on a dialog with a clickable background to close. I’d probably just use rects instead. Support for multiple devices will also be difficult e.g. gamepad navigation. Plus there are a lot of complex controls like dropdowns, scroll views etc.

Not sure why you want to try this but I can’t see it ending well.

I think this is a very good idea, if you need it. The ability to use particle systems and such without much hassle is very nice.

You will need to implement your own selection/UI state system, but that’s actually pretty easy. I got fed up with Unity’s system and implemented our own, and I think that will take less time than you spend on fighting EventSystem in anything longer than a game jam.
It’s not super hard code to write, and since your code can get to know about your game, you can cut down pretty heavily on the abstractions. As an example, if you’re entering a sub-menu in a normal main menu, your sub menu can have an object that gets notified that it’s entered, and knows which button to set as the active one. Super simple stuff.
Animating is just adding Unity animations to the components, and then having your code set the correct animation when you need it. It shouldn’t be harder than OnSelect() animator.Play("selected");, and anyone telling you that it needs to be harder are silly and wrong.

The only hard part is dealing with resolutions and aspect ratios. If you’re just making the main and in game menus, it’ll be somewhat straightforwards - just assume that the aspect ratio is somewhere between 1:2 and 2:1, and make sure to center your stuff so it doesn’t go outside the screen at either of those.

On the other hand, if you need anchoring to the side of the screen, you’ll need to figure out how to do that in a good way. If you want things like automatic wrapping to dynamically handle screen size, then you’re over to this not being a good idea at all anymore.

The tl;dr is really to just sit down and write the code. Unless you’re doing a dynamic UI framework, the code is going to be pretty straightforwards. Stuff like UGUI/UITK gets very complicated because they aim to be generic frameworks where you can do everything for every game possible just from the editor. If you make the UI for your game, it shouldn’t be too bad.

Then create it using the UI Document component (aka UI Toolkit). :wink:

I’m torn between saying “reinventing the wheel, waste of time” and “curious, I want to do so myself”. :laughing:

Be sure you have very, very, very good reasons before you dive into this as it will be way more challenging and time-consuming than you might think. Particularly if you want to handle resolutions and aspects well. Not to mention all the feedback cues that users will come to expect, the mouse over, the selected, the pressed state of a button - omit just one of these and the UI feels unresponsive.

As to handling aspects, just make sure to anchor your content to one of the main anchors: the four screen corners, the four screen edge centers (ie left center), and the screen center itself. If that doesn’t suffice for your UI and HUD then definitely make sure that all UI coordinates are relative screen coordinates in the range 0,0 to 1,1.

For screen resolution it’s hardly enough to do a 1.5x scaling when the UI is designed for 1280x720 but the resolution is 1920x1080. Bad example because in this case it will probably work fine, but it may not be fine with odd resolutions (eg scale like 1.4375) and a change in aspect ratio too (you need to pick either width or height for the scale factor).

Scaling images would lead to aliasing of the UI images and text, even to the point where a string of consecutive letter looks like this “IIIIIIIII” (some letters are wider than others). It gets particularly worse if the UI images are point filtered pixel art images and fonts. You can really only scale them by multiples ie 2x and 4x.

The most important advice here is to set limits. If you know the game is designed for 2k/4k and 16:9 resolutions then absolutely use these and ignore everything else as much as possible. You’d support scaling the UI by 2x and that’s it. Even “close enough” aspects will work fine when using edge/corner anchors since that aspect simply has marginally more vertical pixels.

You should edge/corner anchor UI elements and don’t worry too much about crazy aspects like 5:4 (there may be overlap) or 32:9 (works but UI elements are awkwardly far away), or at best accomodate a special mode ie assuming a 16:9 ratio on a 32:9 screen either using black borders or anchoring UI elements to the 16:9 ratio relative to the screen center (ie corner/edge-anchored UI elements will be at 25% and 75% of screen width) while still allowing the viewport to expand horizontally to the full width.

The more you worry about making it work with uncommon aspect ratios and resolutions the more work you’ll have on your hands, like this tends to grow exponentially and only serves a greatly diminishing number of players.

Also know your UI. If you want to create a Tycoon game like the classic Transport Tycoon Deluxe which had an OS-like windowing system with scalable and movable windows, with many nested and scaling elements, then you may be spending a year trying to figure this out. If however your game is something like Broforce or Vampire Survivors where each screen corner has some clearly defined HUD element (health bar, score, selected weapon) and a menu screen with classic Doom-style selection/navigation, only then will it be as easy as Baste implies.

1 Like