Every Unity mobile developer knows the loop: change one number in a jump or a camera shake, wait for the domain reload, then wait again for a full IL2CPP build before you can feel the change on a real phone. In October 2026 Unity published MethodReload, an experimental feature that swaps the body of a tagged C# method inside a running game, in the Editor and on IL2CPP development builds. This guide explains what it does, how to set it up on a mobile project, where it breaks, and how we would trial it.
▶ Watch the video version (about 4 minutes):
What MethodReload is
MethodReload ships inside com.unity.pipeline, the same experimental package that powers the Unity CLI. You mark a method with the [MethodReload] attribute, start a watcher, enter Play Mode or attach a development player, and then edit the method body. When you save, the running instance uses the new body the next time the method is called. Unity demoed it on stage at Unite Seoul and announced it on the Unity blog and Discussions on October 22, 2026.
It is not a replacement for domain reload. Unity is direct about that: bigger changes still go through a normal compile. The target is the small tweaks that make up most of an iteration session, such as tuning speeds, timings, curves, spawn rules and UI behaviour.
The feature has changed names quickly. According to the package changelog, version 0.6.0 (August 31, 2026) renamed "hot reload" to "code reload" with a [CodeReload] attribute, and the current 0.9 manual uses [MethodReload] and the script.methodreload command group. Unity's blog post still names 0.7.0-exp.1 as the install string, while the latest release is 0.9.1-exp.1 (October 22, 2026). Follow the 0.9 method reload manual for the version you actually install, and expect names to move again.
Why this matters for mobile and IL2CPP
The Editor already has ways around slow reloads. You can turn off domain reload in Enter Play Mode settings, as described in the Unity manual, as long as you reset static state yourself. Asset Store hot reload tools patch methods in a running Mono runtime and support full C#.
None of that helps on a phone running an IL2CPP build. IL2CPP compiles C# ahead of time to native code, so there is no runtime to patch and no domain to reload. Every change has meant a rebuild, an install and a fresh start of the app, often several minutes per cycle on a mid-sized Android or iOS project.
MethodReload takes a different route. Each tagged method gets a small check woven in at compile time. On every call it asks a registry whether a newer body exists. If one does, a small IL interpreter, written in plain C# and compiled into the development build along with your game, runs the new IL. If not, the original compiled code runs. The Editor compiles your edit and pushes it to connected players over PlayerConnection, the channel the Profiler uses, so it works over USB without opening a port.
Unity's own comparison is a fair summary: if your iteration pain lives in the Editor, existing tools are mature; if it lives on a device, especially IL2CPP, this is the first option that reaches it.
How the options compare
| Option | Where it works | C# coverage | Main cost |
|---|---|---|---|
| Domain reload (default) | Editor | Full | Full reload on every change |
| Domain reload disabled | Editor | Full | You must reset statics yourself |
| Asset Store hot reload tools | Editor, Mono players | Full | No IL2CPP support |
| MethodReload, interpreter | Editor, any dev build incl. IL2CPP | Subset | Tagging, slower interpreted code |
| MethodReload, Assembly.Load | Editor, desktop Mono dev builds | Full | Public members only, needs runtime server |
Setting it up on a Unity mobile project
Unity 6.0 or later is required. A safe first setup looks like this:
- Install on a branch. Add the package by name in Package Manager (
com.unity.pipeline) or through the Unity CLI. Pin the exact version inPackages/manifest.jsonso the team runs the same build of an experimental package. - Tag the methods you tune. Tagged methods must be
public(instance or static) and returnvoidorIEnumerator. Anything else is skipped at build time with a warning. The tag must exist before you enter Play Mode or build, because the dispatch check is woven in at compile time. - Start the watcher. Open Project Settings, Pipeline, Editor, and click Start Watching in the Method Reload Interpreter Watch section. The watch covers the whole Assets folder, but a saved
.csfile only compiles if it mentionsMethodReload. - Try it in the Editor first. Enter Play Mode and edit a tagged
Updateor tuning method. The watcher runs your change through the same interpreter used on device, so subset problems show up here before you wait for a build. - Enable the runtime in development builds. In Project Settings, Pipeline, Runtime, turn on the option for development builds, as described in Runtime connection and setup. Build a Development Build, install it, and connect it with Autoconnect Profiler or through the Profiler or Console window.
- Edit and save. Each save compiles in the Editor with the player's scripting defines and pushes to every connected player. No restart is needed.
A minimal example from Unity's docs:
using Unity.Pipeline.MethodReload;
using UnityEngine;
public class Spinner : MonoBehaviour
{
public float rotationSpeed = 90f;
[MethodReload]
public void Update()
{
transform.Rotate(Vector3.up, rotationSpeed * Time.deltaTime);
}
}
If you prefer a terminal, the same push is available as a Unity CLI command (unity command script.methodreload reload_player "Assets/Scripts" in the 0.9 manual), which is also how an AI coding agent could drive it.
The limits you have to plan around
Only method bodies change
A reload never touches fields, call sites or type layout. You cannot add fields or classes. A reloaded body can declare and call a new helper method, but that helper cannot become a reload entry point until your next real compile. In practice you decide in advance which methods you will tune, and tag them.
The interpreter runs a C# subset
Inside a tagged body you cannot use await or Task, try/catch/finally, lock, LINQ query syntax, decimal, dynamic, reflection or threading types, ref/out/in parameters, multi-dimensional arrays or generic methods. Primitives, method calls, loops, delegates, string interpolation, collections and coroutine yield do work. A Roslyn analyzer shipped with the package flags violations in your IDE on tagged methods only.
IL2CPP stripping still applies
On device, interpreted code can only call engine and .NET members that exist in the build. IL2CPP strips code nothing references, so if your new body calls an API the game never used, the push lists it as a warning and the call throws if it is reached. The 0.9 settings page can generate a link.xml that keeps every member of the types your game already uses; regenerate it after larger code changes. Unity's rule of thumb: change what a method does, not which APIs it depends on.
Coroutines and performance
A tagged IEnumerator picks up the new body the next time StartCoroutine runs; coroutines already running keep the old one. An [OnMethodReloaded] method on the same class can stop and restart them. Interpreted code is slower than compiled code, so frame times measured while a reload is active are not your real numbers. Profile with the reload cleared.
Release builds and security
In a release build a tagged method simply runs its compiled body, with no prologue and no interpreter. The attribute lives in a separate Unity.Pipeline.Attributes assembly so tagged code still compiles there. The Pipeline runtime assemblies only compile into development or instrumented builds unless you add the ENABLE_RUNTIME_PIPELINE define on purpose.
That gate matters. The runtime setup page warns that a build with the runtime server enabled carries a local HTTP server that executes commands. Never add ENABLE_RUNTIME_PIPELINE to a store build, and add a CI check that fails if a release build contains Unity.Pipeline assemblies.
Who should try it now
- Good fit: teams tuning game feel on real phones (touch controls, camera, haptics timing, physics feel), and anyone who iterates on device-only behaviour such as notch layouts, sensors or performance-scaled effects.
- Wait: teams with a strict "no experimental packages" rule, projects whose hot code depends on async/await or heavy generics, and anyone who would expect a feature this young to keep the same API between versions.
- Already happy: if your slow loop is only in the Editor and you use an Asset Store hot reload tool or disabled domain reload, keep that setup. MethodReload adds value mainly on hardware.
Our take
At Lightning Games we build Unity mobile games in Da Nang, and a large share of our tuning time is spent rebuilding IL2CPP players to test a few lines of feel code on a phone. MethodReload targets exactly that loop, and the design is careful: nothing ships in release builds, the device link uses the Profiler channel, and the analyzer catches unsupported code early. We are trialling it on a branch with a short list of tagged methods: input handling, camera follow and difficulty curves. We are not adding it to main until the API settles, given that the attribute has been renamed twice since August. If you already use the Pipeline package for builds and tests (see our Unity CLI and Pipeline 0.9 guide), MethodReload is a small extra step and worth an afternoon.
Sources
- Skipping domain reload: faster iteration using the MethodReload feature (Unity blog, October 22, 2026)
- MethodReload announcement thread (Unity Discussions)
- Reloading code with MethodReload (Unity Pipeline 0.9 manual)
- Runtime connection and setup (Unity Pipeline 0.9 manual)
- Unity Pipeline changelog
- Enter Play mode with domain reload disabled (Unity manual)
Want to see what we build with Unity? Visit Lightning Games for our mobile titles and development notes.
Cover photo: Playing with smartphone by Santeri Viinamäki, CC BY-SA 4.0, via Wikimedia Commons (cropped).



