Search Unity

Scenes vs Canvases vs Panels

Discussion in 'UGUI & TextMesh Pro' started by authorthe, Nov 13, 2014.

  1. authorthe

    authorthe

    Joined:
    Oct 28, 2014
    Posts:
    5
    I'm trying to create a game which almost entirely consists of UI with some underlying simulation (I haven't yet decided whether to 'visualize' any parts of the simulation with moving objects etc., but that would probably be a task for version 2 at this rate).

    As a result, I essentially have a need for many different 'Screens' in which I might want to, for example, show a list of entities and, in another screen, detailed data regarding the one specific entity that was clicked on.

    What I'm trying to establish is the best 'architecture' for structuring the flow inside Unity. Should the individual 'Screens' be multiple panels inside one Canvas that I switch on and off in order to transition between them? Individual Canvases? Completely separate Scenes?

    I've had a go at various different approaches which all threw up different challenges. For example, the separate Scenes approach had me delving into Singletons to be able to reference the game data from anywhere and hold some kind of 'state history' that I could use for forward / back buttons. Alternatively, just using UI elements did away with some of that, but made the Editor a bit cluttered and I worried about the overall performance of having lots of elements in one Scene (albeit all inactive apart from the 'current' one).

    I imagine any or all approaches could be 'made' to work with enough effort, but I was wondering if anyone had any advice on which approach might lend itself best to this kind of game with Unity's new UI. Any thoughts?
     
  2. Fattie

    Fattie

    Joined:
    Jul 5, 2012
    Posts:
    476
    I just asked exactly the same thing a week later ....

    With new UI, separate scenes, or just separate panels?

    it's really surprising that there is not more discussion about this. Other than the simplest examples, you always have multiple "screens" of UI, or course, obviously.

    of course, you cannot use multiple "Canvas" because, annoyingly, they all stack up over each other.

    (THERE IS A "TRICK" SOLUTION TO THAT .. USE A SEPARATE GUI CAMERA FOR EACH ONE and you can move them around on the overall editor; it makes no difference to the final Playing result.)

    Personally we decided to just use separate Unity scenes. it means you can't (easily) make animated transitions.

    (As an aside -- But really, as a creative matter, does anyone care about animated transitions between buttons anymore? Answer "no", everything will look like "iWatch" soon :) )

    My thoughts on the matter:

    (1) it's really better to use separate Unity scenes. it's "just better" pipeline all around. it's worked painlessly so far for us dudes

    (2) Multiple canvasses seem to be an "absolutely essential" concept. BUT there's the silly problem you can't move the nominal position in the editor, so, they all stack up and you can't work that way

    (3) In my opinion: Unity's suggestion, and what they show in the current demo ("3D scene"), is that you just fool around with panels. For me, that's not software engineering :) Clearly, a "canvas" (or a whole Unity scene) is the metaphor level for one "screen" of UI. A panel is just a sizer for groups. (For sure, in some obscure cases if you wanted intensely interacting panels, etc, you'd do that. But that's exactly like saying: in iOS sometimes you just totally ignore the whole edifice view controllers, and you manually fly around UIViews etc. Of course, that's insane in normal engineering practice, a non-starter.)

    Finally, as I mention you

    (4) Can indeed use multiple canvasses, with the silly trick of "a camera for each" so they don't nominally sit on top of each other in the editor.

    It could be I am unknowledgeable and there is a better way to make multiple canvasses not sit on top of each other.
     
  3. sonicviz

    sonicviz

    Joined:
    May 19, 2009
    Posts:
    1,051
    Hi,

    Did you arrive at a best solution for this? I have a similar need for a very UI heavy app, and have been wondering since I just started playing with the beta RC2.

    Scenes sounds a bit overkill to me.
    How are you handling loading/unloading of scenes, and testing them all in context when data has to flow between them?
    Wouldn't a panel solution be better, that just plays with transform positions?
     
    sfir likes this.
  4. Senshi

    Senshi

    Joined:
    Oct 3, 2010
    Posts:
    557
    I actually have to disagree with @Fattie; reasons and arguments inline.

    "Just better" really isn't much of a reason if you ask me.. AFAIK there isn't really a lot of convention, or The Way™ of doing things in uGUI (yet). Using scenes can be better, but it heavily depends on your particular situation. For example, I wouldn't use different scenes just for a simple TV guide app e.g.

    Again, multiple canvases can be a great tool, but I wouldn't call it essential; especially not in every use-case. The problem you're describing here is exactly what panels are for imho. The current behavior is absolutely desirable in some situations.

    I'm very curious as to why you said "that's not software engineering". I don't know your intent with this, but to me it comes off as a bit pompous, as if panels are somehow inherintly evil to use.

    I also disagree with your premise about canvases being "meant for" a single screen, and panels being nothing more than sizers. They are also completely different from, and used in completely different ways than, Obj-C UIViews, so drawing this parallel seems a bit misguiding. If anything though, I would say a scene is a UIView more than anything, ready to be populated with elements one way or another (but even that is a stretch imho).

    Rather, here's how I would define the different elements described:
    Scene: A (mostly) self-contained part of the application.
    Canvas: A root container for a ((mostly) self-contained) group of UI elements.
    Panel: A container for a ((mostly) self-contained) group of UI elements.

    I define Canvas and Panel as nearly identical, because they are very similar. When using a world-space canvas, both can move around, stack, etc. When used as a camera overlay, you can use different Canvases to either separate by function, or perhaps to create some stacking effects, separate camera filters, etc.

    I think it's very valid to just look at a panel as a sort of "sub-canvas". There is absolutely nothing wrong with using these for different parts of your app. Again though, a lot of what's practical depends on context. If you have a Game scene for example, you could very well use a single canvas, with in it a HUD panel, a Pause Menu panel, etc. Considering these are only different entities conceptually, but still each have to be rendered the exact same way, I would use panels here rather than different canvases. If you need fancy camera filters on one, but not the other however, I would opt for separate canvases.

    I would personally avoid using too many separate scenes if possible. For me a scene very clearly represents a part of an application, like say a opening screen (press X to start), a character selection screen and the game. Within each of these distinct parts, I would (and do) only use different canvases if needed, but mostly different panels.

    Obviously I'm not an authority on the matter in any way, but these are just my two cents. =)

    Cheers!
     
    Last edited: Nov 20, 2014
  5. Fattie

    Fattie

    Joined:
    Jul 5, 2012
    Posts:
    476
    Hey Sensh !

    Sorry if I was unclear .......

    (1) using separate scenes...

    (pro a) you avoid the silly "disable unused items" problem

    (pro b) it's encapsulated (pretty foundational software engineering need!)

    (2) multiple canvasses ...

    (pro a) they are encapsulated

    (con a) your DON'T avoid the silly "disable unused items" problem

    (con b) the ridiculously annoying "they all sit on top of each other" problem

    (2) multiple panels ...

    (pro a) they are not very encapsulated, encapsulation is more at the canvas level

    (con a) your DON'T avoid the silly "disable unused items" problem

    (3) Why did I say "fooling around with the panels" is "not software engineering"

    Because it's just "fooling around", cowboy coding - it's ridiculous. It's not a ready-made solution. Say we were on a big team project. the first step is we'd all have to write a substantial system, home-made code, to swap the 'screens'. That's "just silly" for such a basic need.

    I gave an analogy: it would be as if in iOS they did not at all offer the whole edifice of view controllers and transitions!!! and you just had to build something "home-made" to swap UIViews.

    (Note that in the demo docu, Unity breezily say , I paraphrase humorously, "Since we didn't bother including anything to swap between screens, just roll your own!" They suggest it is only a few lines of code and the example they include is trivial. But it wouldn't fly in the real world. It would be a big project in itself. It would have to be constantly maintained, utilised within a company on all projects, etc etc - the usual with any codebase.)

    {Note to Unity - if it's such a goddy simple, throwaway task, you guys go ahead and spend, what, 10 .. maybe 12 minutes .. and throw it in to UI eh ? :) }

    So there are three solutions: scenes, canvasses or panels. You mention "There is absolutely nothing wrong with using [panel] for different parts of your app...." Well yes, that's fine. It's just this simple: unity needs to supply a built-in "view controller" system. (It has to work on either canvasses or panels; either would be fine.)

    Whether you choose "panels" level or "canvas" level -- you'll have to write the whole "view controller" system your self.

    It's hokey, it's not software engineering, it's ad-hoc, placeholder cowboy coding.

    100.0% of interfaces have multiple 'screens'. Obviously, Unity will have to build it in properly soon enough.

    Hopefully soon!

    I'm in love with UI, nobody's criticising it. Obviously though, they have to put in "view controllers"

    As I point out, the first thing it says in the demo/doco is "oh, look, you'll have to quickly write this yourself!"
     
  6. Senshi

    Senshi

    Joined:
    Oct 3, 2010
    Posts:
    557
    Before continuing, I'd just like to make clear that I'm just debating in a light-heared manner; apologies if anything comes across as attacking or mean-spirited. =)

    For (OO) programming, yes. Creating a GUI like this is fundamentally different though. I feel you may be viewing scenes more like classes, which, while probably valid in some cases, is not how I look at them at all. Encapsulation can be important even outside of coding, but I think we have differing opinions on what that balance looks like. You could encapsulate a game world into different scenes, with one for each town. Or you could encapsulate even further, with one scene for each district, or one scene per building. How you do this is up to you and what makes sense for you and your project.

    To me, the encapsulation happening on the panel-level is enough. And if I have, say, a menu that needs to appear in several scenes, I can use prefabs for that. Little self-contained bundles (panels) that appear within my scenes; that's enough for me.

    With Unity, the most common use-case will most likely be GUIs on top of game scenes. Since each game is different, I think it'd be extremely hard to A) create a one-size-fits-all solution and thus B) provide any meaningful default screen transitions. I can't think of a single "ready-made solution" that works for everyone. The reason this works for iOS is because they have very strict guidelines on how an app should look and feel. You get ready-made transitions because those are the only transitions you're essentially allowed to use.

    I'm not sure why you're calling building uGUIs "cowboy coding"/ ridiculous; it's not even coding at all! If you want you can create your GUI entirely from code of course, but that's just not very practical in most scenarios. Apologies if I misunderstand, but it comes across to me as if you don't like the idea of building GUIs this way?
     
  7. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
    to be fair cocos2d on ios has none of those restrictions and yet has great transition system
     
  8. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
    but i guess they have different ideas of what a scene means since in cocos2d i can change scenes instantly yet in unity free it takes seconds?
     
  9. Senshi

    Senshi

    Joined:
    Oct 3, 2010
    Posts:
    557
    I'm not too familiar with Cocos2D, but I'm guessing there's indeed a pretty big difference there. IIRC Cocos2D also has a dedicated menu type that uGUI does not which it can hook into. These transition effects are fine, but aside from the more standard swipes, they seem pretty gimmicky as well (in the same sense that a clouds or over-the-top bevel effect becomes old real quick). They also look great like this in full screen, but often times your GUI will only be a small part of your entire scene (think "pause menu" with the game in the background). This already makes things a whole lot harder (in part because scenes in Unity contain pretty much everything, whereas I think in Cocos2D you might still have an overarching structure/ class from which you can access each scene/ menu).

    Thinking about it now, I guess one thing that would be nice to have would be easy tweens for UI elements, to still allow a lot of control while also providing an out-of-the-box way of creating transitions.

    I stand by what I said though; it just seems to variable to try and create a plug-n-play type solution for. =)

    (Sidenote: I should give Cocos2D another look sometime!)
     
  10. DanSuperGP

    DanSuperGP

    Joined:
    Apr 7, 2013
    Posts:
    408
    I haven't done that much with the new UI, but I don't think I would use separate scenes, even separate canvasses seems overkill unless you need them to have different world space orientations or as Senshi mentioned, different camera effects. There's no reason to throw more canvasses than you need at the problem because that just bumps up your draw calls for perceivable benefit.

    To avoid the stacking issue, I'd build the different screens as panels, and save them off as prefabs. Then you can delete them from the scene to get them out of the way when you're not using them during design time, and put them back in the hierarchy but disabled when you're working on the transitions and such.

    The place that using multiple canvasses makes sense is if you were going to do something like having different parts of your UI animate in three dimensions, for instance if you wanted a UI panels to swing in from either side of the screen like closing saloon doors. For that kind of animation you would need multiple canvases because rotating individual elements inside a canvass produces weird skewing as everything is intended to remain in the same plane.
     
    Senshi likes this.
  11. Fattie

    Fattie

    Joined:
    Jul 5, 2012
    Posts:
    476
    Hey Sensh!

    "I can't think of a single "ready-made solution" that works for everyone."...

    couldn't be simpler....

    At the moment panels are unusable for the (incredibly trivial) reason that if you have more than one panel ... they stack up on top of each other, in the editor!

    Just TBAC, for me the "panels" concept is totally awesome and wonderful and does everything you need for encapsulation and solves all problems. Sorry if I was not clear on this.

    But they're a non-starter because of the silly "stack up" problem. of course - obviously - Unity should make the origin OF A PANEL -- I mean purely in the editor as a matter of convenience -- free form.

    (For example, trivially, consider just simply a unity 'window', say the "Hierarchy". Of course, obviously, you can move it around the computer screen :) If - stupidly - the project/hierarchy/inspector windows, were, all stuck absolutely on top of each other and could not be moves - we'd all say that was ridiculous and must be fixed!)

    Note as I mentioned, this is, precisely, the "idiotic problem" Apple had for years where "sub" uiviews would stack up in the IB, which was just incredibly silly. (As a work around you would just "move offscreen" or whatever the ones you weren't working on.) (Apple finally fixed the woe with container views, etc.)

    Also just TBC as I mentioned, there IS a workaround in Unity, you have to use a different cam for each panel right. that's a bit silly though

    Also yeah look at it this way

    Simple fact:

    101% of unity UI uses, will have, "multiple screens". EVERY ux in the universe has depth, you start at the top, go down to options, steering, or whatever.

    Quite simply, it's just .. ridiculous .. that Unity didn't entirely and totally include this "concept" somehow.

    101% of projects need this. It would be, literally, as if they left out say "buttons".

    (That's not a good analogy, because only say 70% of UI has buttons (many just show displays, sliders etc), but 101% of UI has "screens" and heirarchy.)

    Again!! Quite simply. The first thing you read, literally, in the Unity demo is "oh, well, we didn't do this, and of course you need it - so here's a quick workaround approach!"
     
  12. mweldon

    mweldon

    Joined:
    Apr 19, 2010
    Posts:
    109
    I have 2 scenes in my game, front end and game. I could just as easily have done it with 1 scene. It might have even been easier. Using a different scene per screen creates extra work for passing data back and forth. It also slows down transitions and prevents any kind if cool animated trantions.

    I have one canvas for all of the 2d ui. I may make a second one for ui in 3d space like floating health bars or text, but I haven't needed to yet. I don't see any benefit to having more canvases. Though if I did, I would always have a separate camera for every canvas. If you have multiple canvases remember that the objects on different canvases cannot interact with each other in any way. This is why I find it helpful to have separate cameras. It reminds me that each canvas is a different universe.

    The way I build screens is each one has an empty container at the top level called "ui_main_menu" for example. This is where I put the Animator and custom Monobehavior with event handlers. This is set to stretch to full screen. Under this is an Image to serve as the background of the screen. I guess you can call it a "panel" but it's really just a RectTransform with an Image to serve as the visual parent container. This is set to the correct position and size how it should appear on the screen. Under this "panel" goes all the controls for this screen/menu/popup/HUD. Then save the whole thing as a prefab and delete it from the scene. When I want to edit it, I add it back to the scene under the UI canvas, make my edits, apply to the prefab and delete from the scene.

    I have not experienced any "idiotic stack up problem" as far as I know.
     
    Last edited: Nov 27, 2014
  13. Senshi

    Senshi

    Joined:
    Oct 3, 2010
    Posts:
    557
    @Fattie I get what you're saying, but in my experience this is often what you want; it's not uncommen to have several levels of panels within one another, all for just one menu. If I understand correctly, the functionality you're missing is that of "views", specifically. Again, this is easier to solve in something like IB because there's only one transition the system needs to take into account. In that regard, the new UI is a lot of more flexible and "free" than IB's, though it does mean it comes with a couple more caveats as well. I wouldn't call the workaround roundabout either, it's just something that needs to be implemented regardless, not unlike an abstract method. ;)
     
  14. Carpe-Denius

    Carpe-Denius

    Joined:
    May 17, 2013
    Posts:
    842
    Can somebody tell me whats wrong with disabling unused objects?
    I have one canvas for my menu, one object per page, subobjects for elements. If you want transitions, you can use a mask on your page-object, or move them via transform.
     
  15. Senshi

    Senshi

    Joined:
    Oct 3, 2010
    Posts:
    557
    This is pretty much how I do it as well. =) Nothing wrong with this approach imho.
     
  16. dakka

    dakka

    Joined:
    Jun 25, 2010
    Posts:
    113
    This would depend on your requirements. After your splash scene, you could setup a single main menu scene that uses 1 canvas, 1 camera, screen space overlay that has multiple panels that show/hide/transform position into that canvas parent. Each panel uses a canvas group for control enable/disable. Move the panels with Mecanim or write a simple UIPanelSwitcher script. This is not out-of-the-box but the UI tools are very flexible.

    I am currently using this approach and it works like a charm.
     
    sfir likes this.
  17. KnightRiderGuy

    KnightRiderGuy

    Joined:
    Nov 23, 2014
    Posts:
    515
    This a problem I have been having in my mostly U.I. canvas project, I have multiple scenes with canvases that often have animated slide in and out panels by request using U.I. graphic buttons.
    Now in my main scene I have a panel I call "Auto Doors" that slides in and has two indicators on it for closed and open, now they alternate between being lighted, fist click on my main interface button slides in the panel and the light alternates between Open being not lighted to lighted where the button closed goes from lighted to unlighted.
    now here is my BIG problem,
    If the door light indicator for open is lighted and I go from scene one to scene 2 and then back to scene one the door indicators are reset...
    How the frack do I make it so it will remember the setting between scene changes?
    Now I have heard about singletons but have very little clue as to how to use them.
    I have tried using the Don't destroy on load but that just seemed to mess up my script and make it not work at all and I ended up having to reimport the script from an older version of my project, (Thank God for backups)!!
     
  18. Duke_Hast_Mich

    Duke_Hast_Mich

    Joined:
    Apr 14, 2017
    Posts:
    1
    Have you considered just having multiple canvases and setting them to world space when in the designer? When in world space they don't 'have to' stack.


    you can have a quick toggle in a script to set them back to active and change them to camera overlay render mode to swap them out.
     

    Attached Files:

  19. liviub

    liviub

    Joined:
    Jul 22, 2018
    Posts:
    1
    Same situation here! I need to mention that I'm a totally beginner. But i will tell you what i plan to do.

    I will definitely go for panels that will cover the entire screen and activate and deactivate them.

    I have a big questions for you:

    What would you do to change the panels?

    A. use setActive function
    B. move the panels in and out of canvas frame

    And why?
     
  20. poojagandhi0911

    poojagandhi0911

    Joined:
    Jan 31, 2020
    Posts:
    5
    @liviub If you are using canvas render mode as Screen space overlay , you have to go with A (use of SetActive function) and if you use it's render mode Screen space camera then you can go with way B (move the panels in and out of canvas frame).