From 5ac658b721f984fda40da11fff164961b8472f86 Mon Sep 17 00:00:00 2001 From: Clement James Date: Fri, 26 Jun 2026 13:47:40 +0100 Subject: [PATCH 1/4] chore: Update FRAMEWORK_SEARCH_PATHS to use recursive search for UnityFramework in podspec --- engines/unity/dart/ios/gameframework_unity.podspec | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/engines/unity/dart/ios/gameframework_unity.podspec b/engines/unity/dart/ios/gameframework_unity.podspec index 720c02e..cad4094 100644 --- a/engines/unity/dart/ios/gameframework_unity.podspec +++ b/engines/unity/dart/ios/gameframework_unity.podspec @@ -42,8 +42,12 @@ to sync your Unity export to your plugin's ios/ directory. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386', - # Search for frameworks in the local directory (symlink), Pods build directory, and sibling plugins - 'FRAMEWORK_SEARCH_PATHS' => '$(inherited) "${PODS_TARGET_SRCROOT}" "${PODS_CONFIGURATION_BUILD_DIR}" "${PODS_ROOT}/../.symlinks/plugins/*/ios"', + # Find UnityFramework wherever the consumer plugin vendors it. NOTE: Xcode + # does NOT expand a single `*` in search paths, so "plugins/*/ios" never + # resolves for hosted (pub.dev) installs — it only worked when `game sync` + # planted a symlink in this pod's own dir. Use Xcode's recursive `**` + # syntax, which searches all subdirectories under the plugins symlink dir. + 'FRAMEWORK_SEARCH_PATHS' => '$(inherited) "${PODS_TARGET_SRCROOT}" "${PODS_CONFIGURATION_BUILD_DIR}" "${PODS_ROOT}/../.symlinks/plugins/**"', # Allow weak linking to UnityFramework 'OTHER_LDFLAGS' => '$(inherited) -ObjC' } From 86e14ac2f03d89fb0c0c102b191592537b880d6f Mon Sep 17 00:00:00 2001 From: Clement James Date: Fri, 26 Jun 2026 15:02:07 +0100 Subject: [PATCH 2/4] chore(unity): release gameframework_unity 0.0.4 Bump version and add CHANGELOG entry for the iOS FRAMEWORK_SEARCH_PATHS fix so the corrected podspec can be published to pub.dev (0.0.3 cannot be re-published). Co-Authored-By: Claude Opus 4.8 (1M context) --- engines/unity/dart/CHANGELOG.md | 13 +++++++++++++ engines/unity/dart/pubspec.yaml | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/engines/unity/dart/CHANGELOG.md b/engines/unity/dart/CHANGELOG.md index 2db2502..de29ff6 100644 --- a/engines/unity/dart/CHANGELOG.md +++ b/engines/unity/dart/CHANGELOG.md @@ -2,6 +2,19 @@ All notable changes to the gameframework_unity package will be documented in this file. +## [0.0.4] - 2026-06-26 + +### Fixed +- **iOS:** resolve the `UnityFramework` Swift module on hosted (pub.dev) installs. + The podspec's `FRAMEWORK_SEARCH_PATHS` used a single-`*` glob + (`.symlinks/plugins/*/ios`) that Xcode does not expand, so consumers of the + published package failed to build for iOS with + `Unable to resolve module dependency: 'UnityFramework'`. It only worked when + `game sync` planted a symlink in this pod's own directory — which never + happens for hosted installs. Switched to Xcode's recursive `**` search syntax, + which finds the consumer plugin's vendored `UnityFramework.framework` with no + `game sync` symlink and no Podfile workaround. + ## [0.0.3] - 2026-02-06 ### Changed diff --git a/engines/unity/dart/pubspec.yaml b/engines/unity/dart/pubspec.yaml index 2be5bdd..38f0bcf 100644 --- a/engines/unity/dart/pubspec.yaml +++ b/engines/unity/dart/pubspec.yaml @@ -1,6 +1,6 @@ name: gameframework_unity description: Unity Engine plugin for GameFramework. Provides Unity integration with bidirectional communication, AR Foundation support, and WebGL capabilities. -version: 0.0.3 +version: 0.0.4 homepage: https://github.com/xraph/gameframework repository: https://github.com/xraph/gameframework issue_tracker: https://github.com/xraph/gameframework/issues From 77ddd2fa8575c091772aecb43bcfde0271e0354c Mon Sep 17 00:00:00 2001 From: Clement James Date: Mon, 29 Jun 2026 19:30:26 +0100 Subject: [PATCH 3/4] chore: update gameframework_unity dependency to version 0.0.4 --- example/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 68ea247..2f5df45 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -23,7 +23,7 @@ dependencies: gameframework: 0.0.3 # Unity plugin - gameframework_unity: 0.0.3 + gameframework_unity: 0.0.4 # Unreal plugin gameframework_unreal: 0.0.3 From a56dc06de6765a31b606d380371d6078ada0ba53 Mon Sep 17 00:00:00 2001 From: Clement James Date: Mon, 29 Jun 2026 19:40:47 +0100 Subject: [PATCH 4/4] chore: Clean up debugPrint statements and formatting in UnityControllerWeb --- engines/unity/dart/lib/src/unity_controller_web.dart | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/engines/unity/dart/lib/src/unity_controller_web.dart b/engines/unity/dart/lib/src/unity_controller_web.dart index 9c16b47..c49aa24 100644 --- a/engines/unity/dart/lib/src/unity_controller_web.dart +++ b/engines/unity/dart/lib/src/unity_controller_web.dart @@ -205,10 +205,8 @@ class UnityControllerWeb implements GameEngineController { 'streamingAssetsUrl': '$buildUrl/StreamingAssets', 'companyName': _getConfigValue('companyName') ?? 'DefaultCompany', - 'productName': - _getConfigValue('productName') ?? 'Unity Game', - 'productVersion': - _getConfigValue('productVersion') ?? '1.0', + 'productName': _getConfigValue('productName') ?? 'Unity Game', + 'productVersion': _getConfigValue('productVersion') ?? '1.0', }); _emitProgress(0.3); @@ -336,7 +334,8 @@ class UnityControllerWeb implements GameEngineController { _makeEnvelope(msg.target, msg.method, msg.data), ]); } catch (e) { - debugPrint('Failed to flush queued message ${msg.target}.${msg.method}: $e'); + debugPrint( + 'Failed to flush queued message ${msg.target}.${msg.method}: $e'); } } } @@ -352,8 +351,7 @@ class UnityControllerWeb implements GameEngineController { 'Unity WebGL message queue full ($_maxQueueSize). Dropped oldest message.'); } _messageQueue.add(_QueuedMessage(target, method, data)); - debugPrint( - 'Unity WebGL not ready. Message queued: $target.$method ' + debugPrint('Unity WebGL not ready. Message queued: $target.$method ' '(${_messageQueue.length}/$_maxQueueSize)'); return; }