Practical usage of BlueprintImplementableEvent in UnrealEngine


two-edged Hot Reload

  • almost everyone uses this fascinating feature, which accelerates one’s development process
  • this feature can make you skip Editor loading, but cannot make you skip CPP compilation
    • in game development using Unreal Engine, most of time is still consumed in CPP compilation
  • even you may miss some of changes or encounter unexpected bugs
    • this means, Hot Reload feature is not the stable one

※ for more information, see the reference #1
※ one of the bugs: https://forums.unrealengine.com/unreal-engine/feedback-for-epic/37624-hot-reload-for-components-is-a-mess-with-the-hotreload-name-bug-at-the-moment

  • then, is there another way to reduce compilation time ?
    • while ensuring not to occur a malfunction ?
  • now it is time to use blueprint more practically

blueprint versus CPP

  • as we know, blueprint is useful enough to work with personal project
    • because there are no merge conflict and no number of context switchings in personal project
  • blueprint usually bullies developers in group project
    • because blueprint asset file is binary, there is no good way to merge them or see them without Editor
  • but blueprint instead has positive aspects in other sides
    • let us summary the pros and cons of blueprint
Item Blueprint CPP
Compilation absolutely fast (do not need to compile CPP) hell it is so slow (if with Engine build, too ? better kill me)
View & Diff must open Unreal Editor (even some changes cannot be shown) can be opened or diffed with common VCS such as git
Merge almost impossible (even need to re-work for rebase) not that different from merging an ordinary text file
Exception Handling warning in best and shutting down Game in worst unless handling, everyting shuts down (Editor, Game…etc)
Debugging can visit all nodes and variables some of codes can be optimized

※ for more information about Compilation item, see the reference #2

  • so, as you saw the table, I want to say that “prototyping with blueprint is quite useful”
  • in this post, I will show you one of tips to use blueprint efficiently
    • it may be faster than development using Hot Reload

BlueprintImplementableEvent

  • blueprint is efficient when it used only for prototyping
    • if you run your project with features implemented with blueprint, there would be much cost:
      • view or diff blueprint asset → time to open Unreal Editor
      • merge blueprint asset → time to open Unreal Editor & re-work the changes
        (+ effort to remember what were the changes)
      • …etc
  • the UFUNCTION specifier BlueprintImplementableEvent
    • is fit in this purpose
    • will help your prototyping with unit of function

※ for more information about BlueprintImplementableEvent specifier, see the reference #3

1
2
3
/// This function is designed to be overridden by a blueprint.  Do not provide a body for this function;
/// the autogenerated code will include a thunk that calls ProcessEvent to execute the overridden body.
BlueprintImplementableEvent
  • at ObjectMacro.h we can find the enum of BlueprintImplementableEvent and its comment
  • the access specifier of function using BlueprintImplementableEvent must not be private
    • which means, it must be public or protected
  • you cannot implement the body of function in cpp
    • you must implement the body of function in blueprint
    • as UBT(unreal build tool) makes an implementation of the BlueprintImplementableEvent function, your cpp implementation causes error

example

  • suppose you want to make a simple feature
    • when the game starts, a widget is shown at the center of screen
    • the widget is kind of textblock, which contains a text like “Hello World !”
  • let us call the function in BeginPlay()
    • when the player controller is created, the NotifyTestFunc() will be executed

  • add a variable for widget
    • create blueprint class of the cpp player controller
    • it can be assigned at the inspector of Class Defaults
  • you can implement the function in Event Graph
    • let us just show a screen debug message
  • prepare game mode
    • set the game mode, character and player controller as ours
  • screen debug message is shown well
  • now let us show the widget
  • create a widget and add it to viewport
  • what happened ? I cannot see any widget
  • let us see the Message Log
  • the log says, there is access to None at Add to Viewport node
    • add breakpoint at the node and find why
  • absolutely this could be a crash in cpp code
    • with blueprint, we can keep going unless shuting down the editor

  • oh, the Target is None
    • that is why the message log is created
  • as we did not assign the class of widget, Create User Widget node returned None
  • let us create a widget and assign it


  • now it works !
    • almost work is written with blueprint and there is only one cpp compilation
    • this development process can improve your productivity
  • the rest of work is converting the blueprint things into cpp code

wrap-up

  • Hot Reload is fast enough to develop personal project
    • if you do not take much time to compile cpp, there is no significant benefits to using blueprint
    • time to compile cpp can be similar much than blueprint one
  • blueprint using BlueprintImplementableEvent is useful
    • if it takes more than 5~10 minutes whenever cpp compiles, you should consider blueprint
    • but, you need to convert blueprint into cpp when it completes
  • as a result, the workflow I recommend you is:
    • design a feature as one function with BlueprintImplementableEvent
    • implement the function with blueprint
    • remove blueprint implementation & implement the function with cpp