Closed38

Unity ARFoundationをレコーディングできるようにしたい

Koki IbukuroKoki Ibukuro

やりたいこと

  • ARアプリをUnityで作るのに毎回実機ビルド面倒くさいので、ビルド無しでシミュレーションできるようにしたい。
  • 私個人的に100%リモートワークなので、現地でしか動かないようなARを、録画ファイルを送ってもらって、Unity Editor上で再現する見たいなことをしたい。
  • Geospatial APIのような、公式ARFoundationにはないオプション情報もExtra Trackとしてタイムラインに埋め込みたい。
  • Machine Learningの画像認識とかと連動できるように、ARKitとARCoreの画像と同じフォーマットで再生できると嬉しいが… (ARKitはYCrCbで、2枚のテクスチャ、ARCoreはRGBのテクスチャが飛んでくる。)

リサーチ

AR-Testing

AR Foundation Editor Remote, AR Simulation, Unity MARSの比較をしてくれているのでとりあえずここをみると良さそう

AR Foundation Remote 2.0

第一候補。

Pros

  • エディタ専用でUnityとつなげたiPhone(ARKit), Android(ARCore)を録画する機能がある。多くのAR機能を録画してくれる。実際に仕事で使っている。
  • 値段と節約できる時間を考えるとARやるひとはみんな買っても良さそう

Cons

  • 録画できる画質とフレームレートが荒いので、Maschine Lerningで画像認識できなくもないが、認識精度も体験もかなり劣る感じ

Unity MARS

Unity公式のAR, XRシュミレーター

Cons

  • サブスクで$50/month。
  • ARFoundationの上に更にMARSのWrapperを乗っけて、xRグラスとかも含めた抽象化してる。
  • 画像認識のシュミレーションとかはできなそう
  • ar-simulationのGitHubでも言及されているように、抽象的で分厚いWrapperじゃなくて、ただARFoundationをUnity Editor上で実行したいだけなのに、どうしてこうなった感。

ARKitとARCoreの公式機能

ARKitStreamer

Pros

  • 自分で作ったので自分の欲しい機能を足せる

Cons

  • ARCoreには対応してない
  • URP対応まだしてない
  • NDIをつかっているため、iOSはNDIライブラリのインストールが必須。Unity Cloud Buildできない。(プライベート案件ならソースコードに入れちゃってもいい気がするけど、OSSなので)
    • この制約のせいで、Unity CloudBuildなどのCIに組み込めないのが個人的につらい。CI大好き
  • 録画機能ない
  • 動画とその他情報を別々に送っているので、若干タイムラインにずれがある。

Bibcam by Keijiro

別リポジトリでAvfiというミニマムなrecording/playbackの仕組みも用意してくれている。使いやすそう。

Pros

  • 動画の中にAR上のカメラの座標、回転メタデータを埋め込むことで完全同期
  • フレームレートも早い

Cons

  • 大量のデータを埋め込めない
  • ARFoundationの上に作られてはいないので、シミュレーションをできるわけでは無い
Koki IbukuroKoki Ibukuro

自分で作るとしたら

keijiroさんのBibCamの仕組みをベースにして、動画にメタデータをエンコードするのではなく、meta data timelineとして、mp4に埋め込みたいかな。

Unityで再生する仕組みを用意しないといけなくなるけど…。

AVFoundationでバイナリデータのトラックを追加するのはこのへんで行けそうな

https://developer.apple.com/forums/thread/88276
https://developer.apple.com/documentation/avfoundation/avassetwriterinputmetadataadaptor

Koki IbukuroKoki Ibukuro

AppleのARKitをXcode上でシミュレーションための動画を録画するアプリReality Composerで録画した動画の中身を

ffmpeg -i sample.mov

でみてみると、以下のように大量のMetadataストリームを確認した。これはARKitのメタデータを上述の仕組みで埋め込んでいるやつだと思う。

13:35:21
ffmpeg version 4.4.1-tessus  https://evermeet.cx/ffmpeg/  Copyright (c) 2000-2021 the FFmpeg developers
  built with Apple clang version 11.0.0 (clang-1100.0.33.17)
  configuration: --cc=/usr/bin/clang --prefix=/opt/ffmpeg --extra-version=tessus --enable-avisynth --enable-fontconfig --enable-gpl --enable-libaom --enable-libass --enable-libbluray --enable-libdav1d --enable-libfreetype --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libmysofa --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvmaf --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-version3 --pkg-config-flags=--static --disable-ffplay
  libavutil      56. 70.100 / 56. 70.100
  libavcodec     58.134.100 / 58.134.100
  libavformat    58. 76.100 / 58. 76.100
  libavdevice    58. 13.100 / 58. 13.100
  libavfilter     7.110.100 /  7.110.100
  libswscale      5.  9.100 /  5.  9.100
  libswresample   3.  9.100 /  3.  9.100
  libpostproc    55.  9.100 / 55.  9.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'sample.mov':
  Metadata:
    major_brand     : qt
    minor_version   : 0
    compatible_brands: qt
    creation_time   : 2022-05-30T04:13:49.000000Z
    com.apple.framework.state.MOVStreamIO: <?xml version="1.0" encoding="UTF-8"?>
                    : <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
                    : <plist version="1.0">
                    : <dict>
                    : 	<key>default_options</key>
                    : 	<dict>
                    : 		<key>MIOBitrateMultiplier</key>
                    : 		<real>1</real>
                    : 		<key>MIOBitrateOverride</key>
                    : 		<integer>0</integer>
                    : 		<key>MIOBossMode</key>
                    : 		<false/>
                    : 		<key>MIODisableFrameReordering</key>
                    : 		<false/>
                    : 		<key>MIOForce10bitMonoByVT</key>
                    : 		<false/>
                    : 		<key>MIOForceColorLossless</key>
                    : 		<false/>
                    : 		<key>MIOForceLossless8bitMonoByVT</key>
                    : 		<false/>
                    : 		<key>MIOLogAppendTimeStamps</key>
                    : 		<false/>
                    : 		<key>MIOLogPrepareRecording</key>
                    : 		<false/>
                    : 		<key>MIOSkipSourceHint</key>
                    : 		<false/>
                    : 	</dict>
                    : 	<key>version</key>
                    : 	<string>3.17.10b</string>
                    : </dict>
                    : </plist>
                    :
    com.apple.framework.state.MOVKit: {"extrinsicsSWToW":[0.9999387264251709,-0.0010817100992426276,-0.011017407290637493,-8.9610586166381836,0.0010484313825145364,0.99999487400054932,-0.0030258949846029282,16.653076171875,0.011020624078810215,0.0030141586903482676,0.99993473291397095,-1.6000
    com.apple.recordingEnvironment: {"extrinsicsSWToW":[0.9999387264251709,-0.0010817100992426276,-0.011017407290637493,-8.9610586166381836,0.0010484313825145364,0.99999487400054932,-0.0030258949846029282,16.653076171875,0.011020624078810215,0.0030141586903482676,0.99993473291397095,-1.6000
  Duration: 00:00:54.39, start: 0.000000, bitrate: 115785 kb/s
  Stream #0:0(und): Video: hevc (Main) (hvc1 / 0x31637668), yuvj420p(pc, smpte170m/bt709/bt709), 1920x1440, 39827 kb/s, 59.96 fps, 60 tbr, 16800 tbn, 16800 tbc (default)
    Metadata:
      rotate          : 90
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Video
      vendor_id       : [0][0][0][0]
      encoder         : HEVC
    Side data:
      displaymatrix: rotation of -90.00 degrees
  Stream #0:1(und): Data: none (mebx / 0x7862656D), 252 kb/s (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:2(und): Video: hevc (Main) (hvc1 / 0x31637668), yuvj420p(pc, smpte170m/bt709/bt709), 640x480, 4433 kb/s, 10 fps, 10 tbr, 16800 tbn, 16800 tbc (default)
    Metadata:
      rotate          : 90
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Video
      vendor_id       : [0][0][0][0]
      encoder         : HEVC
    Side data:
      displaymatrix: rotation of -90.00 degrees
  Stream #0:3(und): Data: none (mebx / 0x7862656D), 42 kb/s (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:4(und): Video: hevc (Main) (hvc1 / 0x31637668), yuvj420p(pc, smpte170m/bt709/bt709), 1280x720, 13303 kb/s, 59.90 fps, 59.94 tbr, 16800 tbn, 16800 tbc (default)
    Metadata:
      rotate          : 90
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Video
      vendor_id       : [0][0][0][0]
      encoder         : HEVC
    Side data:
      displaymatrix: rotation of -90.00 degrees
  Stream #0:5(und): Data: none (mebx / 0x7862656D), 238 kb/s (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:6(und): Data: none (mebx / 0x7862656D), 14138 kb/s (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:7(und): Data: none (mebx / 0x7862656D), 16981 kb/s (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:8(und): Data: none (mebx / 0x7862656D), 131 kb/s (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:9(und): Data: none (mebx / 0x7862656D), 570 kb/s (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:10(und): Data: none (mebx / 0x7862656D) (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:11(und): Data: none (mebx / 0x7862656D), 552 kb/s (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:12(und): Data: none (mebx / 0x7862656D) (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:13(und): Data: none (mebx / 0x7862656D), 237 kb/s (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:14(und): Data: none (mebx / 0x7862656D) (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:15(und): Data: none (mebx / 0x7862656D), 1854 kb/s (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:16(und): Data: none (mebx / 0x7862656D) (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:17(und): Data: none (mebx / 0x7862656D), 654 kb/s (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:18(und): Data: none (mebx / 0x7862656D), 5394 kb/s (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:19(und): Data: none (mebx / 0x7862656D), 8637 kb/s (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
  Stream #0:20(und): Data: none (mebx / 0x7862656D), 8637 kb/s (default)
    Metadata:
      creation_time   : 2022-05-30T04:13:50.000000Z
      handler_name    : Core Media Metadata
Koki IbukuroKoki Ibukuro

恐らく、videoのタイムラインに同期したmetadataをmp4に同梱するところまではできた。

https://github.com/asus4/Avfi/tree/metadata

次のステップはmp4の再生機能。videoをUnityのテクスチャに反映 & Raw byte dataを送信する

ffmpeg -i record_0707_1737_00.MP4                                                                                                                                                                                                                                            17:37:48
ffmpeg version 4.4.1-tessus  https://evermeet.cx/ffmpeg/  Copyright (c) 2000-2021 the FFmpeg developers
  built with Apple clang version 11.0.0 (clang-1100.0.33.17)
  configuration: --cc=/usr/bin/clang --prefix=/opt/ffmpeg --extra-version=tessus --enable-avisynth --enable-fontconfig --enable-gpl --enable-libaom --enable-libass --enable-libbluray --enable-libdav1d --enable-libfreetype --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libmysofa --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvmaf --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-version3 --pkg-config-flags=--static --disable-ffplay
  libavutil      56. 70.100 / 56. 70.100
  libavcodec     58.134.100 / 58.134.100
  libavformat    58. 76.100 / 58. 76.100
  libavdevice    58. 13.100 / 58. 13.100
  libavfilter     7.110.100 /  7.110.100
  libswscale      5.  9.100 /  5.  9.100
  libswresample   3.  9.100 /  3.  9.100
  libpostproc    55.  9.100 / 55.  9.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'record_0707_1737_00.MP4':
  Metadata:
    major_brand     : qt
    minor_version   : 0
    compatible_brands: qt
    creation_time   : 2022-07-07T15:37:01.000000Z
  Duration: 00:00:11.42, start: 0.000000, bitrate: 7762 kb/s
  Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 7744 kb/s, 58.25 fps, 240 tbr, 600 tbn, 1200 tbc (default)
    Metadata:
      creation_time   : 2022-07-07T15:37:01.000000Z
      handler_name    : Core Media Video
      vendor_id       : [0][0][0][0]
      encoder         : H.264
  Stream #0:1(und): Data: none (mebx / 0x7862656D), 11 kb/s (default)
    Metadata:
      creation_time   : 2022-07-07T15:37:01.000000Z
      handler_name    : Core Media Metadata
At least one output file must be specified
Koki IbukuroKoki Ibukuro

Unityのテクスチャにbyte arrayをネイティブ側で突っ込む事例

https://github.com/keijiro/TextureUpdateExample/blob/master/Plugin/Plasma.c

メタデータを受け取るには2種類の方法があるらしい。

https://github.com/robovm/apple-ios-samples/blob/1f6b14ef6e2bda610ef8f1c93b16bf76b8594fbb/AVMetadataRecordPlayTimedMetadataCaptureRecordingandPlayback/README.md

There are a few different ways to retrieve timed metadata from a QuickTime movie, depending on what an application wants to do:

For offline processing of media (such as an export operation), an AVAssetReader can be used. In this case, an AVAssetReaderOutputMetadataAdaptor provides AVTimedMetadataGroups from metadata tracks in the QuickTime movie. This technique is demonstrated by the AVLocationPlayer sample code.

AVMetadataRecordPlay demonstrates how to visualize timed metadata during realtime playback. The app implements a class conforming to the AVPlayerItemMetadataOutputPushDelegate protocol, which creates an AVMutableComposition, and plays the composition with an AVPlayerItem. Detected face metadata is shown by drawing bounding boxes on the video where faces were detected. Video orientation metadata is "visualized" as the app updates the video track's display layer's transform property. Location (GPS) metadata is shown as a string in a UI label.

Koki IbukuroKoki Ibukuro

最新のARFoundationへの組み込みを試している。

https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@5.0/changelog/CHANGELOG.html

CHANGELOGを追う感じ、ARFoundation 5.0.2から、ARBackgroundRendererFeatureをUnityEditorでも実行してくれるようになったのはいいが、M1 macでフリーズするという問題があり、解決したとか言われているが、全然再現するぞ…。

https://github.com/KirillKuzyk/AR-Foundation-Remote-support/issues/13
https://github.com/Unity-Technologies/arfoundation-samples/issues/994

Koki IbukuroKoki Ibukuro

ARFoundation 5.0.2の大きな変更点として、Overdrawを避けるために、Opaquesパスの後にカメラのバックグランドを表示する機能。ってのがあるらしい。

この辺の内容↓
https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@5.0/manual/migration-guide-5-x.html#arcamerabackground-arcameramanager-and-xrcamerabackgroundrenderingmode

でもURPで以前のBeforeOpaquesを使おうとすると、Clear()を挟まれて、何も描画されなくなるというバグがある。誰も気にしてないのかな…。クリーンなプロジェクトでも再現する。

Koki IbukuroKoki Ibukuro

調べた感じXRInputSubsystemはネイティブプラグインを読み込むことが前提になってるぽい。ARFoundation, XRのAPI設計はモジュール化を意識しすぎたあまり、冗長になり、逆にちょっとこういったツールを作りたいときに拡張性がない。

https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@5.1/manual/implement-a-provider.html
https://docs.unity3d.com/Manual/xrsdk-input.html

ネイティブプラグイン化しなきゃだめなSubsystems

C#からも登録できるようにしてくれてもいいのに。

Koki IbukuroKoki Ibukuro

ARFoundation 5.0.2で、シュミレーター機能がついた。これのおかげで、XRTextureDescriptorなどのプロパティが全部プライベートになっていたstructにコンストラクタがついて、C#からも生成できるようになったのは良い。

以前はネイティブ側からしかstruct生成できないので、Unityシュミレーターを作ろうとすると少しトリッキーな生成をする必要があった。

以前使っていた方法↓
https://asus4.hatenablog.com/entry/2019/10/18/_Unity_AR_FoundationをEditor上でシミュレーションする方法

Koki IbukuroKoki Ibukuro

Unity 2022.2.0 ベータ 、VideoPlayerがエディタでフリーズするという致命的なバグにあたった。
https://forum.unity.com/threads/in-10894-multiple-video-players-running-simultaneously-freeze-up-the-editor-build-in-2022-2-0b2.1314180/

URP Version 14.0.2はバグがあるから、Unityを最新に上げたいものの、最新にあげるとVideoPlayerが動かないという積んでるやつ。
https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@5.0/manual/migration-guide-5-x.html#urp-version-1402-incompatibility

Koki IbukuroKoki Ibukuro

Avfiから出力した動画がVideoPlayerで動かないの調査。

カラースペース設定されてないよってWarningが出ていたので、

https://www.youtube.com/watch?v=IXYKhZdGF6s
https://en.wikipedia.org/wiki/Rec._709
https://en.wikipedia.org/wiki/Rec._2020
https://en.wikipedia.org/wiki/Rec._2100

この辺を参考にベーシックなカラースペースっぽい ITU_R BT.709を設定。カラースペースの警告は消えたが、依然直らず。

// Add color property settings
    NSDictionary* colorPropertySettings =
    @{
        AVVideoColorPrimariesKey: AVVideoColorPrimaries_ITU_R_709_2,
        AVVideoYCbCrMatrixKey: AVVideoTransferFunction_ITU_R_709_2,
        AVVideoTransferFunctionKey: AVVideoYCbCrMatrix_ITU_R_709_2,
    };
    // Asset writer input setup
    NSDictionary* settings =
      @{ AVVideoCodecKey: AVVideoCodecTypeH264,
         AVVideoWidthKey: @(width),
         AVVideoHeightKey: @(height),
         AVVideoColorPropertiesKey: colorPropertySettings,
      };

    _writerInput =
      [AVAssetWriterInput assetWriterInputWithMediaType: AVMediaTypeVideo
                                          outputSettings: settings];

が依然として、ビデオプレーヤーでバグが出ることを確認。

2021.3.12f1: OK
2022.1.20f1: OK
2022.2.0b13.112.4548: NG

と、2022.2で一新されたとされるビデオプレーヤーの問題。

Koki IbukuroKoki Ibukuro

一ヶ月待って、バグレポ回答が来た。多分2022.2のTech Stream リリースへ向けて忙しかったんだろな。

2022.2で変更入ったビデオプレーヤーではVariable Frame Rateに対応しないというRegression. 2023 の最新アルファで直したよーと返答きた。2022 LTSにbackporting してくれって連絡しようかな。

とりあえず2023で開発してみるか

The comment below has been added to your bug report: IN-22670: A Unity Employee (Dominique Leroux) has responded to this issue: Hi, Thanks for reporting this problem, we'll try to address this as best as we can. The reason the clip is not playing correctly is because it has a variable frame rate. E.g.: there is a long gap between the two first frames: the first is at t=0, second is at t=0.3333s, third at .35s, fourth at .3666s and so on. These types of clips, while they have worked better in the past on AVFoundation and are also working better on Windows Media Foundation, are not perfectly well supported (e.g.: seek may not be giving expected results). But we should at least be able to bring back the same level of support there was prior to 2022.2 - where the regression happened. Until the fix gets integrated into a release, you should use clips that have a constant frame rate (CFR). Most softwares are better behaved with these clips. To create a constant frame rate version of the clip you provided that has the issue, you can use ffmpeg: ffmpeg -i freeze-video.mp4 -vsync cfr cfr-video.mp4 This is of course not optimal for image quality, since this causes a re-encoding. Ideally, the video would be produced directly with constant frame rate, but it is frequent for mobile devices to produce movies that have variable frame rate because they may vary the exposure time depending on lighting conditions, thus modulating the frame rate. Hope this helps, Dominique Leroux A/V developer at Unity

Koki IbukuroKoki Ibukuro

2022 LTSにバックポートをお願いしている。これが治らんことにはどうにもならんが

Koki IbukuroKoki Ibukuro

2022年最新版へのバックポートがリジェクトされたって連絡きた。まあ実装適当なのが目にみえてわかったので…。

Koki IbukuroKoki Ibukuro

今日時間があったので、少し見た。AVFoundationのレコードするときに、無理やり固定フレームレートにする(やや現実の時間とずれるが)方法を見つけたのでこの問題を回避できそうな。

またこの現象を確認したことで、なぜ他の録画系のアセット NatCorderなどでwarm upのメソッドが実装されているのかが理解できた。初回の録画だけやたら遅い…。 どこ時間がかかっているのかちゃんとプロファイルをとってみたほうが良いかもしれない。

Koki IbukuroKoki Ibukuro

動画がなんとかなったので、見ぬふりをしていた、


https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@5.1/manual/implement-a-provider.html
https://docs.unity3d.com/Manual/xrsdk-input.html

ネイティブプラグイン化しなきゃだめなSubsystemsを見ているが、XRSDKの通りにやってみたがEditorで読み込んでくれない。インターネット上に実装例がほぼないので、よーわからない。

実機ではどうなってるんだろうと、ARKitで動いてるアプリを実行して、Input Debuggerで見てみると、以下のようにデバイスはHandheldARInputDeviceが登録されているのが確認できる。


Koki IbukuroKoki Ibukuro

XR SDKでXRInputSystemをネイティブプラグインで作らなきゃいけないし、ドキュメントもないしでわからなかったのだが、

新Input Systemで独自デバイスを作って、C#クラスから、HandheldARInputDeviceのイベントを発行することができた。ハックではあるが直接カメラのTransfromをいじるよりはいささか丁寧。

https://github.com/asus4/ARFoundationReplay/blob/f65ac1a5383e9890ecb97efce5021c6233463aeb/Packages/com.github.asus4.arfoundationreplay/Runtime/Subsystems/ARReplayInputSubsystem.cs

Koki IbukuroKoki Ibukuro

長らくXR SDKのネイティブプラグインの使い方が分からなかったのだが、頑張って実装できた気がする。

実装した変更点はここ。最低限のXR SDK実装として参考になる気がする。
https://github.com/asus4/ARFoundationReplay/pull/3

XR SDKについては英語でもGitHubでもUnity 公式でも実装方法についてほぼ情報が無いので別にまとめたい。

まとめる際の要点

  • UnitySubsystemsManifest.jsonがちゃんと読み込まれてるかはEditor Logを [Subsystems] で検索して確認。
  • 同様にXR SDKのログには prefix [XR] がつくのでそれで検索。
  • 読み込まれるネイティブプラグインは相対パスのUnitySubsystemsManifest.json 以下に配置しなくてはいけない。フォルダストラクチャが厳しい。
    • XR SDKのサンプルをコピーしてから開発を始めるといいかもしれない。
  • package.jsonのkeywordsに"xreditorsubsystem"が入っていないと駄目。
Koki IbukuroKoki Ibukuro

ずっとXRSDK native pluginを作るときに何故か、UnitySubsystemsManifest.jsonが読み込まれない問題。しかもなぜかサンプルでは読み込まれてるけど、自分の新規プロジェクトではどうやっても読み込まれない問題があり、3日くらい色々試していたのだが、

自分のpackage.json"xreditorsubsystem" ってキーワードが無いとそもそも読み込み対象に入らないということが判明。

"keywords": [
    "xreditorsubsystem"
  ],

あらゆるドキュメントを漁ったけどどこにも書いてなくて、Verified Solutions Partnerになって、開発者から聞かないとわからないやつじゃん…。これだからクローズドソースは。

このスクラップは2023/10/11にクローズされました