ソースコードを改造してMagicaCloth2をWebGLでも無理やり動かせるようする方法を解説していきます。
※旧MagicaClothをWebGLで動かす場合はこちら
ソースコードの改造は自己責任でお願いします。
本記事はMagicaCloth2 バージョン2.0.0の内容となります。
初版という事もあり、バージョンアップによって変更箇所が変わる可能性はかなり高いです。ご注意ください。
最新版のchrome、firefox、Microsoft Edgeで動作確認済みです。
目次
結論
・動かない原因は『Task』
・UniTaskを使えばWebGLでも動作可能
・ただしWebGLではマルチスレッド非対応なので『UniTask.Create』を使う
・自己責任で!
Magica Cloth 2とは
2023年2月11日に公開された、Magica Clothの後継版です。
旧Magica Clothと同様にボーン、メッシュ両方を揺らすことが可能な他、旧MagicaClothではシミュレーションさせるために複数のコンポーネントが必要だったり、導入の手順がややこしかったのですが、Magica Cloth 2では1個のコンポーネント(+必要なコリジョン)だけで簡単に実装できるようになっています。
・Asset Store
https://assetstore.unity.com/packages/tools/physics/magica-cloth-2-242307
・公式サイト
で、そんな新しくなったMagica Clothの公式サイトには
・WebGLを除くすべてのプラットフォームで動作可能
https://magicasoft.jp/mc2_about/
残念ながら、WebGLはMagica Cloth 2になっても非対応らしく、実際にWebGLでビルドしてもシミュレーションしてくれません。
しかも旧MagicaClothの時とは異なり、エラーログは一切出現しません。
なのでそのままじゃ動きませんし、なんなら旧MagicaClothで行った対応方法も効果がありません
(そもそも現versionのMagicaCloth2のソースコード内にComputeShaderは存在しません)
原因
先述の通りMagicaCloth2にComputeShaderが使われているコードはありません。
ですので、別の処理がWebGLの動作を阻害している事になります。
それで調査した結果、どうやらWebGLで動かない原因はマルチスレッド処理を行う『Task』でした。
Taskとは非同期処理を行う機能なのですが、そのTaskには『SynchronizationContext』というマルチスレッドを行うための機能(?)が内部搭載されているらしいです。
で、WebGLはマルチスレッド非対応なため『SynchronizationContext』が搭載されたTaskクラスを用いると動かなくなる、という事らしいです。
※私はマルチスレッド関連に全く詳しくないため、ここら辺の情報は間違っている可能性があります。鵜呑みにはせず、正しい情報を各自で調べてください。
対応
先のとおりTaskではWebGLが動かせないもののasync awaitは使用する必要があります。
ですので、Taskを使用している箇所は『SynchronizationContext』を搭載していないUniTaskに書き換えていきます。
UniTaskの導入
まずは下記のURLから最新版のUniTaskをダウンロードしてプロジェクトに追加します。
https://github.com/Cysharp/UniTask
MagicaCloth2のAssemblyにUniTaskの参照を追加
プロジェクトにUniTaskを追加したら、次はMagicaCloth2のAssenbly Definition AssetにUniTaskの参照を追加します。
これによってMagicaCloth2のソースコード内で、UniTaskが使えるようになります。
Taskを全てUniTaskに書き換え
v2.0.0時点の内容ですが、Magica Cloth2のソースコードでTaskが使われているクラスは1個だけです。
そのクラス内にあるTaskを全てUniTaskに置き換えていきます。
ただし、『Task.Run』はマルチスレッドに移行する処理なので、『UniTask.Run』とは書き換えずにちょっと工夫する必要があります。
WebGLで実行させる場合は『Task.Run(() =>』 を『UniTask.Create(() =>』に変更します。
これでシングルスレッドのまま非同期処理を行うことが出来ます。
ただ、このままだとWebGL以外の時もシングルスレッドで動いてパフォーマンスが下がるので、WebGL以外の時は『UniTask.RunOnThreadPool』を使うように分けた方がよいです
また、関数を変更する事によって、第二引数にはboolしか渡せないエラーや(UniTask.RunOnThreadPooi)、第ニ引数を指定できないエラー(UniTask.Create)が発生します。
なので、それぞれの第二引数もちゃんと変更する必要があります。
Task.Runの変更前(ラムダ式の後に記述されてる箇所)
以上の改造によって、WebGLでも動作するようになります
改造したMagica Cloth2でWebGLビルドしたものはこちら
注意
改造は自己責任でお願いします!
上記対応によってエラーが出たからと言って、公式にDMやバグレポートを送らない様に!
コード改造して出現したエラーは自力で対応しましょう。
また、本対応は2023/2/17時点の最新バージョンであるv2.0.0での対応となります。
バージョンアップによって対応箇所が変化する可能性がるので、ご注意ください。