diff --git a/Assets/Packages/com.cosminb.unity-internals/Runtime~/Internal/BlittableArrayWrapper.cs b/Assets/Packages/com.cosminb.unity-internals/Runtime~/Internal/BlittableArrayWrapper.cs
index 5b3d224..a8fa25b 100644
--- a/Assets/Packages/com.cosminb.unity-internals/Runtime~/Internal/BlittableArrayWrapper.cs
+++ b/Assets/Packages/com.cosminb.unity-internals/Runtime~/Internal/BlittableArrayWrapper.cs
@@ -28,7 +28,9 @@ public enum UpdateFlags
///
/// Converts the native data to a NativeArray without copying.
- /// The caller is responsible for disposing the NativeArray.
+ /// WARNING: This wraps Unity-owned memory. The returned NativeArray must NOT
+ /// be disposed — use Allocator.None so that Dispose() is a no-op. If you need
+ /// a NativeArray you can safely dispose, use instead.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public NativeArray ToNativeArray(Allocator allocator) where T : unmanaged
@@ -42,13 +44,14 @@ public NativeArray ToNativeArray(Allocator allocator) where T : unmanaged
int elementSize = UnsafeUtility.SizeOf();
int elementCount = size / elementSize;
- // Create NativeArray that wraps the data
+ // Wrap Unity-owned memory with Allocator.None so Dispose() won't
+ // attempt to free native memory we don't own.
var nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray(
- data, elementCount, allocator);
+ data, elementCount, Allocator.None);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
// Set safety handle for the native array
- NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref nativeArray,
+ NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref nativeArray,
AtomicSafetyHandle.Create());
#endif
diff --git a/Assets/Packages/com.cosminb.unity-internals/Runtime~/UnityExposed.cs b/Assets/Packages/com.cosminb.unity-internals/Runtime~/UnityExposed.cs
index 4016316..f53415b 100644
--- a/Assets/Packages/com.cosminb.unity-internals/Runtime~/UnityExposed.cs
+++ b/Assets/Packages/com.cosminb.unity-internals/Runtime~/UnityExposed.cs
@@ -17,11 +17,16 @@ public static class UnityExposed
///
/// Gets the marshalled Unity object pointer. This avoids allocations compared to reflection.
+ /// The Cecil processor detects whether the target Unity version uses the pre-6000.3
+ /// signature (int, Type, out bool) or the 6000.3+ signature (int, out bool) for the
+ /// internal GetPtrFromInstanceID call and emits the correct IL accordingly.
///
public static IntPtr MarshalUnityObject(UnityEngine.Object obj)
{
// This will be replaced by Cecil to access obj.m_CachedPtr directly
- // and call Unity's internal GetPtrFromInstanceID if needed
+ // and call Unity's internal GetPtrFromInstanceID if needed.
+ // The Cecil processor auto-detects the GetPtrFromInstanceID signature at
+ // build time, so the same source works for both pre-6000.3 and 6000.3+.
throw new NotImplementedException("Assembly not processed by Cecil. Run ProcessAssembly.sh");
}
diff --git a/Assets/Packages/com.cosminb.unity-internals/Runtime~/UnityVersionChecker.cs b/Assets/Packages/com.cosminb.unity-internals/Runtime~/UnityVersionChecker.cs
index 7e08f5d..2abda1e 100644
--- a/Assets/Packages/com.cosminb.unity-internals/Runtime~/UnityVersionChecker.cs
+++ b/Assets/Packages/com.cosminb.unity-internals/Runtime~/UnityVersionChecker.cs
@@ -8,17 +8,27 @@ namespace ExposedBindings
{
///
/// Checks Unity version compatibility for the internal bindings.
+ /// The Cecil processor auto-detects internal API signatures at build time,
+ /// so the DLL must be rebuilt via ProcessAssembly.sh when crossing major
+ /// version boundaries (e.g. 6000.0 -> 6000.3).
///
#if UNITY_EDITOR
[InitializeOnLoad]
#endif
public static class UnityVersionChecker
{
- private const string TARGET_UNITY_VERSION = "6000.0.31f1";
- private const int TARGET_MAJOR = 6000;
- private const int TARGET_MINOR = 0;
- private const int TARGET_PATCH = 31;
-
+ // Minimum supported version — anything older is unsupported.
+ private const string MIN_UNITY_VERSION = "6000.0.31f1";
+ private const int MIN_MAJOR = 6000;
+ private const int MIN_MINOR = 0;
+ private const int MIN_PATCH = 31;
+
+ // Maximum version the Cecil processor has been validated against.
+ // Bump this when verifying a new Unity release.
+ private const string MAX_VALIDATED_VERSION = "6000.3.99f1";
+ private const int MAX_MAJOR = 6000;
+ private const int MAX_MINOR = 3;
+
static UnityVersionChecker()
{
CheckUnityVersion();
@@ -30,33 +40,31 @@ static UnityVersionChecker()
public static void CheckUnityVersion()
{
var currentVersion = Application.unityVersion;
-
+
if (!ParseUnityVersion(currentVersion, out int major, out int minor, out int patch))
{
Debug.LogWarning($"[ExposedBindings] Could not parse Unity version: {currentVersion}. " +
- $"This library was built for Unity {TARGET_UNITY_VERSION}.");
+ $"Minimum supported: {MIN_UNITY_VERSION}.");
return;
}
- // Check if version is older than target
- if (major < TARGET_MAJOR ||
- (major == TARGET_MAJOR && minor < TARGET_MINOR) ||
- (major == TARGET_MAJOR && minor == TARGET_MINOR && patch < TARGET_PATCH))
+ // Check if version is older than minimum
+ if (major < MIN_MAJOR ||
+ (major == MIN_MAJOR && minor < MIN_MINOR) ||
+ (major == MIN_MAJOR && minor == MIN_MINOR && patch < MIN_PATCH))
{
- Debug.LogError($"[ExposedBindings] Unity version {currentVersion} is older than the minimum supported version {TARGET_UNITY_VERSION}. " +
+ Debug.LogError($"[ExposedBindings] Unity version {currentVersion} is older than the minimum supported version {MIN_UNITY_VERSION}. " +
"The internal bindings may not work correctly.");
return;
}
- // Warn if version is newer
- if (major > TARGET_MAJOR ||
- (major == TARGET_MAJOR && minor > TARGET_MINOR) ||
- (major == TARGET_MAJOR && minor == TARGET_MINOR && patch > TARGET_PATCH))
+ // Warn if version is beyond validated range
+ if (major > MAX_MAJOR ||
+ (major == MAX_MAJOR && minor > MAX_MINOR))
{
- Debug.LogWarning($"[ExposedBindings] This library was built for Unity {TARGET_UNITY_VERSION}, " +
- $"but you are using {currentVersion}. " +
- "Unity's internal signatures may have changed. " +
- "Please test thoroughly and consider updating the bindings if issues occur.");
+ Debug.LogWarning($"[ExposedBindings] Unity {currentVersion} is newer than the last validated version ({MAX_VALIDATED_VERSION}). " +
+ "Internal signatures may have changed — rebuild with ProcessAssembly.sh against your Unity install " +
+ "and test thoroughly.");
}
}
@@ -72,7 +80,7 @@ private static bool ParseUnityVersion(string versionString, out int major, out i
if (string.IsNullOrEmpty(versionString))
return false;
- // Unity version format: "6000.0.31f1" or "2022.3.10f1"
+ // Unity version format: "6000.0.31f1" or "6000.3.2f1"
var parts = versionString.Split('.');
if (parts.Length < 3)
return false;
@@ -83,12 +91,12 @@ private static bool ParseUnityVersion(string versionString, out int major, out i
if (!int.TryParse(parts[1], out minor))
return false;
- // Extract patch number (remove 'f1' suffix)
+ // Extract patch number (remove 'f1', 'b1', 'a1' suffix)
var patchStr = parts[2];
- var fIndex = patchStr.IndexOf('f');
- if (fIndex > 0)
+ var suffixIndex = patchStr.IndexOfAny(new[] { 'f', 'b', 'a' });
+ if (suffixIndex > 0)
{
- patchStr = patchStr.Substring(0, fIndex);
+ patchStr = patchStr.Substring(0, suffixIndex);
}
if (!int.TryParse(patchStr, out patch))
@@ -103,38 +111,39 @@ private static bool ParseUnityVersion(string versionString, out int major, out i
public static VersionCompatibility GetCompatibility()
{
var currentVersion = Application.unityVersion;
-
+
if (!ParseUnityVersion(currentVersion, out int major, out int minor, out int patch))
{
return new VersionCompatibility
{
IsCompatible = false,
CurrentVersion = currentVersion,
- TargetVersion = TARGET_UNITY_VERSION,
+ MinVersion = MIN_UNITY_VERSION,
+ MaxValidatedVersion = MAX_VALIDATED_VERSION,
Message = "Could not parse Unity version"
};
}
- bool isOlder = major < TARGET_MAJOR ||
- (major == TARGET_MAJOR && minor < TARGET_MINOR) ||
- (major == TARGET_MAJOR && minor == TARGET_MINOR && patch < TARGET_PATCH);
+ bool isOlder = major < MIN_MAJOR ||
+ (major == MIN_MAJOR && minor < MIN_MINOR) ||
+ (major == MIN_MAJOR && minor == MIN_MINOR && patch < MIN_PATCH);
- bool isNewer = major > TARGET_MAJOR ||
- (major == TARGET_MAJOR && minor > TARGET_MINOR) ||
- (major == TARGET_MAJOR && minor == TARGET_MINOR && patch > TARGET_PATCH);
+ bool isBeyondValidated = major > MAX_MAJOR ||
+ (major == MAX_MAJOR && minor > MAX_MINOR);
- bool isExactMatch = major == TARGET_MAJOR && minor == TARGET_MINOR && patch == TARGET_PATCH;
+ bool isInRange = !isOlder && !isBeyondValidated;
return new VersionCompatibility
{
IsCompatible = !isOlder,
- IsExactMatch = isExactMatch,
- IsNewer = isNewer,
+ IsInValidatedRange = isInRange,
+ IsBeyondValidated = isBeyondValidated,
CurrentVersion = currentVersion,
- TargetVersion = TARGET_UNITY_VERSION,
+ MinVersion = MIN_UNITY_VERSION,
+ MaxValidatedVersion = MAX_VALIDATED_VERSION,
Message = isOlder ? "Unity version is older than minimum supported version" :
- isNewer ? "Unity version is newer than target version - internals may have changed" :
- "Unity version matches target version"
+ isBeyondValidated ? "Unity version is newer than last validated version — rebuild recommended" :
+ "Unity version is within validated range"
};
}
@@ -144,11 +153,12 @@ public static VersionCompatibility GetCompatibility()
public struct VersionCompatibility
{
public bool IsCompatible;
- public bool IsExactMatch;
- public bool IsNewer;
+ public bool IsInValidatedRange;
+ public bool IsBeyondValidated;
public string CurrentVersion;
- public string TargetVersion;
+ public string MinVersion;
+ public string MaxValidatedVersion;
public string Message;
}
}
-}
\ No newline at end of file
+}
diff --git a/Assets/Packages/com.cosminb.unity-internals/package.json b/Assets/Packages/com.cosminb.unity-internals/package.json
index 785398b..3651e3a 100644
--- a/Assets/Packages/com.cosminb.unity-internals/package.json
+++ b/Assets/Packages/com.cosminb.unity-internals/package.json
@@ -1,8 +1,8 @@
{
"name": "com.cosminb.unity-internals",
- "version": "1.0.0",
+ "version": "1.1.0",
"displayName": "Exposed Bindings",
- "description": "Exposes Unity internal bindings for high-performance native array operations. Built for Unity 6000.0.31f1. Source code is available in the Runtime~ folder for reference and modification.",
+ "description": "Exposes Unity internal bindings for high-performance native array operations. Supports Unity 6000.0.31f1 through 6000.3.x. Source code is available in the Runtime~ folder for reference and modification.",
"unity": "6000.0",
"unityRelease": "31f1",
"dependencies": {
diff --git a/CecilProcessor/Program.cs b/CecilProcessor/Program.cs
index 02178bd..8f712c3 100644
--- a/CecilProcessor/Program.cs
+++ b/CecilProcessor/Program.cs
@@ -102,7 +102,7 @@ static void ProcessAssembly(string inputPath, string outputPath,
AddMarshalUnityObjectMethod(assembly, exposedType, coreModule);
ReplaceImageConversionMethod(assembly, exposedType, imageConversionModule, unitySpanWrapper, ourSpanWrapper);
ReplaceAssetBundleMethods(assembly, exposedType, assetBundleModule, unitySpanWrapper, ourSpanWrapper);
- ReplaceEncodingMethods(assembly, exposedType, imageConversionModule);
+ ReplaceEncodingMethods(assembly, exposedType, imageConversionModule, coreModule);
// Remove System.Private.CoreLib reference (added by dotnet SDK but not needed in Unity)
var coreLibRef = assembly.MainModule.AssemblyReferences.FirstOrDefault(r => r.Name == "System.Private.CoreLib");
@@ -154,7 +154,11 @@ static void AddMarshalUnityObjectMethod(AssemblyDefinition assembly, TypeDefinit
return;
}
- // Find GetPtrFromInstanceID method
+ // Find GetPtrFromInstanceID method.
+ // The signature changed in Unity 6000.3:
+ // Pre-6000.3: IntPtr GetPtrFromInstanceID(int instanceID, Type objectType, out bool isMonoBehaviour)
+ // 6000.3+: IntPtr GetPtrFromInstanceID(int instanceID, out bool isMonoBehaviour)
+ // We detect the parameter count at processing time and emit the correct IL.
var getPtrMethod = unityObjectType.Methods.FirstOrDefault(m => m.Name == "GetPtrFromInstanceID");
if (getPtrMethod == null)
{
@@ -162,6 +166,11 @@ static void AddMarshalUnityObjectMethod(AssemblyDefinition assembly, TypeDefinit
return;
}
+ bool hasTypeParameter = getPtrMethod.Parameters.Count == 3;
+ Console.WriteLine(hasTypeParameter
+ ? " Detected GetPtrFromInstanceID(int, Type, out bool) — pre-6000.3 signature"
+ : " Detected GetPtrFromInstanceID(int, out bool) — 6000.3+ signature");
+
// Clear existing method body
method.Body.Instructions.Clear();
method.Body.Variables.Clear();
@@ -195,38 +204,42 @@ static void AddMarshalUnityObjectMethod(AssemblyDefinition assembly, TypeDefinit
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Conv_I);
il.Emit(OpCodes.Beq_S, needsInstanceIdLabel);
-
+
// m_CachedPtr is valid, return it
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ret);
// m_CachedPtr is zero, need to use instance ID
il.Append(needsInstanceIdLabel);
-
+
// Call GetInstanceID() to get the instance ID
var instanceIdLocal = new VariableDefinition(assembly.MainModule.TypeSystem.Int32);
method.Body.Variables.Add(instanceIdLocal);
-
+
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, assembly.MainModule.ImportReference(getInstanceIdMethod));
il.Emit(OpCodes.Stloc, instanceIdLocal);
-
+
// Check if instance ID == 0
var instanceIdNotZeroLabel = il.Create(OpCodes.Nop);
il.Emit(OpCodes.Ldloc, instanceIdLocal);
il.Emit(OpCodes.Brtrue_S, instanceIdNotZeroLabel);
-
+
// Instance ID is 0, return IntPtr.Zero
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Conv_I);
il.Emit(OpCodes.Ret);
-
+
// Instance ID is not 0, call GetPtrFromInstanceID
il.Append(instanceIdNotZeroLabel);
il.Emit(OpCodes.Ldloc, instanceIdLocal);
-
- // For simplicity, pass null for Type (Unity will handle it)
- il.Emit(OpCodes.Ldnull);
+
+ // Pre-6000.3: pass null for the Type parameter that was removed in 6000.3
+ if (hasTypeParameter)
+ {
+ il.Emit(OpCodes.Ldnull);
+ }
+
il.Emit(OpCodes.Ldloca_S, isMonoBehaviourLocal);
il.Emit(OpCodes.Call, assembly.MainModule.ImportReference(getPtrMethod));
il.Emit(OpCodes.Ret);
@@ -485,11 +498,9 @@ static void ProcessAssetBundleMethod(AssemblyDefinition assembly, AssemblyDefini
Console.WriteLine($"Processed {methodName}");
}
- static void ReplaceEncodingMethods(AssemblyDefinition assembly, TypeDefinition exposedType, AssemblyDefinition imageConversionModule)
+ static void ReplaceEncodingMethods(AssemblyDefinition assembly, TypeDefinition exposedType, AssemblyDefinition imageConversionModule, AssemblyDefinition coreModule)
{
- // Find Unity's BlittableArrayWrapper type - it's in CoreModule
- var coreModulePath = Path.Combine(Path.GetDirectoryName(imageConversionModule.MainModule.FileName), "UnityEngine.CoreModule.dll");
- var coreModule = AssemblyDefinition.ReadAssembly(coreModulePath);
+ // Reuse the already-loaded CoreModule to find BlittableArrayWrapper
var unityBlittableWrapper = coreModule.MainModule.GetType("UnityEngine.Bindings.BlittableArrayWrapper");
if (unityBlittableWrapper == null)
diff --git a/ProcessAssembly.sh b/ProcessAssembly.sh
index 0410e26..657e818 100755
--- a/ProcessAssembly.sh
+++ b/ProcessAssembly.sh
@@ -1,8 +1,14 @@
#!/bin/bash
# Build script for processing Unity internal bindings assembly with Cecil
-
-UNITY_PATH="/Applications/Unity/Hub/Editor/6000.0.31f1"
+#
+# Usage:
+# ./ProcessAssembly.sh # uses default Unity path
+# ./ProcessAssembly.sh /path/to/unity/editor # custom Unity install
+# UNITY_PATH=/path/to/unity ./ProcessAssembly.sh # via env var
+
+# Accept Unity path as first argument, fall back to env var, then to default.
+UNITY_PATH="${1:-${UNITY_PATH:-/Applications/Unity/Hub/Editor/6000.0.31f1}}"
PROJECT_PATH="$(pwd)"
ASSEMBLY_NAME="ExposedBindings"
@@ -10,6 +16,23 @@ echo "=== ExposedBindings Assembly Processor ==="
echo "Unity Path: $UNITY_PATH"
echo "Project Path: $PROJECT_PATH"
+# Resolve the managed assemblies directory (macOS vs Windows layout)
+if [ -d "$UNITY_PATH/Unity.app/Contents/Managed/UnityEngine" ]; then
+ MANAGED_DIR="$UNITY_PATH/Unity.app/Contents/Managed"
+ ENGINE_DIR="$MANAGED_DIR/UnityEngine"
+elif [ -d "$UNITY_PATH/Editor/Data/Managed/UnityEngine" ]; then
+ MANAGED_DIR="$UNITY_PATH/Editor/Data/Managed"
+ ENGINE_DIR="$MANAGED_DIR/UnityEngine"
+else
+ echo "Error: Could not locate Unity managed assemblies under $UNITY_PATH"
+ echo "Tried:"
+ echo " $UNITY_PATH/Unity.app/Contents/Managed/UnityEngine (macOS)"
+ echo " $UNITY_PATH/Editor/Data/Managed/UnityEngine (Windows)"
+ exit 1
+fi
+
+echo "Managed Dir: $MANAGED_DIR"
+
# Step 1: Build the Cecil processor
echo ""
echo "Step 1: Building Cecil processor..."
@@ -32,8 +55,8 @@ rm -rf "$TEMP_BUILD"
mkdir -p "$TEMP_BUILD/TempAssembly"
cd "$TEMP_BUILD/TempAssembly"
-# Create project file
-cat > TempAssembly.csproj << 'EOF'
+# Create project file — references are resolved from the detected Unity install
+cat > TempAssembly.csproj << CSPROJ_EOF
netstandard2.1
@@ -43,29 +66,29 @@ cat > TempAssembly.csproj << 'EOF'
- /Applications/Unity/Hub/Editor/6000.0.31f1/Unity.app/Contents/Managed/UnityEngine/UnityEngine.CoreModule.dll
+ ${ENGINE_DIR}/UnityEngine.CoreModule.dll
- /Applications/Unity/Hub/Editor/6000.0.31f1/Unity.app/Contents/Managed/UnityEngine/UnityEngine.AssetBundleModule.dll
+ ${ENGINE_DIR}/UnityEngine.AssetBundleModule.dll
- /Applications/Unity/Hub/Editor/6000.0.31f1/Unity.app/Contents/Managed/UnityEngine/UnityEngine.ImageConversionModule.dll
+ ${ENGINE_DIR}/UnityEngine.ImageConversionModule.dll
- /Applications/Unity/Hub/Editor/6000.0.31f1/Unity.app/Contents/Managed/Unity.Collections.dll
+ ${MANAGED_DIR}/Unity.Collections.dll
- /Applications/Unity/Hub/Editor/6000.0.31f1/Unity.app/Contents/Managed/mscorlib.dll
+ ${MANAGED_DIR}/mscorlib.dll
- /Applications/Unity/Hub/Editor/6000.0.31f1/Unity.app/Contents/Managed/System.dll
+ ${MANAGED_DIR}/System.dll
- /Applications/Unity/Hub/Editor/6000.0.31f1/Unity.app/Contents/Managed/System.Core.dll
+ ${MANAGED_DIR}/System.Core.dll
-EOF
+CSPROJ_EOF
# Copy source files from package Runtime~ directory
cp -r "$PROJECT_PATH/Assets/Packages/com.cosminb.unity-internals/Runtime~"/* .
@@ -110,7 +133,8 @@ echo "2. Unity will automatically reimport it"
echo "3. Test the functionality with the TestUnityInternalBindings MonoBehaviour"
echo ""
echo "All methods processed successfully:"
-echo " ✓ MarshalUnityObject - Direct access to Unity object pointers without allocations"
-echo " ✓ ImageConversion_LoadImage_Injected - Direct Span-based image loading"
-echo " ✓ AssetBundle_LoadFromMemoryAsync_Internal_Injected - Async bundle loading from Span"
-echo " ✓ AssetBundle_LoadFromMemory_Internal_Injected - Sync bundle loading from Span"
\ No newline at end of file
+echo " - MarshalUnityObject - Direct access to Unity object pointers without allocations"
+echo " - ImageConversion_LoadImage_Injected - Direct Span-based image loading"
+echo " - AssetBundle_LoadFromMemoryAsync_Internal_Injected - Async bundle loading from Span"
+echo " - AssetBundle_LoadFromMemory_Internal_Injected - Sync bundle loading from Span"
+echo " - Texture encoding methods (PNG, JPG, TGA, EXR)"
diff --git a/README.md b/README.md
index 2764028..6a2957c 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
### High-Performance Unity Internal Bindings for Zero-Allocation Operations
- [](https://unity3d.com/)
+ [](https://unity3d.com/)
[](https://docs.microsoft.com/en-us/dotnet/csharp/)
[](https://docs.unity3d.com/Manual/IL2CPP.html)
[](https://unity.com/)
@@ -42,7 +42,7 @@ The `Runtime~` folder (with `~` suffix) prevents Unity from compiling the source
## Requirements
-- Unity 6000.0.31f1 or later
+- Unity 6000.0.31f1 through 6000.3.x (Cecil processor auto-detects internal API signatures)
- .NET 6.0 SDK (for Cecil processing)
- Mono.Cecil NuGet package
@@ -84,16 +84,18 @@ Alternatively, add directly to your `Packages/manifest.json`:
### Post-Installation: Processing the Assembly
-**Note:** The package includes a pre-built `ExposedBindings.dll` that works with Unity 6000.0.31f1+.
+**Note:** The package includes a pre-built `ExposedBindings.dll` that was processed against Unity 6000.0.31f1.
-If you need to rebuild for a different Unity version:
+If you are on Unity 6000.3.x or a different version, you **must** rebuild the assembly:
1. Copy `ProcessAssembly.sh` and `CecilProcessor/` from this repository to your project root
2. Run:
```bash
chmod +x ProcessAssembly.sh
- ./ProcessAssembly.sh
+ # Pass your Unity editor path (auto-detects macOS/Windows layout):
+ ./ProcessAssembly.sh "/Applications/Unity/Hub/Editor/6000.3.0f1"
```
+ The Cecil processor will auto-detect which internal signatures your Unity version uses and emit the correct IL.
## Usage Examples
@@ -123,7 +125,18 @@ The library uses Mono.Cecil to:
- **Platforms**: Android, WebGL, macOS, Windows, Linux, iOS
- **Build Types**: Mono and IL2CPP
-- **Unity Version**: 6000.0.31f1 and later
+- **Unity Version**: 6000.0.31f1 through 6000.3.x (validated)
+
+### Unity 6000.3 (Unity 6.3) Notes
+
+Unity 6000.3 changed the internal signature of `UnityEngine.Object.GetPtrFromInstanceID`:
+
+| Version | Signature |
+|---------|-----------|
+| 6000.0 - 6000.2 | `IntPtr GetPtrFromInstanceID(int instanceID, Type objectType, out bool isMonoBehaviour)` |
+| 6000.3+ | `IntPtr GetPtrFromInstanceID(int instanceID, out bool isMonoBehaviour)` |
+
+The Cecil processor detects the parameter count at build time and emits the correct IL, so the same source works across both version ranges. If you upgrade Unity, just re-run `ProcessAssembly.sh` against the new editor install.
## Performance Benefits
@@ -173,19 +186,24 @@ If you want to modify the library or rebuild for a different Unity version:
# Make the script executable
chmod +x ProcessAssembly.sh
-# Run the processor
+# Run the processor (defaults to 6000.0.31f1, or pass your Unity path):
./ProcessAssembly.sh
+./ProcessAssembly.sh "/Applications/Unity/Hub/Editor/6000.3.0f1"
+
+# Or via environment variable:
+UNITY_PATH="/path/to/editor" ./ProcessAssembly.sh
```
This will:
- Build the CecilProcessor from source
-- Compile the source code from `Runtime~/`
-- Process the assembly with Cecil to inject IL code
+- Compile the source code from `Runtime~/`
+- Auto-detect internal API signatures from your Unity install
+- Process the assembly with Cecil to inject the correct IL
- Output `ExposedBindings.dll` to the `Plugins/` folder
### Customizing for Different Unity Versions
-1. Update Unity path in `ProcessAssembly.sh` if needed
-2. Modify `CecilProcessor/Program.cs` if internal signatures changed
+1. Pass your Unity editor path to `ProcessAssembly.sh` (macOS and Windows layouts auto-detected)
+2. The Cecil processor inspects method signatures at build time — no manual code changes needed for known API variations
3. Test thoroughly on your target Unity version
### Build and Distribution (For Maintainers)