Successfully reported this slideshow.

Plug-ins & Third-Party SDKs in UE4

9

Share

1 of 75
1 of 75

More Related Content

Related Books

Free with a 14 day trial from Scribd

See all

Related Audiobooks

Free with a 14 day trial from Scribd

See all

Plug-ins & Third-Party SDKs in UE4

  1. 1. Plug-ins & Third-Party SDKs in UE4 Yes, there will be funny cats, too Gerke Max Preussner max.preussner@epicgames.com @gmpreussner
  2. 2. Funny cat videos have been removed to keep these slides at a reasonable download size. You can find those videos (and many more) at https://www.reddit.com/r/thecatdimension/
  3. 3. The Basics Modules Plug-ins Projects Modules Overview •Two methods to implement features in UE4: Blueprint & C++ •Most projects use a combination of both •All C++ code resides in modules •Modules bundle type declarations and implementations •Each module has a particular purpose or responsibility •Most modules are generic and reusable •UE4 ships with hundred of modules •Can be compiled into DLLs or static libs
  4. 4. The Basics Modules Plug-ins Projects Module Types •Developer – for development only •Editor – for Unreal Editor only •Runtime – for anything •Programs – for standalone programs •Third Party – for external code & libs Note: The UE4 EULA prohibits inclusion of Editor modules in shipping games
  5. 5. The Basics Modules Plug-ins Projects Structure of Modules •Private folder • Internal implementation • Module initialization • Pre-compiled header •Public folder • Interfaces • Exported Types •Build.cs file https://github.com/ue4plugins/NdiMedia
  6. 6. The Basics Modules Plug-ins Projects Structure of Modules •Private folder • Internal implementation • Module initialization • Pre-compiled header •Public folder • Interfaces • Exported Types •Build.cs file https://github.com/ue4plugins/NdiMedia
  7. 7. The Basics Modules Plug-ins Projects Structure of Modules •Private folder • Internal implementation • Module initialization • Pre-compiled header •Public folder • Interfaces • Exported Types •Build.cs file https://github.com/ue4plugins/NdiMedia
  8. 8. The Basics Modules Plug-ins Projects Module initialization
  9. 9. The Basics Modules Plug-ins Projects Module initialization
  10. 10. The Basics Modules Plug-ins Projects Structure of Modules •Private folder • Internal implementation • Module initialization • Pre-compiled header •Public folder • Interfaces • Exported Types •Build.cs file https://github.com/ue4plugins/NdiMedia
  11. 11. The Basics Modules Plug-ins Projects Pre-compiled Headers
  12. 12. The Basics Modules Plug-ins Projects Pre-compiled Headers
  13. 13. The Basics Modules Plug-ins Projects Pre-compiled Headers
  14. 14. The Basics Modules Plug-ins Projects Structure of Modules •Private folder • Internal implementation • Module initialization • Pre-compiled header •Public folder • Interfaces • Exported Types •Build.cs file https://github.com/ue4plugins/NdiMedia
  15. 15. The Basics Modules Plug-ins Projects Structure of Modules •Private folder • Internal implementation • Module initialization • Pre-compiled header •Public folder • Interfaces • Exported Types •Build.cs file https://github.com/ue4plugins/NdiMedia
  16. 16. https://github.com/ue4plugins/NdiMedia Structure of Modules The Basics Modules Plug-ins Projects
  17. 17. The Basics Modules Plug-ins Projects Structure of Modules •Private folder • Internal implementation • Module initialization • Pre-compiled header •Public folder • Interfaces • Exported Types •Build rules https://github.com/ue4plugins/NdiMedia
  18. 18. The Basics Modules Plug-ins Projects Build Rules
  19. 19. The Basics Modules Plug-ins Projects Build Rules
  20. 20. The Basics Modules Plug-ins Projects PrivateIncludePaths •Sub-folders inside your module’s Private folder PublicIncludePaths •Sub-folders inside your module’s Public folder (not needed) PrivateIncludePathModuleNames •Modules whose public headers your module’s private implementation includes, but doesn’t link to PublicIncludePathModuleNames •Modules whose public headers your module’s public interface includes, but doesn’t link to
  21. 21. The Basics Modules Plug-ins Projects PrivateDependencyModuleNames •Modules that your module’s private implementation requires for compiling and linking PublicDependencyModuleNames •Modules that your module’s public interface requires for compiling and linking DynamicallyLoadedModuleNames •Modules that are loaded at run-time via ModuleManager (this is to ensure that they get compiled) More options in RulesCompiler.cs
  22. 22. 1 2 3
  23. 23. The Basics Modules Plug-ins Projects Structure of Plug-ins •One or more modules •Plug-in descriptor •Content (optional) •Resources (optional) Configuration files for plug-ins are not yet supported, so any settings should be stored in Engine or project INI files (set default values in constructors) https://github.com/ue4plugins/NdiMedia
  24. 24. The Basics Modules Plug-ins Projects Structure of Plug-ins •One or more modules •Plug-in descriptor •Content (optional) •Resources (optional) https://github.com/ue4plugins/NdiMedia
  25. 25. The Basics Modules Plug-ins Projects Structure of Plug-ins •One or more modules •Plug-in descriptor •Content (optional) •Resources (optional) https://github.com/ue4plugins/NdiMedia
  26. 26. The Basics Modules Plug-ins Projects Plug-in Descriptor •Json file {PluginName.uplugin} •Inside root of plug-in directory •Contains: • Version information • User friendly description • Module loading rules https://github.com/ue4plugins/NdiMedia
  27. 27. The Basics Modules Plug-ins Projects Plug-in Descriptor
  28. 28. The Basics Modules Plug-ins Projects Plug-in Descriptor
  29. 29. The Basics Modules Plug-ins Projects Plug-in Descriptor
  30. 30. The Basics Modules Plug-ins Projects Plug-in Descriptor
  31. 31. The Basics Modules Plug-ins Projects Plug-in Descriptor 1
  32. 32. The Basics Modules Plug-ins Projects Plug-in Descriptor 1
  33. 33. The Basics Modules Plug-ins Projects Plug-in Descriptor 1
  34. 34. The Basics Modules Plug-ins Projects Plug-in Descriptor 1
  35. 35. The Basics Structure of Projects •Configuration files •Content (optional) •Plug-ins (optional) •Modules (optional) •Target Rules •Project descriptor Modules Plug-ins Projects
  36. 36. The Basics Modules Plug-ins Projects Project Descriptor
  37. 37. The Basics Modules Plug-ins Projects Project Generation •UBT searches entire solution for *.Build.cs files •GenerateProjectFiles.bat invokes UBT to generate Visual Studio solution files containing all modules
  38. 38. The Basics Modules Plug-ins Projects Project Compilation •Visual Studio invokes UBT to... • find all *.Build.cs files • compile and instantiate them • create a module dependency graph • generate compiler and linker settings • compile all C++ modules •A module is compiled if it is... • a dependency of another module • required by an enabled plug-in, or the project itself
  39. 39. Third-Party Libraries Engine Plug-ins UPL Platforms Distribution
  40. 40. Third-Party Libraries Engine Plug-ins UPL Platforms Distribution Structure of Engine Dependencies •Located in /Engine/Source/ThirdParty •Each has its own Build.cs file • Just like any other module • Public includes (for headers to be compiled into dependent modules) • Public libraries (for libraries to be linked into dependent modules) • Optional pre-processor definitions
  41. 41. Third-Party Libraries Engine Plug-ins UPL Platforms Distribution Building Engine Dependencies •Source code is often included, but… • We provide pre-compiled libs for everything • UBT never compiles them when building your projects •Internally, we pre-compile the libraries using… • BuildThirdPartyLibs UAT script (automated) • Batch files and shell scripts (manual) • Specialized UAT scripts (i.e. for PhysX) •Sometimes there are text files with instructions
  42. 42. Third-Party Libraries Engine Plug-ins Platforms UPL Distribution More Build Rules
  43. 43. Third-Party Libraries PublicLibraryPaths •Paths to folders containing additional libraries PublicAdditionalLibraries •Additional libraries (.lib or .a files) to link against PublicFrameworks •Additional XCode frameworks (iOS, macOS only) PublicWeakFrameworks •Weak frameworks (for OS transition) Engine Plug-ins Platforms UPL Distribution
  44. 44. Third-Party Libraries PublicAdditionalShadowFiles •Files that need to be copied for remote compilation RuntimeDependencies •Runtime dependencies to be staged for a packaged build Engine Plug-ins Platforms UPL Distribution
  45. 45. Third-Party Libraries Engine Plug-ins Platforms UPL Distribution Structure of Plug-in Dependencies •Same as Engine third-party dependencies •Same build rules
  46. 46. Third-Party Libraries Engine Plug-ins Platforms UPL Distribution Linux: Building libs that require STL •Use our bundled libc++ (offers most independence, because then your plug-in works wherever UE4 works) •Modules built within UE4 are automatically linked with libc++ •We support CentOS 7 and newer (4.14) and CentOS 6 (4.13) •We don’t target any particular version of Ubuntu •Most other Linux versions should also be covered
  47. 47. Third-Party Libraries Engine Plug-ins Platforms UPL Distribution Linux: Locating Libs at Runtime • On macOS we update RPATH via RuntimeDependencies •On Linux you have to hack LinuxToolchain.cs  •Or use FPlatformProcess::GetDllHandle •At some point we will fix this On Linux we always use weak symbol resolution by default!
  48. 48. Third-Party Libraries Engine Plug-ins Platforms UPL Distribution Android • One lib subfolder per architecture • You list all of them in the Build.cs • Tool chain filters out unused architectures
  49. 49. Third-Party Libraries Engine Plug-ins UPL Platforms Distribution Unreal Plug-in Language • Used to be Android Plug-in Language (APL) • XML based scripting system for building UE4 plug-ins • Interpreter implemented in UnrealPluginLanguage.cs •Can be used for iOS as well (for modifying Plists) •Other platforms not implemented yet •Often used for: • Staging additional files • Stripping out files • Injecting Java code
  50. 50. GearVR_APL.xml
  51. 51. GearVR_APL.xml
  52. 52. GearVR_APL.xml
  53. 53. GearVR_APL.xml
  54. 54. GearVR_APL.xml
  55. 55. GearVR_APL.xml
  56. 56. GearVR_APL.xml
  57. 57. Third-Party Libraries Engine Plug-ins Platforms UPL Distribution Marketplace Submissions •http://publish.unrealengine.com/welcome Our current web form sucks a little, so we’ll communicate with you over email, too.
  58. 58. Third-Party Libraries Engine Plug-ins Platforms UPL Distribution Submission Audit •Plug-in / project descriptor files must be complete •Payment information must be correct •Automated test builds for all platforms & versions •Basic code review & light runtime testing •Virus scan We don’t enforce UE4 coding guidelines, but we look for common bad practices that may break in the future.
  59. 59. Third-Party Libraries Engine Plug-ins Platforms UPL Distribution Third-party Libs (permissive license) •Can be included with submission •Must provide web links to library origin •Must include license copies Third-party Libs (non-permissive license) •Must be a separate download from the vendor •Must include instructions on how to install
  60. 60. Third-Party Libraries Engine Plug-ins Platforms UPL Distribution What else? •Plug-ins will be installed in /Engine/Plugins •We include pre-compiled binaries for all supported platforms •We include source code, so they can be used in custom UE4 • You can put your secret sauce into static libraries •You must resubmit for every new UE4 version
  61. 61. Case Studies LogiLed VlcMedia GearVR https://github.com/ue4plugins/LogiLed
  62. 62. Case Studies LogiLed VlcMedia GearVR
  63. 63. Case Studies LogiLed VlcMedia GearVR
  64. 64. Case Studies LogiLed VlcMedia GearVR https://github.com/ue4plugins/VlcMedia
  65. 65. VlcMedia.Build.cs
  66. 66. Vlc.cpp
  67. 67. Vlc.cpp
  68. 68. Case Studies LogiLed VlcMedia GearVR GearVR_APL.xml
  69. 69. Case Studies LogiLed VlcMedia GearVR Java Code Injection via UPL GearVR_APL.xml
  70. 70. Case Studies LogiLed VlcMedia GearVR GameActivity.java
  71. 71. Case Studies UEDeployAndroid.cs
  72. 72. Questions? Documentation, Tutorials and Help at: • Answer Hub: • Documentation: • Forums: • Issue Tracker: • Wiki: • UE4 Road Map • YouTube Tutorials: • Community Discord: • Community IRC: https://answers.unrealengine.com https://docs.unrealengine.com https://forums.unrealengine.com https://issues.unrealengine.com https://wiki.unrealengine.com https://trello.com/b/gHooNW9I/ue4-roadmap https://www.youtube.com/user/UnrealDevelopmentKit http://unrealslackers.org #unrealengine on FreeNode

Editor's Notes

  • *** Prepared and presented by Gerke Max Preussner for MIGS 2016, November 15th
  • UE4 provides two methods to implement new features: Blueprint (our visual programming interface) and C++.
    Most projects use a combination of both, and Blueprint and C++ can interact with each quite easily. It is also possible to implement a game entire in Blueprint, or entirely in C++. This presentation will focus on C++.
    All C++ code resides in modules. You can think of these as packages or libraries that bundle types and functions together.
    In earlier versions of Unreal Engine all the code was split into a few DLLs, which lead to a lot of very tightly coupled code that was difficult to maintain and extend.
    In UE4 we refactored most of this code into hundreds of small modules, each of which has a particular purpose that can be reused more easily.
    Depending on the platform and type of application, modules can be compiled into static libraries (monolithic builds) or DLLs (non-monolithic builds).
  • Because there are so many modules in UE4, we decided to logically organize them depending on how and where they are meant to be used.
    For example, modules that are to be used exclusively in Unreal Editor and not in any game or project are referred to as ‘Editor’ modules.
    We also have a number of modules that implement standalone programs and tools.
    Runtime modules are the most numerous as they form the foundation for all games, programs, and Unreal Editor.
    Other modules are used exclusively to integrate code and libraries from other third-party vendors. At these we will look in more detail later.
  • Modules can be found in various locations of the Engine code base, but they all have more or less the same structure.
    For most modules there’s a Private and Public folder, as well as a Build.cs file.
  • The Private folder contains all the module’s implementation details that should not be accessible by other modules.
  • Each module is required to implement special initialization code that is executed each time the module is loaded or unloaded.
  • This is easily accomplished by writing a class that implements the IModuleInterface interface.
  • The IMPLEMENT_MODULE macro generates the module registration and other boilerplate code.
    The module initialization file is also a good place to define other things that are used throughout your module, such as log categories.
  • All modules in UE4 are also expected to use a pre-compiled header file.
    This header must be the first include file in any of your module’s .cpp files.
    UBT will warn during compilation if you fail to do this.
  • There are no official guidelines on what should go into the pre-compiled header.
    Personally I found it most useful to include all external header files from other modules or third-party SDKs that the module uses.
    We generally use unique file names for all headers in the Engine, but there are a few exceptions.
    For this reason, I always specify the full include path relative to the Engine’s “Source” directory.
  • It is not strictly required to include Core.h as it should always be included by UBT.
    For consistency, I include it anyway.
  • It is also possible to use relative include paths.
    This is useful when including shared headers from neighboring modules inside of plug-ins.
  • The module’s Public folder contains everything that should be accessible by other modules.
    This typically includes C++ interface declarations…
  • … as well as exported types and functions.
  • Pure interface declarations can be used by other modules by simply including your module’s public header files.
    If your module implements functions or class methods, these need to be exported, and other modules have to not include the headers, but also link against your module.
    Exporting types is easy: we have a macro that is automatically generated for each module ({MODULENAME}_API).
  • The most important part of a module is the module build rules file (*.Build.cs)
    It tells UBT how the module is to be compiled, which modules it depends on for compiling and linking, and many other build options.
  • Module build rules are written in C#.
    UBT automatically locates all build rules, and compiles and executes them in order to generate the command lines for the compiler and linker.
  • The build rules are mostly configured via built-in properties.
    There are many options available for rules compiler, and I quickly want to go over some of the most important ones, because almost everyone gets them wrong (and by that I mean most programmers at Epic, too!).
  • For efficiency reasons, UBT does not automatically discover sub-folders in your module’s Private directory. If you have any private sub-folders, you need to add them to PrivateIncludePaths.
    PublicIncludePaths is currently not needed, because UBT discovers public sub-folders automatically.
    If your module’s private implementation includes public headers from another module, but does not link against that module (this usually happens when including only interface headers), then you must list that module in PrivateIncludePathModuleNames.
    If your module’s public interface uses types from another module’s public interface, but does not need to link against it, then you must list that module in PublicIncludePathModuleNames.
  • If your module includes public headers from another module and also has to link against that module, then you can list that module in PrivateDependencyModuleNames and PublicDependencyModuleNames respectively.
    Finally, if your module does not depend on another module at compile or link time, but loads it at run-time, then we must tell UBT to compile that module anyway by adding it to the DynamicallyLoadedModuleNames array. This setting is often used in combination with PrivateIncludePathModuleNames.
    It is important that you completely understand these options. I often see that module dependencies are over-specified in order to “make things work” without really knowing what that means.
    I also often see that dependencies are underspecified, and the code compiles, links and runs successfully only by accident, and it may break later if someone changes dependencies in some other, completely unrelated module.
    You are responsible for ensuring that your module specifies its dependencies correctly.
  • One easy way to create a new plug-in in three simple steps is to use the Plug-in Wizard in Unreal Editor.
    You can reach it via the Plugin Manager from the main menu.
    However, I generally prefer to just copy the relevant files from an existing plug-in and do a find and replace of the plug-in name in files and file names.
  • Plug-ins are really just a collection of one or more modules bundled together with a descriptor file for easy redistribution.
    Plug-ins can reside in /Engine/Plugins (so called Engine plug-ins), or /MyProject/Plugins (so called project plug-ins). There is no functional difference, except that project plug-ins will only be accessible within a particular project, while Engine plug-ins can be used by all projects.
    If your plug-in is project specific, put it inside the project. Otherwise put it inside the Engine.
  • A plug-in’s C++ modules are located inside its Source sub-directory (just like Engine, project, or program modules).
    You can see in the picture that one of the three modules in the NdiMedia plug-in is actually the module we looked at a few minutes ago.
    There are no surprises here.
  • The only new addition is the plug-in descriptor, which resides in the plug-in’s root directory.
  • The plug-in descriptor is stored as a JSON file with the file extension .uplugin.
    It must have the same name as the plug-in itself.
  • And this is what a plug-in descriptor file looks like.
    It stores version information, user friendly descriptions, and – most importantly – module loading rules.
  • As you can see, most of the information is used to display details about the plug-in in the Editor’s plug-in manager UI.
  • However, the “Modules” section is used by the Engine to determine which modules of a plug-in are loaded and when.
    Let’s take a closer look..
  • Each of the plug-in’s modules may have an entry in this section.
    If it is listed here, the Engine will try to automatically load the module on startup.
  • The “Name” field must match the name of the module that should be loaded.
  • The “Type” specifies under what circumstances the module is loaded. For example, “Runtime” means that the module should be loaded pretty much anywhere, including in the Engine, the Editor, games, and standalone programs. “RuntimeNoCommandlet” means that the module should be loaded anywhere, except in commandlets. “Editor” means, as you can guess, that the module should be loaded only in the Editor, but not in games or other programs.
  • There are also different loading phases that determine when exactly in the startup phase the module should be loaded. This can be used to ensure that certain Engine dependencies are loaded before your plug-in loads, or to control the loading order between a plug-in’s modules.
  • Last but not least, you can also blacklist and whitelist specific platforms for each module.
  • Projects are the self-contained units that hold all the content (and optional code) that make up your games.
    Code projects usually include one or more C++ modules. They may also contain plug-ins.
    The “Source” directory of projects contains target build rules that are unique to projects.
    A target is an executable to be built by UBT, and the target rules describe which modules are to be included.
    Similar to plug-ins, projects also have a descriptor file.
  • Project descriptors are similar to plug-in descriptors in that they are also JSON files describing the project, as well as loading rules for its modules.
  • Whenever you add modules or plug-ins to your UE4 solution, you should run the GenerateProjectFiles.bat batch file, regenerate projects from within the Editor, or hit the re-generate project files button in the UnrealVS Visual Studio plug-in.
    UBT will then search the entire solution directory for Build.cs files and generate a new Visual Studio solution file.
    On macOS we generate Xcode project files.
  • When compiling your project, UBT will locate all Build.cs files, compile them, create a dependency graph, generate compiler and linker settings, and then compile all C++ modules.
    Modules are only compiled if they’re referenced somewhere, i.e. if it is listed in a project or plug-in descriptor, or if another module depends on it.
  • Before we look at how to include third-party SDKs in plug-ins, I’d like to show you how we treat third-party dependencies in the Engine in general.
    UE4 already includes a large number of dependencies.
    If your project requires any of these, we recommend that you use the ones shipping with UE4, because then you can rest assured that they will work on all supported platforms.
  • All third-party libraries are located in the /Engine/Source/ThirdParty directory.
    Just like regular modules, they have their own Build.cs files. These specify public header files to be compiled into dependent modules, as well as public libraries to be linked into dependent modules.
    Some third-party modules may also declare pre-processor definitions, for example for platform specific switches that can be used in your C++ code.
  • We include source code for most third-party modules, but we don’t compile it when building UE4.
    Instead we provide pre-compiled libraries for all supported platforms, so you don’t have to deal with that.
    Internally, we use automated and manual ways to compile third-party dependencies.
    For some dependencies that are particularly complicated, we even have specialized UAT scripts.
  • If you’re curious how this works, you can find all UAT scripts in the /Programs/Automation directory of the UE4 solution.
    The BuildThirdPartyLibs scripts, for example, will locate all UE4_BuildThirdPartyLib.bat batch files and execute them.
  • In the Automation folder you can also find the special build script for PhysX that I mentioned.
  • When we talked about modules, I showed you various build rules for specifying dependencies to other modules.
    Some of these are also used to specify additional include directories for third-party SDKs
    In addition to that, we also have a set of build rules to specify additional SDK library dependencies for linking.
  • The PublicLibraryPaths property allows you to specify additional directories to be searched for libraries by the linker.
    The actual libraries (usually .lib or .a files) to be linked are specified using the PublicAdditionalLibraries property.
    There are also some platform specific build rule properties, for example for adding Xcode frameworks on macOS and iOS.
  • If you use remote compilation, for example when compiling for macOS from Visual Studio on a Windows computer, the remote machine performing the compilation may need additional tools or files that have to be copied from your PC.
    These can be specified using the PublicAdditionalShadowFiles property.
    Lastly, after successfully compiling and linking your libraries, you also need to tell UBT which DLLs or other files have to be included in the packaged build.
    If you don’t do this, then those required files will be missing, and while your game works fine on your own PC, it may not work on anybody else’s device.
  • Third-party dependencies for plug-ins are usually placed into a “ThirdParty” folder inside the plug-in’s root directory, but this is not required.
    Everything I have shown you about Engine third-party dependencies also applies to Plug-in third-party dependencies.
  • On some platforms you may have to consider additional things when including third-party dependencies.
    On Linux, for example, we highly recommend that you link against our bundled libc++ standard library, because that will insure that your plug-in works everywhere UE4 works.
    All modules that are part of a UE4 solution are already linked against our libc++, so this only applies if you’re compiling other libraries yourself outside of the UE4 solution.
    Starting with 4.14, we support CentOS 7. We do not target any specific Ubuntu version, but since we bundle the C++ standard library, everything should work on most Linux distributions.
  • One thing to keep in mind on Linux is that we currently do not have a convenient to add look-up paths for runtime libraries.
    The best option is to manually load your libraries via GetDllHandle (= UE4’s dlopen() equivalent) before starting to call functions from your imported library.
    This is possible, because we use weak symbol resolution on Linux by default, which means that your imported symbols won’t be looked up until you use them for the first time.
    Another, somewhat hacky solution is to modify the RPATH settings in LinuxToolchain.cs
    On macOS we are already able to automatically generate RPATH from the RuntimeDependencies property that I have shown you earlier.
    We are hoping to make this work soon for Linux as well.
  • On the Android target platform things can get more complicated, because there are many possible architectures to support.
    UBT expects that you have library sub-folders for each supported architecture, such as ARM64 or x64.
    It does not matter where exactly these directories are located, but they have to have the same name as the architecture.
    In your module’s *.Build.cs file you actually specify the library dependencies for ALL architectures at once.
    Depending on which architecture you’re compiling for, UBT will later automatically filter out the unnecessary dependencies based on the sub-folder’s name.
    For example, if you’re compiling only for ARM64, then the dependencies containing “x64” or “ARMv7” will be ignored by UBT.
  • Android is presenting additional challenges during compilation and packaging, because it involves extra steps and tools.
    Because UBT is not aware of these Android specific requirements, and because the build rules can get quite complicated, we actually developed an XML based scripting language to deal with this.
    UPL was originally called Android Plug-in Language (APL), but it can now also be used for other platforms.
    Besides Android, it is currently also used for iOS (to modify .plist files).
    In the UE4 code you may still find references to both APL and UPL – they are the same thing.
    On Android in particular, UPL is generally used to inject Java code, and to add or remove files to/from Android packages.
  • Here is an excerpt of the UPL script for the GearVR plug-in.
    As you can see, it is all XML code.
  • Each UPL script runs in its own context, i.e. <init> in GoogleVR and <init> in GearVR won’t collide.
  • You can declare and assign variables.
    These variables will be visible throughout the rest of the section and any subsequent section.
  • There are some XML tags that provide shortcuts to common logic, such as conditional code for specific target architectures.
  • You can also declare regular conditional code.
  • It’s also possible to read configuration values from INI files.
  • <init> is not the only section. There are many others. The platform specific implementation of UPL determines which sections are available.
    Sections are evaluated sequentially.
  • Now, let’s quickly take a look at how you get your plug-in onto the UE4 Marketplace.
    All the steps required for submission are described on our web site.
    We have a web form where you can submit all your files, but it’s not that great yet.
    Until we improved it, a lot of the communication with you will also take place via email.
  • After you submitted your project or plug-in, we will audit it.
    We will make sure that all the information you provided is correct.
    We will also do some basic code review and functional testing.
    However, we don’t enforce UE4 coding guidelines.
  • When your submission requires third-party libraries, you may only include those that have a permissive license.
    Non-permissive dependencies have to be kept as a separate download for the user.
  • When users download your plug-ins from the UE4 Marketplace, they will be installed as Engine plug-ins.
    We include pre-compiled binaries for all supported platforms, as well as the source code.
    However, only the source code to compile and link the plug-in into UE4 is required. You can keep your secret intellectual property inside of static libraries for which you do not have to provide source code.
    Lastly, we do not automatically check whether your plug-in still works in future versions of UE4. You have to resubmit your work for every version you wish to support.
  • Now that you know the basics about integrating third-party dependencies into your projects and plug-ins, let’s take a look at a few examples.
    For the purpose of this presentation I created a plug-in (called LogLed) that integrates the Logitech LED SDK for driving illuminated keyboards and mice.
    Zak will show you later how to build a small game around it using UE4 Blueprints.
    The plug-in can be found on GitHub (https://github.com/ue4plugins/LogiLed).
    By the way, the https://github.com/ue4plugins/ GitHub depot contains some other interesting plug-ins as well.
    We use it as a place for experimental plug-ins that we do not want to include with UE4.
  • The Logitech SDK is very straightforward, so that the LogiLed plug-in is extremely simple as well.
    The first half of the module build rules define our Engine module dependencies and private include directories.
    If we’re building the Editor, then we also include the UnrealEd module, so that we can enable some Editor specific features (i.e. PIE support) in the plug-in.
  • The second half the build rules define the third-party library dependencies.
    Since we only support Windows and simply link against a .lib file to import the DLL functions, there aren’t any big surprise here.
    First we try to figure out the path to the ThirdParty directory, then we add the path to the include files, and finally the path and names of the libraries to link against.
  • VlcMedia is another experimental plug-in on GitHub that implements a Media Framework player using the VideoLAN codec.
  • Here, things are a little more complicated.
    Instead of linking against a static .lib to import the DLL functions, I decided to look up all function imports at runtime.
    As a result, the build rules only define which DLL files are to be included in the packaged build via the RuntimeDepdencies property.
    All the rest happens in the C++ code.
  • Here’s an excerpt of the C++ code that imports the DLL function pointers.
    Note that we’re first determining the path to the DLLs and then manually loading them.
  • Further down in the code, we can then import the functions exported by the VLC libraries.
    The VLC_IMPORT is a local macro that makes this a little bit more convenient (implementation not shown here).
  • The GearVR plug-in makes extensive use of Unreal Plug-in Language (UPL).
    Here you can see the UPL file (still called “APL” for historic reasons) being added to the receipt, which will cause it to be executed during the build.
    On Android, receipt files contain everything about a target being built.
  • There are some interesting things happening in the UPL file – injection of Java code, for example.
  • How does the Java code get injected into the correct location of the GameActivity.java file?
    UPL actually parses the java file for special insertion tags that start with //$$
    It replaces the text with the one from the XML file and saves it to an output file, which gets built.
  • If you’re curious, you can find the replace logic in UEDeployAndroid.cs, which also implements the other Android specific UPL sections.
  • Here is another section of the same UPL file that copies additional resource files into the Android package.
    At the bottom we are removing signature files when making a Shipping build.
  • With that I would like to conclude this talk.
    Make sure to check out our extensive materials on the internet, all of which are available for free.
    Are there any questions I can answer right now?
  • ×