Zygisk Mod Menu for Unity Games
This tutorial will guide you through creating a Zygisk Mod Menu for Unity games. This method is particularly useful for games with custom protections or integrity checks. It is recommended for modders who already have basic knowledge.
Requirements
- A rooted device with Zygisk enabled, or use the VPhonegaga App for an easier setup.
- Last tested on VPhonegaga 3.4.0 + Magisk v26.1.
Instructions
- Clone the repo from GitHub: Zygisk-ImGui-Menu
- To generate the module zip package, run the Gradle task
:module:assembleRelease
. The package will be generated in the{ProjectDirectory}/out
folder. - Install the package by selecting it in the Magisk App.
What You Should Know/Do
- Edit the package name in
hook.cpp
:#define GamePackageName "com.example.game"
- Pointers and hook functions are called in the
hack_thread
function. Initializing the menu is done by hookingegLSwapBuffers
. - The
DrawMenu
function inmenu.h
creates the components of the mod menu. - Write your hooks in
functions.h
and callHOOK
,PATCH
functions directly. - Use the obfuscate function integrated at
Include/obfuscate.h
.
Additional Information
- Edit module properties like name and version in
module.gradle
. - Add
abiFilters
tobuild.gradle
as needed. For example, only for ARM64:release { ndk { abiFilters 'arm64-v8a' } }
- Refer to
imgui.h
for more menu components.
End to End Example - Adding God Mode & Damage Multiplier Features
- Edit the package name in
hook.cpp
:#define GamePackageName "com.platinmods.yunana"
- Declare variables and create hook functions in
functions.h
:// Declaring variables bool isGodMode; int damageMultiplier = 1; // Creating the hook functions void (*old_ApplyDamagePlayer)(void* instance); void ApplyDamagePlayer(void* instance) { if (instance != NULL) { if (isGodMode) { return; } } return old_ApplyDamagePlayer(instance); } void (*old_ApplyDamageEnemy)(void* instance, int damage); void ApplyDamageEnemy(void* instance, int damage) { if (instance != NULL) { damage *= damageMultiplier; } return old_ApplyDamageEnemy(instance, damage); } // Calling the hooks constructed above void Hooks() { // HOOK are automatically obfuscated, refer to macros defined in Misc.h HOOK("0xOFFSET_1", ApplyDamagePlayer, old_ApplyDamagePlayer); HOOK("0xOFFSET_2", ApplyDamageEnemy, old_ApplyDamageEnemy); }
- Create the menu components in
menu.h
:void DrawMenu() { static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); { Begin(OBFUSCATE("Platinmods.com")); // Header ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_FittingPolicyResizeDown; if (BeginTabBar(OBFUSCATE("Main Tab"), tab_bar_flags)) { if (BeginTabItem(OBFUSCATE("Tab Items"))) { TextUnformatted(OBFUSCATE("Damage Multiplier:")); // just plain text SliderInt(OBFUSCATE("Damage Multiplier"), &damageMultiplier, 1, 100, OBFUSCATE("%d"), 0); // min = 1, max = 100 Checkbox(OBFUSCATE("God Mode"), &isGodMode); EndTabItem(); } EndTabBar(); } Patches(); // <-This is entry point of patching functions, navigate to it and you will understand :) End(); } }
- Run the Gradle task
:module:assembleRelease
to compile. Grab the module package.zip from the{ProjectDirectory}/out
folder. - Install the module package.zip with the Magisk App. Reboot the device and launch the target game.
Extras
If you encounter an initialization error about unsupported Java, it's likely due to an incompatible Java version with the Gradle version used. To fix this:
- Click on the "Unsupported Java" error for a solution.
- Select "Build Variant" to change the build type, then click "Make Project" in the "Build" menu to compile/build your Zygisk module. No need to change "Active ABI".
If the project complains about CMake not being found, install the required CMake version.
0 Comments