Swift Native Unity Plugins

How to create a plugin for Unity that can be written in pure swift, no objective-c necessary

Project Setup

To ensure Swift files link correctly in Xcode, enable Swift support in one of the following ways:

  • If Google Dependency Resolver is already installed (or you’re comfortable adding it), enable the Enable Swift Framework Support Workaround option.

  • Alternatively, after the Xcode project is generated, manually create a new swift file in the project. Xcode will prompt to configure Swift support; accept to enable it.

Script Setup

To call Swift directly from C#, pay attention to how functions are defined and exposed for interop.

The following examples show a simple structure that supports calling both static and instance methods. Apply your own judgement and best practices for production code.

Swift

Shiki failed: 122 |             brackets: 0,
123 |             doubleApostrophe: 0,
124 |             singleApostrophe: 0
125 |         };
126 |         const name = this.scope.nodeType === NodeTypeEnum.documentNode ? 'Document' : 'Element';
127 |         const error = new this.window.SyntaxError(`Failed to execute 'querySelectorAll' on '${name}': '${selector}' is not a valid selector.`);
                            ^
TypeError: undefined is not a constructor (evaluating 'new this.window.SyntaxError(`Failed to execute 'querySelectorAll' on '${name}': '${selector}' is not a valid selector.`)')
      at getSelectorGroups (/home/runner/work/personal-site/personal-site/node_modules/happy-dom/lib/query-selector/SelectorParser.js:127:23)
      at querySelector (/home/runner/work/personal-site/personal-site/node_modules/happy-dom/lib/query-selector/QuerySelector.js:130:67)
      at main (/home/runner/work/personal-site/personal-site/tools/shiki-render.ts:72:28)

C#

Shiki failed: 122 |             brackets: 0,
123 |             doubleApostrophe: 0,
124 |             singleApostrophe: 0
125 |         };
126 |         const name = this.scope.nodeType === NodeTypeEnum.documentNode ? 'Document' : 'Element';
127 |         const error = new this.window.SyntaxError(`Failed to execute 'querySelectorAll' on '${name}': '${selector}' is not a valid selector.`);
                            ^
TypeError: undefined is not a constructor (evaluating 'new this.window.SyntaxError(`Failed to execute 'querySelectorAll' on '${name}': '${selector}' is not a valid selector.`)')
      at getSelectorGroups (/home/runner/work/personal-site/personal-site/node_modules/happy-dom/lib/query-selector/SelectorParser.js:127:23)
      at querySelector (/home/runner/work/personal-site/personal-site/node_modules/happy-dom/lib/query-selector/QuerySelector.js:130:67)
      at main (/home/runner/work/personal-site/personal-site/tools/shiki-render.ts:72:28)

Additional Notes

  • Ensure the Swift source is placed under a folder within Plugins and is marked as an iOS plugin.

  • Keep function signatures stable and avoid name changes that could break bindings.

  • Prefer small, focused bridging surfaces to keep interop simple and maintainable.

Unity plugin import settings panel showing platform checkboxes with only iOS selected (Editor, Standalone, and Android unchecked).

Troubleshooting

  • If Xcode reports missing Swift symbols, verify that Swift support was actually enabled in the generated project.
  • If you see duplicate symbol or linkage errors, ensure exported function names are unique across files.
  • Confirm the plugin import settings target iOS only, and that the files are included in the build.