Announcement

Collapse
No announcement yet.

[UMG Tutorial] - Placing Widgets Over Actors In Screenspace

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    [UMG Tutorial] - Placing Widgets Over Actors In Screenspace

    EDIT This tutorial is out of date as of 4.7, now you can just use the WidgetComponent and change the new Space property to "Screen", will do all this work (and more) for you.

    ====================================================

    Matt and I did the support twitch stream yesterday and several people were curious about how you get widgets to appear over actors in the world, but in screen space. NOTE: The widgets are not actually rendered in the world, they're still in the viewport.

    DEVNOTE: I didn't noticed until I finished writing this tutorial that you can't expose on spawn Text variables in 4.5, coming in 4.6 When you get to that part in the tutorial, just replace that with, "Make a function to set the text, or make it public so you can set it after spawning the widget."

    First we need to make a user widget that we want to appear over our actors, mine looks like this:
    Click image for larger version

Name:	TextOver_TextWidget_Designer.jpg
Views:	1
Size:	333.0 KB
ID:	1139736

    I deleted the Canvas, because I don't want absolute layout, I just want something that flows and has a desired size. So I placed a Horizontal box with some text in it. The text block is bound to a Text Variable I placed on my widget class simply called "Text".

    Next, we need some logic for this widget. On construct, we're going to set it's alignment in the viewport to be 0.5, 0.5. When UMG adds items to the viewport, it's constructing a temp canvas to house the widget in. Normally we anchor the widget to fill the entire space, but setting the alignment and position manually lets us position our user widget inside that temporary canvas just like we would in the designer. The Alignment is more or less the normalized pivot point in local space of the widget about which it's positioned. So by setting it to 0.5,0.5, we ensure the horizontal box + text will be centered about whatever position we give it.

    Additionally - each Tick we determine the position of "Ammo Box" which is just a member variable we exposed on spawn for our widget that the Ammo Box actor that will be creating this widget is responsible for setting. We transform that position, plus some offset, to be in screenspace. Then we set the position of our user widget in the viewport, we don't worry about also setting the size, because by default widgets will be their desired size when using absolute position in the viewport.
    Click image for larger version

Name:	TextOver_TextWidget.jpg
Views:	1
Size:	220.1 KB
ID:	1139737

    Ok, now we need our actor to construct our widget. I made a simple ammo crate static mesh blueprint actor, and on his begin play he constructs my AmmoContainerUI widget, assigns himself to the Ammo Box exposed on spawn parameter, as well as a Name Variable, is assigned to the "Text" variable that is also exposed on spawn that our textblock has a binding to. I assign the UI to a variable that the actor keeps track of so that he can remove it from the viewport when it is destroyed.
    Click image for larger version

Name:	TextOver_Spawn.jpg
Views:	1
Size:	111.4 KB
ID:	1139738

    And here's what it looks like when it's running,
    Click image for larger version

Name:	TextOverExample.jpg
Views:	1
Size:	153.1 KB
ID:	1139735

    Cheers,
    Nick
    Attached Files
    Last edited by Nick Darnell; 12-26-2014, 02:06 PM.

    #2
    Sweet, thank you much for this
    Movable Widgets

    Comment


      #3
      hi,
      thank you for this clarification , I think we'll do great things in Unreal 4.6
      Love stylised character..

      Thank

      Comment


        #4
        Hey thanks for this. Very much appreciated!
        https://github.com/iniside/ActionRPGGame - Action RPG Starter kit. Work in Progress. You can use it in whatever way you wish.

        Comment


          #5
          Thanks Nick, I did your tutorial. I got a question, though, how can I put the text location only on top of Actor (like the using UTextRenderComponent then rotate and move them relatively based on Character's camera's and Actor's rotation and location). Right now, The text located fix on the screen even if I rotate away from the Actor.

          Comment


            #6
            Is this method more performant than using a 3D component-based widget? This seems great for drawing on top of everything when necessary but i can't seem to find a way to occlude the text. A 3D component widget seems not only easier to use, but like it would be occluded by objects in front of it. Unless I'm wrong?
            Procedural, modular, on-the-fly animation - iTween For UE4
            - Actors - Components - UMG - Ease In - Ease Out - Path-constrained Animation - $0

            Comment


              #7
              Originally posted by Jared Therriault View Post
              Is this method more performant than using a 3D component-based widget? This seems great for drawing on top of everything when necessary but i can't seem to find a way to occlude the text. A 3D component widget seems not only easier to use, but like it would be occluded by objects in front of it. Unless I'm wrong?
              Yes - much more performant. The Experimental 3D widget currently employs a render target in order to be rendered into the world. So for every one of them, you've got another render target. On top of that, they're in the world. Which means they get all the same post processing everything else does, motion blur, AA shader...etc. so if the camera is moving, don't plan to be able to read it. You are correct about the occlusion though, it's good for making Dead Space styled UI, where the camera is stationary.


              Thanks Nick, I did your tutorial. I got a question, though, how can I put the text location only on top of Actor (like the using UTextRenderComponent then rotate and move them relatively based on Character's camera's and Actor's rotation and location). Right now, The text located fix on the screen even if I rotate away from the Actor.
              You want the text to rotate when the object rotates? That's a bit tricker, you'd need to figure out the render transform to apply to get the same rotation in screen space. I would just use the text component if all you need is text and wanted rotations to be applied.

              Comment


                #8
                Thank you, Nick. I'm excited to figure out different ways to employ this
                Procedural, modular, on-the-fly animation - iTween For UE4
                - Actors - Components - UMG - Ease In - Ease Out - Path-constrained Animation - $0

                Comment


                  #9
                  So unfortunately this method fails when r.ScreenPercentage, or sg.ResolutionQuality are not 100. Any tips to have this align correctly under those circumstances?

                  Comment


                    #10
                    Originally posted by fisj View Post
                    So unfortunately this method fails when r.ScreenPercentage, or sg.ResolutionQuality are not 100. Any tips to have this align correctly under those circumstances?
                    I'm having the same issue! Any workarounds?

                    ----

                    To reproduce, do the following:

                    1) Lower the resolution
                    2) Close & Reopen the project
                    3) Play

                    Edit: This was apparently reported here, under bug report UE-6191.

                    Edit2: By the way, is it possible to occlude these widgets behind other UMG widgets?
                    Last edited by FS Creations; 12-26-2014, 02:06 AM.

                    Comment


                      #11
                      You'd need to get the resolution quality and divide the projected position by the normalized quality.

                      This tutorial is out of date as of 4.7, now you can just use the WidgetComponent and change the new Space property to "Screen".

                      I've just checked in a fix for the quality issue, and extended the capability to control the ZOrder of the widgets added to the viewport, for both the standard BP call, as well as the WidgetComponent. Which will allow you to control what layer they appear on LHutz. Those changes should be in github master soon / 4.8.

                      Comment


                        #12
                        Thanks a lot Nick!

                        Wow, I can't believe how simple this is! There is still the resolution problem but we can wait for 4.8 for that.

                        Thanks!
                        Last edited by FS Creations; 12-26-2014, 09:57 PM.

                        Comment


                          #13
                          This is a great tutorial. I had a perfect way to do this same thing in 4.4 that would parse strings and display them over an actor's head (think SCUMM era dialogue), but with UMG it became obsolete and this method is way (re: WAY) simpler. No math involved!

                          Thanks!

                          Comment


                            #14
                            Thanks for sharing this with us Nick!



                            Rama
                            100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

                            UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

                            Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

                            Comment


                              #15
                              Thanks for the tutorial.
                              There is one interesting thing I run into during recent development.
                              I don't know if here or the answer board would be better place, let me know.

                              1. I finally figure out a way to make class dependent custom context menu, so class A have it's own menu item say a spinbox and class B have a combo box instead.
                              But during this development, I found it's only possible through event dispatcher so that each instance gets to keep their own data and event feed back from the widget.
                              I wonder if there is a better way to implement this in blueprint? So a struct in a blueprint can let a widget blueprint to setup the interactions.
                              My original thought is to use construct to take in a reference and the use a struct from the actor to build dynamic menu(with different widgets), but found it really hard to pass result back to the actor.
                              So at the end I do it reversely to let the actor build and add its own widget and use event dispatcher to bind UI events.

                              2. there doesn't seems to have a mouse scroll events on slider or spinbox widgets. Which seems to be a pretty good interaction method for UI in many softwares, but not in UE4.

                              3. is there anything that we can do to have a proper "text bubble" or "chat bubble" style of pointy widget that point to certain location in screen space?
                              Like the word processor/slide making text bubble that you can drag a yellow dot and the pointy wedge shape will have a good visual reference for player?
                              Unreal Engine 4 Game Framework diagram for relation of all major base object types
                              Unreal Engine 4 Input Event diagram, scroll down to section Input Processing Procedural
                              Resident Evil Classic Camera
                              RPCs official document, Must Read
                              Everything you should know about replication

                              Comment

                              Working...
                              X