Home / Forums / Getting Started with BepInEx 6 (IL2CPP) for Unity Modding: Complete Beginner Guide

UnreliableCode Community

Developer Research, Reverse Engineering & Coding Community

Tutorial

Getting Started with BepInEx 6 (IL2CPP) for Unity Modding: Complete Beginner Guide

ParanormalDev
MelonLoader / BepInEx Dev
MEMBER
Rep: 230
Join Date: Sep 2023
Posts: 21
Thanks: 58
2y ago · May 8, 2024 2:20 PM
#1
What is BepInEx for IL2CPP?
BepInEx 6.x is the standard plugin framework for Unity IL2CPP games. Unlike older Mono games that ran on .NET bytecode, IL2CPP compiles C# to native C++. BepInEx generates C# proxy assemblies at runtime using Il2CppInterop, allowing you to write clean C# mods, hook methods with HarmonyX, and interact with game objects effortlessly.

---

Step 1: Installing BepInEx 6 on Target Game
1. Download the latest **BepInEx 6 Unity (IL2CPP) x64** release from GitHub.
2. Extract all contents (
CODE
BepInEx/
,
CODE
doorstop_config.ini
,
CODE
winhttp.dll
) directly into the game's root folder (where the game's [.exe] is located).
3. Run the game once. BepInEx will automatically unhollow/generate interop assemblies inside
CODE
BepInEx/interop/
and create a
CODE
plugins/
folder.

---

Step 2: Setting up your C# Plugin Project
Create a new C# **Class Library** project in Visual Studio or Rider targeting **.NET 6.0** (or .NET Standard 2.1):

XML
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.*" IncludeAssets="compile" />
    <PackageReference Include="HarmonyX" Version="2.10.*" />
  </ItemGroup>
</Project>


Or add direct assembly references from
CODE
BepInEx/core/
and
CODE
BepInEx/interop/
.

---

Step 3: Creating your Base Plugin Class
CSHARP
using BepInEx;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;

namespace MyFirstIl2CppMod
{
    [BepInPlugin("com.unreliablecode.firstmod", "My First Mod", "1.0.0")]
    public class Plugin : BasePlugin
    {
        public static Plugin Instance { get; private set; } = null!;
        private Harmony _harmony = null!;

        public override void Load()
        {
            Instance = this;
            Log.LogInfo("Plugin loaded successfully!");

            // Apply all Harmony patches in this assembly
            _harmony = new Harmony("com.unreliablecode.firstmod");
            _harmony.PatchAll();
        }
    }
}


---

Step 4: Hooking Game Methods with HarmonyX
Suppose you want to hook the player movement or stamina system in the target game:

CSHARP
using HarmonyLib;
using UnityEngine;

namespace MyFirstIl2CppMod.Patches
{
    // Hook target method inside the game's PlayerController class
    [HarmonyPatch(typeof(PlayerController), nameof(PlayerController.Update))]
    public static class PlayerControllerUpdatePatch
    {
        [HarmonyPostfix]
        public static void Postfix(PlayerController __instance)
        {
            if (__instance == null) return;

            // Example: Infinite Stamina
            __instance.stamina = 100f;

            // Check for hotkey press
            if (Input.GetKeyDown(KeyCode.F1))
            {
                Plugin.Instance.Log.LogInfo($"Player Position: {__instance.transform.position}");
            }
        }
    }
}


---

Step 5: Building & Testing
1. Build the solution (
CODE
Ctrl+Shift+B
).
2. Copy the compiled
CODE
MyFirstIl2CppMod.dll
from
CODE
bin/Debug/net6.0/
into
CODE
GameFolder/BepInEx/plugins/
.
3. Launch the game and check the console output!
ParanormalDev | MelonLoader & ImGui Modding
The following users thanked ParanormalDev for this post:
IL2Cpp_Wizard
IL2Cpp & Metadata Engineer
VIP
Rep: 360
Join Date: Feb 2023
Posts: 21
Thanks: 92
2y ago · May 8, 2024 4:15 PM
#2
Outstanding tutorial for newcomers to BepInEx 6!

One crucial difference between Mono and IL2CPP in BepInEx to keep in mind:
- In Mono, generic types work natively in Harmony patches.
- In IL2CPP, Il2CppInterop wraps native pointers into C# proxy instances. If you ever need to access private/internal fields that aren't exposed on the proxy class, you can use
CSHARP
Il2CppSystem.Object
casting or
CSHARP
IL2CPP.il2cpp_field_get_value()
!
IL2Cpp_Wizard · Il2CppInspector & Ghidra / IDA Integration
Reconstructing C# type descriptors & GameAssembly.dll offsets
RustMechanic
Unity & IL2CPP Reverser
VIP
Rep: 295
Join Date: Nov 2022
Posts: 32
Thanks: 74
2y ago · May 8, 2024 6:30 PM
#3
Also a tip for drawing in-game menus: you can attach a MonoBehaviour component to the BepInEx plugin GameObject using:
CSHARP
IL2CPP.RegisterTypeInIl2Cpp<MyCustomUI>();
AddComponent<MyCustomUI>();

and draw standard Unity
CODE
OnGUI()
elements or instantiate custom canvas prefabs right from your mod!
RustMechanic | IL2CPP & Unity Engine Analysis
ZeroMemory
Member
MEMBER
Rep: 75
Join Date: Oct 2024
Posts: 32
Thanks: 18
2y ago · May 9, 2024 10:05 AM
#4
Originally Posted by @ParanormalDev
Step 1: Installing BepInEx 6 on Target Game

Thank you so much for this guide! Setting up BepInEx 6 and getting the first Harmony patch running was super smooth with this template!
ZeroMemory · Always experimenting