Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,18 @@ expose, an optional C++ helper (`MCPythonHelper`) is available. Full details in

**Option A: Download from GitHub Releases (Recommended)**

Download the latest zip from [Releases](https://github.com/GenOrca/unreal-mcp/releases) and extract it anywhere. Then copy `Plugins/UnrealMCPython/` into your project's `Plugins/` folder:
Each [release](https://github.com/GenOrca/unreal-mcp/releases) ships two kinds of plugin asset — pick whichever fits:

- **`UnrealMCPython_<engine>_<version>.zip`** (e.g. `UnrealMCPython_5.7_2.2.0.zip`) — **precompiled** for that exact UE version. No C++ toolchain required; just drop it in.
- **`UnrealMCPython-v<version>.zip`** — **source only** (the CI release pipeline runs on Linux and does not compile the C++ module). Unreal builds the module on first open, which needs a C++ toolchain.

Extract, then copy `Plugins/UnrealMCPython/` into your project's `Plugins/` folder:

```
YourProject/
└── Plugins/
└── UnrealMCPython/
├── Binaries/ (precompiled zip only)
├── Source/
├── Content/
└── UnrealMCPython.uplugin
Expand All @@ -131,7 +137,7 @@ YourProject/
Keep the `mcp-server/` folder from the zip in a convenient location — you'll need its path in Step 3.

> [!NOTE]
> The release zip ships the plugin as **source** (no precompiled binary — the release pipeline runs on Linux and does not build the C++ module). On first open, Unreal offers to build the `UnrealMCPython` module for you; this needs a C++ toolchain (on Windows, Visual Studio with the "Game development with C++" workload). Binaries are engine-version-specific, so source distribution keeps the plugin portable across UE versions.
> Precompiled binaries are engine-version-specific. If there's no `_<your engine>_` zip for your version, use the source zip and let Unreal compile it on first open (Windows: Visual Studio with the "Game development with C++" workload). Maintainers build the per-version binaries locally with `tools/build-plugin.ps1` (the CI pipeline can't — GitHub-hosted runners have no Unreal Engine).

**Option B: Install from [Fab](https://fab.com/s/aed5f75d50b2)**

Expand Down
52 changes: 52 additions & 0 deletions tools/build-plugin.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<#
.SYNOPSIS
Package UnrealMCPython as a precompiled binary plugin for one UE version, via RunUAT BuildPlugin.

.DESCRIPTION
Produces a distributable zip (UnrealMCPython/ with Binaries + Source + Content + .uplugin)
named UnrealMCPython_<engineLabel>_<pluginVersion>.zip. Run once per UE version on a machine
that has that engine installed — the same model KawaiiPhysics uses for its per-version releases.
GitHub-hosted CI cannot do this (no Unreal Engine on the runner), so this is a local build step.

.EXAMPLE
./tools/build-plugin.ps1 -UeRoot "C:\Program Files\Epic Games\UE_5.7"
./tools/build-plugin.ps1 -UeRoot "C:\Program Files\Epic Games\UE_5.8" -EngineLabel 5.8

Then attach the zip to a release:
gh release upload v2.2.0 .\Saved\PluginBuild\UnrealMCPython_5.7_2.2.0.zip
#>
param(
[Parameter(Mandatory = $true)][string]$UeRoot,
[string]$EngineLabel = "",
[string]$OutDir = ""
)
$ErrorActionPreference = "Stop"

$repo = (Resolve-Path "$PSScriptRoot\..").Path
$uplugin = Join-Path $repo "Plugins\UnrealMCPython\UnrealMCPython.uplugin"
$runuat = Join-Path $UeRoot "Engine\Build\BatchFiles\RunUAT.bat"
if (-not (Test-Path $runuat)) { throw "RunUAT.bat not found at $runuat" }
if (-not (Test-Path $uplugin)) { throw ".uplugin not found at $uplugin" }
if (-not $OutDir) { $OutDir = Join-Path $repo "Saved\PluginBuild" }

# plugin version from the .uplugin
$ver = ([regex]'"VersionName"\s*:\s*"([^"]+)"').Match((Get-Content $uplugin -Raw)).Groups[1].Value
if (-not $ver) { throw "Could not read VersionName from $uplugin" }
# engine label: explicit, else derived from the UE_x.y folder name
if (-not $EngineLabel) { $EngineLabel = (Split-Path $UeRoot -Leaf) -replace '^UE_', '' }

$pkg = Join-Path $OutDir "UnrealMCPython"
if (Test-Path $pkg) { Remove-Item -Recurse -Force $pkg }
New-Item -ItemType Directory -Force -Path $OutDir | Out-Null

Write-Host "Building UnrealMCPython $ver for UE $EngineLabel ..." -ForegroundColor Cyan
& $runuat BuildPlugin -Plugin="$uplugin" -Package="$pkg" -TargetPlatforms=Win64 -Rocket
if ($LASTEXITCODE -ne 0) { throw "RunUAT BuildPlugin failed (exit $LASTEXITCODE)" }

# Intermediate is build scratch — not needed in the distributed plugin.
Remove-Item -Recurse -Force (Join-Path $pkg "Intermediate") -ErrorAction SilentlyContinue

$zip = Join-Path $OutDir "UnrealMCPython_${EngineLabel}_${ver}.zip"
if (Test-Path $zip) { Remove-Item -Force $zip }
Compress-Archive -Path $pkg -DestinationPath $zip
Write-Host "BUILT: $zip" -ForegroundColor Green
Loading