公式サンプルゲーム「復讐する王子と竜が残した剣」に同梱されている ReplaceCodesAddon をもちいて、IL2CPP 環境下でも動作するメソッド差し替えを行う方法を紹介します。
(サンプルゲーム作者の Toya Shiwasu 様から記事化の了承を頂きました。)
- サンプルゲームの動作環境は v1.00.00 が指定されていますが、本記事で紹介する ReplaceCodesAddon は v1.00.01 でも動作します。
目次
- まえがき (対象読者など)
- ReplaceCodesAddon のダウンロード
- Code Analysis パッケージの追加 (ダウンロード)
- ReplaceCodesAddon の導入
- 実際にメソッド置き換えを行うアドオンの作成
- アドオンの有効化・動作確認と無効化
- 本記事のメソッド書き換え例 (タイトル BGM 変更) の説明
- 補足:アドオンのユーザーに行っていただく必要がある手順
- おわりに
- 主な更新履歴
まえがき (対象読者など)
前回の記事で紹介していた方法 (関数ポインター差替) では、IL2CPP では動作しないという問題がありました。そのため、iOS 版など一部プラットフォームへの対応ができませんでした。
2023-06-27 に公開された公式サンプルゲーム作者の Toya Shiwasu 様も、公式フォーラムに投稿されたとおり、IL2CPP の問題に直面し、対処策を講じる必要が出てきました。
その結果、サンプルゲーム作者が編み出したのが Unity の Code Analysis 機能を使用して C# Script の構文解析を行い、指定メソッドのみを直接差し替える方法です。
簡単に言うと、
- オリジナルのソースコードのバックアップ、参照
- 変更対象となるメソッドの差し替え、差し戻し
をアドオン経由で自動化するアプローチです。
本記事では、実際に本機能を実現する ReplaceCodesAddon (公式のサンプルゲームに同梱) をもちいて、IL2CPP 環境下でも動くメソッド差し替えを行う方法を紹介していきます。(アドオン付属の readme の内容を噛み砕いて説明しています)
対象読者もアドオン作者向けとなっていますので、あらかじめご了承ください。
- 前回の記事で説明した内容 (IL2CPP でのビルド方法も含む) は省略していますので、適宜参照していただけますよう、よろしくお願いいたします。
ReplaceCodesAddon のダウンロード
本記事執筆時点 (2023-06-29) では、ReplaceCodesAddon は単独では公開されていません。
公式サンプルゲーム「復讐する王子と竜が残した剣」のダウンロードページの使用規約に目をとおしたうえで、右下の「同意してプロジェクトファイルをダウンロード」リンクからプロジェクト環境一式 (psr_1.0.zip) をダウンロードして下さい。
Code Analysis パッケージの追加 (ダウンロード)
ReplaceCodesAddon は、Unity の Code Analysis パッケージに依存しているため、新規プロジェクトに導入する際は Package Manager 経由で Code Analysis を追加する必要があります。
- サンプルゲーム「復讐する王子と竜が残した剣」のプロジェクトをそのまま使用する場合は、既に Code Analysis パッケージが含まれていますので、本手順は不要です。
新規プロジェクトに Code Analysis パッケージを導入するための手順
前提として、新規 Unity プロジェクトに RPG Maker Unite のアセットを組み込んだ直後の「まっさらな状態」を推奨します。
(特に初めて試す場合は、余計なトラブルを避けるため、なるべく新しいプロジェクトで試すことをおすすめします)
Unity 本体の「ウィンドウ」メニューから「パッケージマネージャー」を開きます。
左上の「+」ボタンをクリックし、「GIT URL からパッケージを加える...」を選びます。
ダウンロード元の URL 入力が求められますので、以下の URL を貼り付けて「追加」をクリックします。
com.unity.code-analysis
ダウンロードが正常に完了すると、Code Analysis のバージョン情報が表示され、その直後に Unity Editor が「自動的に」再起動します。
再起動が完了した後、Unity 本体側の「プロジェクト」タブで Packages フォルダの中身を確認し、Code Analysis パッケージが存在していれば組み込み完了です。
ReplaceCodesAddon の導入
サンプルゲーム「復讐する王子と竜が残した剣」のプロジェクト環境 (psr_1.0.zip) を任意の場所に解凍し、Assets\RPGMaker\Codebase\Add-ons\ReplaceCodesAddon を開きます。
この ReplaceCodesAddon フォルダーを丸ごと、導入先 Unity プロジェクトのまったく同じ場所にコピーします。
コピー元のプロジェクトファイルに残っている拡張子 .meta のファイルが悪さをしないように、「念のため」削除します。
- .meta ファイルには当該 Unity プロジェクト環境にファイルをインポートしたり、インポート後にカスタマイズした際のプロジェクト固有情報が保存されるため、一般的には、コピー元とは「無関係」の別プロジェクトにファイルを持っていく際には削除した方が無難です。
Editor フォルダーの中も同様に、拡張子 .meta のファイルを削除します。
組み込み先プロジェクトの Unity Editor 画面に戻ると、自動的にインポートが始まりますので、しばらく待ちます。
インポート完了後、Unity Editor の操作ができるようになったら、アドオン一覧に ReplaceCodesAddon が追加されていることを確認します。
(この時点では、まだ ON にする必要はありません)
実際にメソッド置き換えを行うアドオンの作成
本記事の例では、実際に ReplaceCodesAddon を使用してタイトル画面 (TitleController.cs) の PlayBgm() の定義を上書きし、戦闘用 BGM が流れるように変更します。
アドオンの名称 (フォルダー名) は ReplaceCodesAddonUseSample とします。
ReplaceCodesAddonUseSample アドオンの新規作成
アドオン設置先のフォルダー (※ ReplaceCodesAddon を入れた場所と同階層です) に、ReplaceCodesAddonUseSample という名称で空のフォルダーを新規作成します。
ReplaceCodesAddonUseSample の中に、さらに replaceinfo フォルダーと ReplaceCodesAddonUseSample.cs の 2 ファイルを新規作成します。
さらに、replaceinfo フォルダーの中に ChangeTitleBGMToBattle.txt を新規作成します。
ReplaceCodesAddonUseSample アドオンの中身の追加
ソースコード (.cs) およびテキストファイル (.txt) の中身については、実際に動かしてみた後で解説しますので、現時点では以下の指示どおりにコピペして下さい。
ReplaceCodesAddonUseSample.cs に貼り付ける内容
/*: * @addondesc Usage Sample of ReplaceCodesAddon * @author SuzukiYE(Yakuentei) * @help This is a usage sample of ReplaceCodesAddon. */ /*:ja * @addondesc ReplaceCodesAddon の使用サンプル * @author 鈴木YE(役演亭) * @help ReplaceCodesAddon の使用サンプルです。 */ namespace RPGMaker.Codebase.Addon { public class ReplaceCodesAddonUseSample { } }
ChangeTitleBGMToBattle.txt に貼り付ける内容
Assets/RPGMaker/Codebase/Runtime/Title/TitleController.cs method PlayBgm replace SoundManager.Self().SetData(SoundManager.SYSTEM_AUDIO_BGM, system.bgm.battleBgm); await SoundManager.Self().PlayBgm(); SoundManager.Self().SetData(SoundManager.SYSTEM_AUDIO_SE, system.soundSetting.ok); SoundManager.Self().ChangeBgmState(config.bgmVolume); SoundManager.Self().ChangeSeState(config.seVolume);
アドオンの有効化・動作確認と無効化
アドオンの有効化
アドオンリストから、ReplaceCodesAddon と ReplaceCodesAddonUseSample の両方を有効化します。
当該プロジェクトで初めて有効化する場合のみ必要な追加手順
当該プロジェクト環境において初めて ReplaceCodesAddon を使用する場合に限り、Unity 本体側に追加された Replace Codes → Backup Original Codes を選択し、オリジナルのソースコードのバックアップを実行します。
- ReplaceCodesAddon では、オリジナルの RPG Maker Unite ソースコードをもとに C# Script の書き換えを行うため、ReplaceCodesAddon を使用するプロジェクトでは初回に限り本手順を実行して、必ずオリジナルのソースコードを残しておく必要があります。
バックアップ完了メッセージが「コンソール」タブに出力されるので確認します。
オリジナルの RPG Maker Unite ソースコードは、Assets\RPGMaker\Codebaseの直下に「.CoreSystem」「.Editor」「.Runtime」というドット付きのフォルダー名でバックアップされます。(これらのフォルダーの中身が、メソッド差し替え時の参照元コードとなります)
アドオンの動作確認
まず最初に、Replace Codes → Replace Codes を選択し、メソッド置き換えを実行します。
「コンソール」タブに置換完了メッセージが表示されるので、指示どおりに Ctrl + R を押下し、プロジェクトの再読み込み (C# Script のビルド) をかけます。
実際に書き換え対象となった Assets\RPGMaker\Codebase\Runtime\Title\TitleController.cs の中身が書き換えられていることを確認します。
(PlayBgm() メソッドにおいて、system.bgm.title になっていた箇所が system.bgm.battleBgm に変わっているはずです)
実際にゲームを実行し、タイトル画面で戦闘 BGM が流れていることが確認できれば成功です。
アドオンの無効化
無効化するときは、アドオンリストで無効化する前に、必ず「Replace Codes → Revert Original Codes」を実行して元のソースコードを全部復元する必要があります。
- アドオンリストで無効化するだけだと、書き換えた C# ソースコードの内容が残ったままとなるため、事実上アドオンが有効になったままになります。
「コンソール」タブに復元完了メッセージが表示されるので、指示どおりに Ctrl + R を押下し、プロジェクトの再読み込み (C# Script のビルド) をかけます。
復元完了後、アドオンリスト側で無効化を行います。
本記事のメソッド書き換え例 (タイトル BGM 変更) の説明
ReplaceCodesAddonUseSample.cs について
実は、ReplaceCodesAddonUseSample.cs は単なるダミーで、実際には何も処理していません。より正確に言えば、RPG Maker Unite 本体にアドオンとして認識させるためだけに存在しています。
実際のアドオンの中身の処理は、事実上、ChangeTitleBGMToBattle.txt に貼り付けた内容となります。
ChangeTitleBGMToBattle.txt について
ReplaceCodesAddon が実際に行っていることは以下のとおりです。
- アドオンリストで有効 (ON) になっている全アドオンについて、replaceinfo フォルダーがあるかどうかをチェックする。
- replaceinfo フォルダーに含まれているすべての .txt ファイルの中身を確認する。
- 各 .txt ファイルの中身の指示 (=記述) にしたがって、指定されたメソッドの書き換えを行う。
そのため、本記事の例では、ReplaceCodesAddon 側で ChangeTitleBGMToBattle.txt の読み込みが行われ、TitleController.cs の PlayBgm() メソッドの書き換えを行っています。
- 実際に実用可能なアドオンを作る際は、一般的には複数の .txt ファイル (拡張子が .txt にさえなっていればファイル名は任意) を replaceinfo フォルダーの中に格納して、複数のメソッドを書き換えることになるでしょう。
テキストファイルの中身の書式の解説
それでは、改めて ChangeTitleBGMToBattle.txt に貼り付けた内容を確認してみましょう。
Assets/RPGMaker/Codebase/Runtime/Title/TitleController.cs method PlayBgm replace SoundManager.Self().SetData(SoundManager.SYSTEM_AUDIO_BGM, system.bgm.battleBgm); await SoundManager.Self().PlayBgm(); SoundManager.Self().SetData(SoundManager.SYSTEM_AUDIO_SE, system.soundSetting.ok); SoundManager.Self().ChangeBgmState(config.bgmVolume); SoundManager.Self().ChangeSeState(config.seVolume);
1 行目 : 書き換え対象のソースコードのパス指定
最初の 1 行目で、書き換えたい対象となるソースコードを指定します。
パス区切りは \ (バックスラッシュ、日本語環境では「円」記号) ではなく / (スラッシュ) となりますのでご注意下さい。
Assets/RPGMaker/Codebase/Runtime/Title/TitleController.cs
2 行目 : 書き換え対象の種別を指定
現時点では、ReplaceCodesAddon で書き換えが可能なものはメソッドのみであるため、必ず method と記述します。(将来のバージョンで、メソッド以外の書き換えが可能になったときに使用される可能性があります)
method
3 行目 : 書き換え対象のメソッド名を指定
本記事の例では、TitleController.cs の PlayBgm() メソッドが書き換え対象となるため、PlayBgm を指定しています。
PlayBgm
4 行目 : 書き換え方式の指定
ReplaceCodesAddon で指定できる書き換え方式は、以下の 3 種類です。
- replace (メソッドの中身を指定コードで上書き)
- appendToHead (オリジナルの記述を残し、その直前に指定コードを追加)
- appendToTail (オリジナルの記述を残し、その直後に指定コードを追加)
本記事の例では、書き換え対象は最初の 1 行のみですが、純粋な追加 (appendToHead, appendToTail) では対処ができませんので、replace を指定しています。
replace
しかし、実際には、appendToHead, appendToTail で対応可能な場合は、できる限りこれらで対応するように検討した方が (Unite のバージョンアップや他のアドオンとの競合を防ぐ観点から) 丁寧だと言えるでしょう。
5 行目以降 : 実際に置き換え (または追加) するソースコードの指定
本記事の例では、4 行目で replace を指定したので、メソッドの中身が以下の内容で完全に上書きされます。
SoundManager.Self().SetData(SoundManager.SYSTEM_AUDIO_BGM, system.bgm.battleBgm); await SoundManager.Self().PlayBgm(); SoundManager.Self().SetData(SoundManager.SYSTEM_AUDIO_SE, system.soundSetting.ok); SoundManager.Self().ChangeBgmState(config.bgmVolume); SoundManager.Self().ChangeSeState(config.seVolume);
補足:特別な記述 <ORIGINAL_CONTENT> について
例えば 4 行目で replace を指定した際、以下のように記述することで、オリジナルのソースコードの前後両方にアドオン用の C# コードを追加することができます。
// 元コードの直前にコードを挿入 <ORIGINAL_CONTENT> // 元コードの直後にコードを挿入
例えば、以下は 4 行目で appendToHead を指定した場合と等価です。
// 元コードの直前にコードを挿入 <ORIGINAL_CONTENT>
同じく、以下のように書けば appendToTail 相当の書き換え動作となります。
<ORIGINAL_CONTENT> // 元コードの直後にコードを挿入
より実用的なアドオンを作るためのヒント
実際に、アドオンコピー元の「復讐する王子と竜が残した剣」のプロジェクトフォルダー内に、作者 (Toya Shiwasu 様) 自身が ReplaceCodesAddon をもちいて制作されたアドオンがいくつか入っています。
各アドオンの replaceinfo フォルダー内に格納されている多数のテキストファイル (メソッドの書き換え指示記述) の内容が、実用的なアドオンを作るうえで参考になるはずです。
補足:アドオンのユーザーに行っていただく必要がある手順
ReplaceCodesAddon は、その仕組み上、導入手順が他のアドオンに比べて複雑です。
ReplaceCodesAddon を使用したアドオンを一般公開して不特定多数のユーザーに使っていただく際、本記事で説明している以下の手順を、アドオン作者でなくても理解できるように噛み砕いて説明する必要があります。
ReplaceCodesAddon に対応した複数のアドオンが存在する場合
ReplaceCodesAddon そのものは汎用的に作られているので、複数のアドオン間で共有することが可能ですが、ソースコードの書き換えの順番や内容によってはアドオン間で競合を起こす可能性もあるので、注意が必要でしょう。
また、メソッド書き換えは、本記事でも説明したとおりチェックが ON になっているアドオン (の中に含まれている replaceinfo フォルダーの中身) すべてが対象となりますので、アドオンの有効化・無効化の手順も複雑になることが予想されます。
今後、ReplaceCodesAddon のバージョンアップにより改善される可能性もありますが、アドオン作者の方は今までのツクールのプラグイン以上に警戒・配慮が必要と思われますので、ソースコードの書き換えの挙動や順番、癖などを熟知・研究しておく必要があると思われます。
RPG Maker Unite 本体のバージョンアップ時に必要な対応
RPG Maker Unite 本体のバージョンアップが行われた場合、ほぼ確実にオリジナルのソースコードに変更が入ることになるでしょう。
したがって、ReplaceCodesAddon を導入済みのプロジェクトでは RPG Maker Unite 本体のバージョンアップを行う「前」に以下の対応が必要です。
1. バックアップされているオリジナルのソースコードを復元
Revert Original Codes を実行し、すべてのコードをオリジナルの状態に戻しておきます。
2. アドオンの無効化
ReplaceCodesAddon を使用しているすべてのアドオンを無効化します。
3. バックアップフォルダーの手動削除
バージョンアップ後の再バックアップ処理で問題が起こらないようにするため、以下のバックアップフォルダー (.CoreSystem, .Editor, .Runtime の 3 つ) を「手動で」すべて削除します。
4. RPG Maker Unite 本体のバージョンアップ
公式サイトに記載されているアップデート手順にしたがって、RPG Maker Unite 本体のバージョンアップを行います。
- バージョンアップ後に必要なアドオンの有効化手順は、本記事の「アドオンの有効化・動作確認と無効化」で既に説明しているとおりですが、これをユーザーに行っていただくのは、もちろん新バージョンでも動作することが確認されている場合のみです。
- ユーザーには、Replace Codes → Backup Original Codes も再度行っていただく必要がありますのでご注意下さい。
おわりに
本記事では、公式サンプルゲーム「復讐する王子と竜が残した剣」に同梱されているアドオンをもちいた、IL2CPP 環境下でも使用可能なメソッド書き換え方法を紹介しました。
これにより、RPG Maker Unite で対応可能なすべてのプラットフォームで動かすことのできるアドオンを制作・公開することが現実味を帯びてきたと思います。
本記事執筆時点 (2023-06-29) の RPG Maker Unite は、最初のバージョンアップ (v1.00.01) が行われた直後でもあり、まだ不具合も多い状況です。
しかし、公式サンプルゲーム 8 本の公開にともなって、公式サンプルゲーム作者による高度なノウハウ (本記事で紹介したメソッド置き換え手法も含む) も研究できるようになりましたので、今後の RPG Maker Unite の盛り上がりに期待できるのではないかと筆者は考えております。
本記事を読まれたプラグイン・アドオン作者の方が、実際に iOS 版など IL2CPP 環境下でも動作可能なアドオンを作るうえで本記事の内容を活かしていただけたら幸いです。(サンプルゲーム作者の Toya Shiwasu 様も喜ぶと思います)
主な更新履歴
- 2023-06-29
- 初版
- (当日夜追記)「アドオンの有効化・動作確認と無効化」に以下の項を追加。
- より実用的なアドオンを作るためのヒント
- (当日夜追記)「補足:アドオンのユーザーに行っていただく必要がある手順」に以下の項を追加。
- RPG Maker Unite 本体のバージョンアップ時に必要な対応