RickLamb / UELibApp

Unreal Game as a Shared Library example app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unreal Game as a Shared Library (UELibrary) for Unreal 5.2

I've spent a lot of time figuring our how to set up UELibrary for my custom project. The official documentation is helpful but unfortunately incomplete. I've compiled all of my findings in one post + added an example on how you can extend the base API.

UELibrary Setup

Our goal is to build a game as a shared .dll library that we can use in an external Win32 application.

Follow the following steps:

  1. Clone the Unreal Engine source code.

  2. Find this line of code in SlateApplication.cpp and remove it:

    // If we are embedded inside another app then we never need to be "active"
    bAppIsActive = !GUELibraryOverrideSettings.bIsEmbedded;

    This will fix the mouse bug.

  3. (Optional) Find this line of code in DesktopPlatformBase.cpp and replace it:

    // Append any other options
    Arguments += " -Progress -NoEngineChanges -NoHotReloadFromIDE";

    with this line:

    // Append any other options
    Arguments += " -Progress";

    This will solve the "Engine modules are out of date" error when you open your projects in a custom built UnrealEditor.

  4. Compile the Unreal Engine source code. Run Setup.bat, GenerateProjectFiles.bat, open UE5.sln. Select Development Editor configuration, right click on UE5 and press Build.

  5. Open Engine\Binaries\Win64\UnrealEditor.exe. Create a new Blank C++ project (no starter content required). Let's name it UELibExtended.

  6. Navigate to your project location and open UELibExtended.sln. Find UELibExtended\Source\UELibExtended.Target.cs and modify it:

    // Copyright Epic Games, Inc. All Rights Reserved.
    using UnrealBuildTool;
    using System.Collections.Generic;
    
    public class UELibExtendedTarget : TargetRules
    {
      public UELibExtendedTarget( TargetInfo Target) : base(Target)
      {
        Type = TargetType.Game;
        DefaultBuildSettings = BuildSettingsVersion.V2;
        IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_1;
    
        // new lines of code
        GlobalDefinitions.Add("UE_LIBRARY_ENABLED=1");
        LinkType = TargetLinkType.Monolithic;
        bShouldCompileAsDLL = true;
        ExtraModuleNames.AddRange(new string [] { "UELibExtended", "UELibrary"});
      }
    }

    This will build your game as a monolith .dll file and expose UELibrary_ (e.g. UELibrary_WndProc) functions.

  7. Select Development Editor configuration, right click on UELibExtended project and build it. This will generate the necessary modules for the UE5 Editor.

  8. Open UELibExtended.uproject and cook the content (Platforms -> Windows -> Cook Content). This will transform raw assets into platform specific packages.

  9. Select Development configuration and compile UELibExtended project. This will generate UELibExtended\Binaries\Win64\UELibExtended.dll library. and corresponding UELibExtended.lib file

  10. Open Developer Command Prompt for VS 2022 from the Windows Start menu. Run these commands:

    cd path\to\UELibExtended.dll
    dumpbin /exports UELibExtended.dll

    Look for UELibrary_InitA, UELibrary_InitW, UELibrary_Shutdown, UELibrary_Tick and UELibrary_WndProc symbols. If they are missing make sure that you've saved the UELibExtended.Target.cs file and compiled UELibExtended project in Development, not Development Editor configuration.

  11. Clone UELibApp project. This is a Win32 app that will embed the UELibExtended game.

    Inside of this repo you will find the UELib folder:

    UELibApp\
      UELib\
        include\
        lib\

    I have configured UELibApp project to search for header files in the include folder and look for UELibExtended.lib file in the lib folder.

  12. Copy UnrealEngine\Engine\Source\Runtime\UELibrary\Public\UELibraryAPI.h to UELibApp\UELib\include.

  13. Modify the path to your UELibExtended.uproject file in the UELibApp.cpp:

    // replace ..\\..\\..\\UELibExtended\\UELibExtended.uproject with the full path to your .uproject
    int Error = UELibrary_Init(hInstance, hWnd, L"..\\..\\..\\UELibExtended\\UELibExtended.uproject");
  14. Copy UELibExtended\Binaries\Win64\UELibExtended.lib to UELibApp\UELib\lib.

  15. Open UELibApp.sln, change the configuration to Release and compile it.

  16. Copy all .dll files from UELibExtended\Binaries\Win64 to UELibApp\x64\Release and run the project.

You need to repeat the last 3 steps every time you recompile UELibExtended game. You can automate this with PostBuild steps. I'm too lazy to learn it lol.

Extending the base UELibrary API (per game)

You can expose more functions to the external application. The official documentation is very vague on what to do so we will craft our own example. Let's expose a UELibExtended_CountActors function that will return a number of actors in the current level.

  1. Create blank UELibExtended\Source\UELibExtended\UELibExtendedApi.h and UELibExtended\Source\UELibExtended\UELibExtendedApi.cpp files.

  2. Generate project files by right clicking on UELibExtended.uproject and selecting the Generate Visual Studio project files option.

  3. Modify header file UELibExtendedApi.h:

    // Copyright Epic Games, Inc. All Rights Reserved.
    #pragma once
    
    #ifdef UELIBEXTENDED_LIBRARY_DLL_EXPORT
    #define UELIBEXTENDEDLIBRARYAPI __declspec(dllexport)
    #else
    #define UELIBEXTENDEDLIBRARYAPI __declspec(dllimport)
    #endif
    
    extern "C"
    {
        UELIBEXTENDEDLIBRARYAPI int UELibExtended_CountActors();
    }
  4. Modify source file UELibExtendedApi.cpp:

    // Copyright Epic Games, Inc. All Rights Reserved.
    #define UELIBEXTENDED_LIBRARY_DLL_EXPORT
    #include "UELibExtendedApi.h"
    #undef UELIBEXTENDED_LIBRARY_DLL_EXPORT
    
    #include "EngineMinimal.h"
    
    UELIBEXTENDEDLIBRARYAPI int UELibExtended_CountActors()
    {
        if (!GEngine) {
            return 0;
        }
    
        for (const FWorldContext& Context : GEngine->GetWorldContexts())
        {
            if (Context.WorldType == EWorldType::Game) {
                return Context.World()->GetActorCount();
            }
        }
        return 0;
    }
  5. Compile UELibExtended project in Development configuration. Examine UELibExtended.dll with the dumpbin command and make sure UELibExtended_CountActors is exposed.

  6. Copy UELibExtended\Source\UELibExtended\UELibExtendedApi.h to UELibApp\UELib\include

  7. Copy UELibExtended\Binaries\Win64\UELibExtended.lib to UELibApp\UELib\lib.

  8. Copy all .dll files from UELibExtended\Binaries\Win64 to UELibApp\x64\Release and run the project.

  9. Compile UELibApp project and run it. If there are some errors make sure that you've copied UELibExtendedApi.h, UELibExtended.lib and UELibExtended.dll files as described above.

  10. Modify the UELibApp.cpp to include the new UELibExtendedApi.h header. Modify Windows Message Processing callback to show the actor count on right mouse button click:

    // include new header
    #include "UELibExtendedApi.h"
    
    // a lot of code here... 
    
    // modify WM_RBUTTONUP in WndProc function
    case WM_RBUTTONUP:
    {
        OutputDebugStringVar(L"Actor count :%d", UELibExtended_CountActors());
        return UELibrary_WndProc(hWnd, message, wParam, lParam);
    }
    break;
  11. Compile UELibApp project and run it. Click the right mouse button to spawn a dialog box.

About

Unreal Game as a Shared Library example app


Languages

Language:C++ 83.2%Language:C 16.8%