Drawing using Canvas

Canvas is a continuation of the simple HUD implemented within Unreal 3. While it isn't so commonly used within shipping games, mostly being replaced by Slate/UMG, it's simple to use, especially when you want to draw text or shapes to the screen. Canvas drawing is still used extensively by console commands used for debugging and performance analysis such as the stat game and other stat commands. Refer to Chapter 8, Integrating C++ and the Unreal Editor, for the recipe for creating your own console commands.

How to do it...

  1. Open your <Module>.build.cs file, and uncomment/add the following line:
    PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
  2. Create a new GameMode called CustomHUDGameMode using the editor class wizard. Refer to Chapter 4, Actors and Components, if you need a refresher on doing this.
  3. Add a constructor to the class:
    ACustomHUDGameMode();
  4. Add the following to the constructor implementation:
    ACustomHUDGameMode::ACustomHUDGameMode()
    :AGameMode()
    {
      HUDClass = ACustomHUD::StaticClass();
    }
  5. Create a new HUD subclass called CustomHUD, again using the wizard.
  6. Add the override keyword to the following function:
    public:
    virtual void DrawHUD() override;
  7. Now implement the function:
    voidACustomHUD::DrawHUD()
    {
      Super::DrawHUD();
      Canvas->DrawText(GEngine->GetSmallFont(), TEXT("Test string to be printed to screen"), 10, 10);
      FCanvasBoxItemProgressBar(FVector2D(5, 25), FVector2D(100, 5));
      Canvas->DrawItem(ProgressBar);
      DrawRect(FLinearColor::Blue, 5, 25, 100, 5);
    }
  8. Compile your code, and launch the editor.
  9. Within the editor, open the World Settings panel from the Settings drop-down menu:
    How to do it...
  10. In the World Settings dialog, select CustomHUDGameMode from the list under GameMode Override:
    How to do it...
  11. Play and verify that your custom HUD is drawing to the screen:
    How to do it...

How it works...

  1. All the UI recipes here will be using Slate for drawing, so we need to add a dependency between our module and the Slate framework so that we can access the classes declared in that module.
  2. The best place to put custom Canvas draw calls for a game HUD is inside a subclass of AHUD.
  3. In order to tell the engine to use our custom subclass, though, we need to create a new GameMode, and specify the type of our custom class.
  4. Within the constructor of our custom Game Mode, we assign the UClass for our new HUD type to the HUDClass variable. This UClass is passed onto each player controller as they spawn in, and the controller is then responsible for the AHUD instance that it creates.
  5. With our custom GameMode loading our custom HUD, we need to actually create the said custom HUD class.
  6. AHUD defines a virtual function called DrawHUD(), which is invoked in every frame to allow us to draw elements to the screen.
  7. As a result, we override that function, and perform our drawing inside the implementation.
  8. The first method used is as follows:
    floatDrawText(constUFont* InFont, constFString&InText, float X, float Y, float XScale = 1.f, float YScale = 1.f, constFFontRenderInfo&RenderInfo = FFontRenderInfo());
  9. DrawText requires a font to draw with. The default font used by stat and other HUD drawing commands in the engine code is actually stored in the GEngine class, and can be accessed by using the GetSmallFont function, which returns an instance of the UFont as a pointer.
  10. The remaining arguments that we are use are the actual text that should be rendered, as well as the offset, in pixels, at which the text should be drawn.
  11. DrawText is a function that allows you to directly pass in the data that is to be displayed.
  12. The general DrawItem function is a Visitor implementation that allows you to create an object that encapsulates the information about the object to be drawn and reuse that object on multiple draw calls.
  13. In this recipe, we create an element that can be used to represent a progress bar. We encapsulate the required information regarding the width and height of our box into an FCanvasBoxItem, which we then pass to the DrawItem function on our Canvas.
  14. The third item that we draw is a filled rectangle. This function uses convenience methods defined in the HUD class rather than on the Canvas itself. The filled rectangle is placed at the same location as our FCanvasBox so that it can represent the current value inside the progress bar.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.156.35