※主にC#の話です
結論:
・マルチプラットフォーム開発したい! → やめとけ
プラットフォーム固有のバグや変な仕様、制約を飲み込み、かつ開発者登録料や本人確認書類、審査のめんどくささなどすべて理解した上でそれでもやりたいというなら…
・ネイティブAPI叩いてパフォーマンスも重視したい! → Blazor Hybrid
・多少重くても知ってるHTML/CSSでやりたい! → 任意のPWAアプリ / Electron
・マルチいらんかも → WPF とかお好きなものを
まず、なぜマルチプラットフォームが必要か?
そもそもなぜマルチプラットフォーム(以下マルチPF or 単にマルチ)が必要なのか?
巷では狂ったようにマルチPFが謳われていますが、ここではマルチPF展開するということについてもう少し考えたいと思います。
まずマルチPF開発をするとすると、単純にその労力は実に「2倍」になります。
IDEや環境が優秀なのでついつい勘違いしがちですが、基本的にはアプリを2つ同時開発することと同義だと思ってください。
MAUIやBlazorなど種々のマルチPF開発環境ではせいぜいこれが1.5倍くらいかな?がんばって圧縮されたとしてその程度が限界で、そこにデバッグやデザイン調整、デバイスに最適化するコーディングは勿論、手を動かしていない時間も考慮すると2倍どころか2.5倍くらいには膨れ上がるのが実情で、基本的には単独ロンチのほうが圧倒的に楽です。
労力が2倍になる。これはつまり、個人なら当初2ヶ月だった計画を4ヶ月に伸ばせばいい話ですが、
組織的には2倍の人件費がかかるという意味でもあります。
つまりマルチPF展開をするということは、単独リリースよりも当然収益が見込め、倍以上の人件費をかけつつそれでも大きなリターンを回収できる、そんな計画がないと土台にすら上がらないものなのです。
なので「なんとかなくマルチPF開発したいなぁ~とりあえずAndroidとiOSとWindowsくらいは対応したいな!」とか軽く思ってると地獄を見ます。
今でこそ良いソリューションが出てきましたが、Xamarinもなく、XcodeとAndroid Studioで個別に書かなければいけない時代はできてAndroidとiOSのモバイル2対応、そこからWindowsやブラウザ展開など夢のまた夢でした。(&もちろんそこから地獄のバージョン・ハードウェア対応管理が始まる)
さて、ここで市場を見た時にもっともマルチPF展開が目立つのはゲームだと思います。最近はコンソール・PC・モバイル問わずリリースされているのが当たり前になってきています。これはゲームエンジンが最初からマルチPFに対応していることやコンソール側が汎用PC寄りになってきたこと、環境やノウハウが整備されてきたことなど複合的な要因があると思いますが、ここで大事なのは「マルチPFという手段はあくまで手段でしかない」ということです。
「売れるからマルチPFにする」べきであって、「とりあえずマルチPFにしておけば売れるだろ」はNGです。
結局消費者は「欲しいものを知った時点で勝手に自分から近づいていく」ので、たとえコンソールやPCを持っていなくても、ゲームソフトをどうしてもやりたいなら多少遅くなってもいつかは必ず買います。
マルチPF展開するとどんなハードでも満遍なく売れるように錯覚しがちですが、当たり前ですが1人のプレイヤーが同じ作品を何本も買うことはほぼありません。なので実際は大半が所有率や稼働率がもっとも高いデバイスでプレイします。これはつまりせっかく苦労してマルチPF開発したところで、結局売上的には覇権プラットフォームでの単体ロンチと大差ないのです。
特にゲームの場合はハードウェア最適化でソフトウェアパフォーマンスに如実の差が出ることと、各ハードの独自機能や遊び方の差が非常に大きくなります。そのため最初から「マルチPF開発が目的化」していると、ゲームコンセプトとしても独自ハード機能は極力使わず、必然的に均質で同じゲーム体験になります。
「どれでもできる」は得てして「別にどれでもいい」という極めて消極的な印象になりうるということです。
「均質で均一、同じ」という性質はメリットにもデメリットにもなります。
ユーティリティ的なアプリは「どこでもどれでも同じことができる」という面で機能的均質さはメリットです。
一方でゲームは斬新さや興奮、楽しさという面でどれも同じゲーム体験だったらつまらないですよね?
アプリでは均質であることは機能面ではメリットでしたが、ゲームでは体験面からは完全にデメリットとなります。つまりゲームでマルチPF対応はひとつの手段どころか、本来取ってはいけない手段ですらあるとも言えます。
大事なのは「戦略上、まずユーザーを想定する。その上でマルチPF開発が必要かどうか検討する」という、戦略的判断を忘れてはいけないということです。
「でも俺はマルチPF開発ノウハウを身に着けたいんだ!」という考えもあるかもしれません。私にもあります。
ですが、「ノウハウ目的でマルチに手を付けた結果、みんなに還元するのが遅延して実装も中途半端になった」なんて目も当てられないと思いませんか?「慣れてる〇〇環境なら3分で終わったボタンの実装に、仕様理解やら想定外のバグやらアップデートでの挙動変更やらで3日もかかったあ~」というなら考え直したほうがいいと思います。
少し前置きが長くなってしまいましたが、闇雲にマルチプラットフォーム開発を始めたところで、疲弊し地獄を見るのは明らかです。本来やりたかったはずの素晴らしいアイディアを泣く泣く「マルチでは実装できないから」という本末転倒な理由で諦めるハメになる……そんなことにならないよう、マルチPFでの開発について考えてみてください。
– – – – – –
マルチPF開発環境の比較
Electronだけあんまり触ってないですが、他はある程度開発経験済みなのでかなり辛辣なところもありますがリアルな感想になっているかと思います。
– | MAUI | Avalonia | Electron | Blazor Hybrid |
---|---|---|---|---|
特徴 | 旧Xamarin。C#でwin/mac/android/ios/linuxなどあらゆるアプリ開発が可能。(という願望) | サードパーティ開発のマルチPFで、知名度の割に意外と歴史が長い。 | Chromium ブラウザベースで、Webページのノウハウが活かせる。 (WebViewが共通化したような感じ) | Blazor と WPF のいいとこ取り。 Blazor はC#の機能(for文やLINQなど)を使いつつもブラウザとしてHTML/CSSでのデザインをしたり、一方でデスクトップ版.NET APIの機能(MsgBoxやHWINDなど)も利用可能 |
デスクトップ | Win/mac | Win/mac | Win/mac | Win/mac |
モバイル | Android/Apple | Android/Apple | Android/Apple | Android/Apple |
ブラウザ | 対応 | 対応 | 対応 | 対応 |
言語 | C# | C# | Electron | C# |
所感 | ❌️ WPF XAMLとはかなり違う上、WPFやUWPではできた細かいプロパティ、動作、コントロールの充実度、カスタムやグラフィックスが非常に弱く、タッチ感重視のモバイル環境ではショボく感じる。 あと言うほどマルチPFでのデバッグが楽じゃない | ❌️ MAUIよりはマシだが変な思想が入っており所々中途半端に変更されている。(ResourceDictionaryの記法や、Style指定がClassesになっていたり。) そのためWPFとAvaloniaの仕様がごっちゃになり検索汚染がすごい | ? C#とは当然違うがHTML/CSSなので世の中のデザインや機能的ノウハウが豊富なのでWeb経験があるならスムーズ。(XAMLもHTMLもマークアップなので当然か) | 🔵 記法は違うものの、むしろHTML/CSSでC#が使えるという喜び感のほうが大きい。 |
「進歩的学習か?」(後述) | NO | NO | YES | YES |
アニメーション | ▲ 微妙 (コードではやりやすくなったがトータルでは「?」) | ▲ 微妙 | 🔵 CSS/JS | 🔵 CSS/JS |
カスタム | ❌️ 劣化WPF | ▲ 微妙 | 🔵 | 🔵 |
デザイン性 | ❌️ WPFでもUWPでもない | ❌️ 劣化WPF | 🔵 | 🔵 |
設計思想 | 中途半端 | 中途半端 | 明確 | 明確 |
知識の焼き増し | ❌️ あり | ❌️ あり | 特になし | 特になし |
開発難易度 | 😡 地獄 | 🤢 地獄よりはマシ | 😊 良き | 😊 良き |
メンテナンス性 | ★☆☆☆☆ | ★☆☆☆☆ | ★★★☆☆ | ★★★☆☆ |
パフォーマンス | ★★★☆☆ | ★★★☆☆ | ★★☆☆☆ | ★★~★★★★★ |
検索性 | ❌️ WPF, UWP, さらには.NETのバージョン毎に混在しておりカオス | ❌️ 同左 | ? | ▲ まだ歴史が浅い |
公式Doc | ❌️ 頼りない | ❌️ 肝心な部分がない | ? | ▲ MS感 |
ユーザー記事数 | ❌️ 全然情報がない | ❌️ Githubのバグ報告だけは多い | 🔵 | 🔵 意外と多い |
バージョン安定性 | ❌️ 迷走 | ❌️ 破壊的変更 | ▲ 安定はする | 🔵 |
バグ | ❌️ バグというか公式にやる気がない | ❌️ 非常に多い | 🔵 比較的安定 | 🔵 安定 |
APIやWin32 | ❌️ | ▲ | ❌️ | OK |
プラグイン | 少ない | そこそこ | ? | 少ない |
AIによる補助 | 弱い | 弱い&WPFと混ざって大変 | OK | OK |
特記事項 | 手抜き。Toolkitに頼りすぎ。実際はPFごとに機能や仕様に差がありすぎて苦痛 | 圧倒的にバグが多い。何もかも中途半端 | Chrominium ベースのため、本体の頻繁なアップデートに付き合わなきゃいけない | ほぼWebアプリならWeb部分だけ書いて実装はBlazorじゃなくてもOK |
– – – – – –
ここからは各環境の印象です。メモ書き程度の感想です。
🔵MAUI
👍️ よいところ
・マルチPF開発ができる。
C#のノウハウを活かしながらマルチPF開発ができるのはメリット。
❌️ イマイチ
・溢れ出る開発途上感。
多くのWPFでの機能は実装されておらず、じゃあUWP(ストアアプリ)なのかというとそうでもない。
おそらく設計段階では今後実装していく予定だったのだろうが、思ったより流行らなかったからかMSが本腰を入れていない感じがある。
・アニメーションやコントロールのカスタム、独自実装に弱い。
Windows版はアニメーションが貧弱でデフォルトでは本当に何もない(デスクトップ環境のWPFよりも!)ので、リッチなデザインが当たり前のスマホ環境では尚更見劣りする。
コントロールのカスタムやグラフィックス周りはSkiaなど使えるものはあるがまだMAUIとしては整備されておらず、ちょっと難儀する。
・結局楽じゃない。
マルチPF開発で楽をしたいはずが、結局MAUIのあれこれを吸収するためにWPFでもなければObjective-Cでも、JavaでもHTML/CSSでもないもの、しかも今後うまく発展する見込みがないものを新しく新規学習するということに多大なメリットを見出せなければ厳しい、というのが正直な感想。
🔵Avalonia
👍️ よいところ
・インタラクティブプレビューが良い。
プレビューの段階でボタンのタッチアニメーションも効くのでそこまで見れるのはとても良い。
・マルチPF開発が比較的楽なほう。
MAUI同様なんやかんや自分で別々のコードを書くよりは楽。少なくともWindowsとAndroidは動いた。
❌️ イマイチ
・わかりづらく中途半端。
WPF XAMLとの親和性やスムーズな移行をアピールされているわりに開発側で変な思想を挟み込み、中途半端な独自機能(でもやってることは同じなのでただ学習コストがかかるだけ)を載せたがる。そのため、WPFかと思ったらWPFじゃない、でもWPFっぽいみたいな脳の拒絶反応を引き起こすことがよくある。
変にCSS感出そうとしてStyle指定がしれっと「Classes」になってて「Style=」での指定ではなくなっていたり、BasedOnが使えない、Keyなしでのグローバルスタイル適用ができなくなっていたり……。他にもただでさえWPFの時点でややこしかった Resource Dictionary の指定方法が機能的な中身は特に変わってないのにIncludeとかいう変なタグに変更されていたり、「それ本当にいる?」という中途半端な仕様変更が多い。HTML/CSSが使いたいなら最初からそっちを使っているし、WPF XAMLがマルチPF開発でも使いたいからこうしているのに、Avalonia の設計思想はズレていると感じる。
個人的にこういうとき「それは進歩的学習か?」という点が重要だと思っている。例え新規学習コストがかかってもそれに見合うなら人は喜んで学ぶ。一方で、焼き増しに過ぎないものや、たとえ1ワードの置き換えだけだったとしても新しい価値を生み出せないないなら、それは相当なストレスである。スムーズな移行を謳うなら焼き増しや変な語句の置き換えはすべきではない。Avaloniaの使いにくさの根底はそこにある。
・バグが多い。
本当にバグが多く0.4バージョンくらい上がっても全然修正されていないことが多い。ClipToBoundsなど比較的メジャーな機能でもこれなので付き合うのに疲れる。
・マルチ環境で動かないことがある。
なぜかBrowser版が動かないことがあった。
・変更が多い。
メジャーアップデートでもないのに細かく記法が変わったり、使えた機能が使えなくなったりして過去のWorkaroundが効かなくなったりする。
・Intellisenseが使えない。
自分で定義したStyleやその他Key系の定義がサジェストに出てこないため、記憶を頼りにコーディングする昔の悪いスタイルに戻ってしまっている。せっかく Visual Studio 使ってるのにいいところが潰されている。
(ついでに、axamlという新しい書式扱いなためかフォントカラーがうまく適用されず行番号も出ない、xamlでのregionも使えないなどWPF XAMLに慣れているほどかえって厄介に感じた)
・思っていたよりナレッジがないかもしれない。
WPFやBlazor, MAUIだと検索するとわりと記事やStackOverflowのQAなどがヒットするが、Avaloniaの場合はいつも調べるとGithubで「Avaloniaのバグであり、修正待ちでクローズされたIssue」(そして修正はされていない) しかヒットしないことに気付き始めた。
そのため検索ヒット数はそこそこあるのだが解決可能な情報というよりも「問題が問題として取り上げられているだけ」の情報であり、正直開発としては全く前進しないのでナレッジとして足りなさすぎる部分を感じている。
🔵Blazor Hybrid
👍️ よいところ
・使いやすい。
まずBlazorの部分として、独自のルールはあるにはあるものの、純粋な進歩的新機能として受け止められるので新規学習にあたってストレスがない。覚えることは多いがそれがしっかり結果につながるというポジティブな印象が強い。(Avaloniaで挙げた「それは進歩的学習か?」の問いにBlazorはしっかり答えられていると思う)
既存のHTML/CSSのお作法が通用するというとても大きいメリットがありつつ、そこにおなじみのfor文やデータバインディングなどのモダンな機能が使えるというこれぞC#.NETという感。
さらにさらに Blazor Hybrid ではそこにもう一段ネイティブのデスクトップAPIが引っ張ってこれるという極めて大きなメリットかつ今までの懸念(ネイティブパフォーマンスやMessageBoxなどのデスクトップAPIへのアクセス性など)をまとめて払拭できるという至れり尽くせり。
もちろんHTML/CSSということはブラウザであり、その部分のパフォーマンスや互換性の面で課題はあるものの、グラフィックスや大規模なデータ処理はネイティブ実装に委ねるという選択肢が生まれたのは非常に大きい。
❌️ イマイチ
・まだナレッジが少ない。
Blazorは比較的新しい技術なのでまだWPFやWinFormほど枯れてはいない。だがこれは時間の問題だろうと思う。
・よく競合とわからない。
Blazorの最大のネックはMAUIやその他のマルチPF開発環境と何が違うのか?という点にあると思う。同じMSのC#系でもうMAUIとかXamarinがあるのに何が違うのか?というのが初心者にとってわかりにくくなってしまいっているのが難点。
……
総論
Blazor にしろ、「ブラウザを使うなら別にElectronとかでもいいんじゃないか?ていうか今まで通りWebページとして作っておいて、WindowsでもAndroidでも何でも WebView で乗っけるだけでいいんじゃないか?」という疑問は自然 (実際ほとんどのアプリはそう。実際、ZoomやTeamsはちょっと重くてもWeb版で十分に動いている。アドレス帳もバイブレーションも実はAPIがある)。
正直、 MAUI と Avalonia は開発環境としてレベルが低すぎるのでこのまま素直にクローズしてほしい。(検索汚染という意味でも)
– – – – – –
以上です。
ひとまず現段階: 2025年の結論としては普通の用途なら Blazor Hybrid が良さそうな気がします。C#はUnityでもデスクトップでも使えますし、ゴリゴリのC++が要求されるシビアなパフォーマンス環境でなければパフォーマンスも十分です。
C#未経験勢なら Electron でしょうか。MS Teams や Obsidian は Electron を使っているらしいです。頻繁なバージョンアップについていくのが大変ですが、中身がほぼ Chrome ブラウザでHTML/CSS/JSの知見が通用するのでデザインも機能も実装がとても楽です。
一方でWindowsの機能を使うMessageBoxやウィンドウのハンドリング、いくらハードウェア支援があるからとはいえ基本的にブラウザ実装は重くなりがちだというパフォーマンス面での懸念は拭えません( Teams も Obsidian もUIデザインはいいがわりと重め)。ただ、Web系ならJSが使えるならその流れで React.js も Node.js も使い始めやすいので、スキルの潰しが効くという点でデメリットにはならないでしょう。
ゲームなら Unity / UE かと思いますが、最近は「ゲームエンジンの習得自体が目的化しつつある」のがネックです。
ちなみに挙げなかったものの Python と Gradio でゴリゴリのコードを書くという手もなくはないですが、C系とはだいぶ記法が違うのと、パフォーマンス面で結構遅く感じます。私には Visual Studio の支援なしでUIを書くことは考えられません。(C#から離れられない理由の一つ)
あなたのマルチプラットフォーム開発に幸あらんことを……。