Skip to content

Tutorial Connecting Reconstructed Logic to UnityEvents

clericall edited this page Aug 13, 2026 · 1 revision

Tutorial: Connecting Reconstructed Logic to UnityEvents

One of the biggest surprises when working with IL2CPP decompilations is that 100% of serialized event data survives.

When a designer sets up a button click or an interaction trigger in the Unity Inspector using UnityEvent, Unity saves the target object, method name, and arguments into the scene or prefab YAML file. Even though the C# code behind those methods was stripped during IL2CPP compilation, the YAML files still remember every call chain.

This guide explains how to read serialized UnityEvent graphs, inspect target calls, and make sure your reconstructed C# components plug into existing scene wiring.


How Unity Stores UnityEvents in YAML

Open any decompiled .unity scene file or .prefab file in a text editor and search for m_PersistentCalls. You will see blocks that look like this:

m_OnClick:
  m_PersistentCalls:
    m_Calls:
    - m_Target: {fileID: 11500000, guid: a1b2c3d4e5f67890a1b2c3d4e5f67890, type: 3}
      m_TargetAssemblyTypeName: Menu, Assembly-CSharp
      m_MethodName: OpenPanel
      m_Mode: 5
      m_Arguments:
        m_ObjectArgument: {fileID: 0}
        m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
        m_IntArgument: 0
        m_FloatArgument: 0
        m_StringArgument: Panel_Settings
        m_BoolArgument: 0
      m_CallState: 2

Here is what each field means:

  • m_TargetAssemblyTypeName: The class holding the method (e.g. Menu).
  • m_MethodName: The exact method name invoked when the event fires (e.g. OpenPanel).
  • m_Mode: Parameter mode (0 = Void/No args, 1 = Int, 2 = Float, 3 = String, 4 = Object, 5 = EventDefined).
  • m_StringArgument: The string parameter passed to the method (e.g. "Panel_Settings").

Why This Matters for Porting

In the MiSide port, the main menu carried 108 ButtonMouseClick components, 84 of which had wired event handlers and 20 with scene-loading calls.

Because the scene YAML file retains all 84 event chains intact, you do not have to rewrite the actions that happen when buttons are clicked. You only need to write the minimal wrapper that receives UI clicks and calls eventClick.Invoke().

Once eventClick.Invoke() runs, Unity's built-in event engine executes the entire original event chain—triggering scene loads, opening panels, changing settings, and toggling GameObjects.


Rebuilding Scripts to Fit Existing Wiring

When you rebuild a component that uses UnityEvent, your replacement C# class must match three things so Unity can deserialize it correctly:

  1. Same Class Name: Must match the original script name (e.g. ButtonMouseClick).
  2. Same Field Names: The UnityEvent fields must match the original variable names in C# (e.g. public UnityEvent eventClick;).
  3. Same Method Signatures: Any target method called by an event in YAML (e.g. public void OpenPanel(string panelName)) must exist with the exact same name and parameter type.

Example: Matching a Door Trigger

Suppose a door object in Scene 2 - InGame has a 23-call UnityEvent chain attached to an ObjectInteractive script.

Looking at the scene YAML, we see the interaction event calls:

  1. Animator.SetTrigger("OpenDoor")
  2. AudioSource.Play()
  3. ObjectAnimationPlayer.AnimationPlay()

To get this whole chain working, your replacement ObjectInteractive script only needs to fire its onClick event when the player looks at the object and presses the interaction key:

using UnityEngine;
using UnityEngine.Events;

public class ObjectInteractive : MonoBehaviour
{
    public UnityEvent onClick;

    // Called by PlayerMove raycast when player presses Use key
    public void Click()
    {
        if (onClick != null)
        {
            onClick.Invoke(); // Fires the original 23-call chain from the scene YAML
        }
    }
}

You didn't have to code the door opening, animation triggering, or audio playback. As long as Click() calls onClick.Invoke(), Unity handles the rest.


Summary Checklist for Event Rewiring

  1. Search scene/prefab YAML for m_PersistentCalls to see what methods the scene expects to call.
  2. Ensure your reconstructed C# script defines public UnityEvent fields with matching names.
  3. Ensure methods called by events (like OpenPanel(string)) have matching public signatures.
  4. Run tools/remap-ugui.py to fix synthetic script GUIDs so uGUI components link to Unity's native package scripts instead of missing script placeholders.