UnityプロジェクトにSwiftUIを載せる

https://davidpeicho.github.io/blog/unity-swiftui-integration-revisited/

SwiftのプロジェクトにUnityのビューを載せて、さらにその上にSwiftUIのビューを表示するというのが正しいかもしれません。
現在のところUnity製アプリにSwiftUI固有のビューを表示するには上記の記事の方法しか無いようです。

環境
Xcode14.1
Unity2021.3.16
AdmobやFireBaseも載っています。
この環境で実機ビルドが通っているのを前提とします。

https://github.com/DavidPeicho/unity-swiftui-example/tree/main

まずDavidPeichoさんのサンプルコードをDLしてその中のUnityappフォルダの中から以下のファイルを自分のUnityにコピーする。場所は必ずサンプルと同じ場所に。

**Assetes > Editorには**
AutoBuilder.cs

**Assetes > Plugin > iOS　には**
API.swift
NativeCallProxy.h
NativeCallProxy.mm
UnityCommunicationProtocol.swift
UnityFramework.modulemap

**Assetes > Scripts には**
API.cs

をそれぞれ配置する。
これでiOS実機ビルドが成功しているプロジェクトにAppend。それを実機ビルドするとおそらく起動直後に以下のようなエラーが出る。
```error
objc[4928]: Class CLSUserDefaults is implemented in both /System/Library/Frameworks/ClassKit.framework/xxxxxxxxxxxxx/UnityFramework.framework/UnityFramework (0x1110f0290). One of the two will be used. Which one is undefined.
objc[4928]: Class FrameworkLibAPI is implemented in both /private/var/containers/Bundle/Application/xxxxxxxxxxxxx/Frameworks/UnityFramework.framework/UnityFramework (0x1110c1698) and /private/var/containers/Bundle/Application/B7654130-918B-4201-B814-A2FE3D95D98C/xxxxxxxxxxxxx. One of the two will be used. Which one is undefined.
```

これはXcodeの
Product > Scheme > Edit Scheme... > Run で以下のチェックを外すことで解消できる（はず）
![スクリーンショット 2023-01-17 16.15.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117011/6eac8994-75cf-ca21-668e-904da1fcb1b8.png)

ここからこのUnityのビューをSwiftに載せていきます。ここまでで詰まったときはトップの記事の原文もしっかり読むことをお勧めします。

DavidPeichoさんのサンプルコードからsandboxフォルダをコピーしておく
Xcodeで　File > New > Workspace を作り、ここでは名前をUnitySwiftUIとする
これを先ほど吐き出したiOSプロジェクト、sandboxフォルダと同じ場所に保存する
![スクリーンショット 2023-01-18 11.07.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117011/660fbfd7-dd07-4c8c-2370-0b0e28c7c0b9.png)

UnitySwiftUI.xcworkspaceを開いて以下の左カラムに以下のファイルをドラッグで追加する
sandbox.xcodeproj
Unity-iPhone.xcodeproj(iosプロジェクトの中)
Pods.xcodeproj（iosプロジェクト > Pods の中）
![スクリーンショット 2023-01-18 11.11.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117011/c91d550b-d56c-0c6a-5587-38963612b28f.png)
これでsandboxをビルドすると、SwiftUIの上にUnityのビューが載っているという形になるのだが、ビルドを通すまでにいろいろエラーが出る。

sandboxの Minimum deployment をUnity-iPhoneと同じにそろえる
![スクリーンショット 2023-01-18 11.18.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117011/8544efa9-7703-afb6-b3a3-503ca6cb759b.png)

Bundle identitifierもUnity-iPhoneと同じにそろえる![スクリーンショット 2023-01-18 11.23.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117011/571a7a9e-a8d9-2123-f1f8-7784f381d9ee.png)

Xcode左カラムの　sandbox >　Frameworks > UnityFrameWorkを一旦削除して、自分のプロジェクトのものに差し替える。
TARGET > sandbox > BuildPhases > Link Binary With Libraries から追加。


info.plist関連のエラーを無くすために、sandboxの中のinfo.plistをUnity-iPhoneの中のinfo.plistで置き換える。
このままだと
```
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no storyboard/xib was provided.'
```
というエラーが出るのでstoryboardの名前をsandboxの中のものに変更する![スクリーンショット 2023-01-18 12.42.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117011/c34af153-bbbd-7823-4fd1-0e532d9f4b5d.png)

ここでもProduct > Scheme > Edit Scheme... > Run で以下のチェックを外します![スクリーンショット 2023-01-17 16.15.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117011/97fadcd4-7c80-f751-ca1a-98f2ebb9cc3f.png)


これで実機ビルドして、アプリの画面中央にカラーピッカーボタンが表示されていれば成功です。![IMG_19456ADCE8C7-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117011/18ea233f-e5a7-167f-3bce-ec97e00a302d.jpeg)

ただし、このままではAdmobは表示されませんし、アプリを閉じたり開いたりした時のデリゲートも通っていません。
ここからは以下のサンプルコードも非常に参考になります。

https://note.com/hrkd/n/n2bb5fbbd407b

追加2023/11/29
AdmobのSwiftUI版の実装で広告の表示には成功したがインターステシャル、リワードの全画面広告で閉じるボタンを押下しても広告が閉じるまでに4秒の遅延が発生するという致命的な不具合が発生。3日費やしたが改善せず。結局ApplovinのSDKで実装してみると遅延が発生せずに広告を閉じることを発見した。
現在はApplovinのMAXのメディエーションを通してAdmobインターステシャル、リワードを表示。Admobの単独でバナー、起動時広告を表示している。どちらもSwiftUI側に実装しないと表示されないのでご注意を。