Unity を検索

プログラマーのワークフローを高速化しよう

2021年9月27日 カテゴリ: Engine & platform | 10 分 で読めます
Two monitors and a laptop
Two monitors and a laptop
取り上げているトピック
シェア

Is this article helpful for you?

Thank you for your feedback!

最近、2 本のブログ記事「エディターでのワークフローを高速化する 5 つの方法」と「アーティストワークフローをスピードアップ」を公開しましたが、どちらの記事もプロの開発者向けに書かれた e ブック「70+ tips to increase productivity with Unity 2020 LTS」をベースにしたものです。シリーズ 3 回目となる今回のブログ記事では、ワークフローと、プログラマーがより少ない時間でより多くの仕事をこなすために役立つ機能に焦点を当てます。まずは、プレイテスト時のコンパイル時間を短縮する方法からご紹介します。

Enter Play Mode 設定でコンパイル時間を短縮

再生モードに入ると、ビルドと同じようにプロジェクトが実行され始めます。再生モード中にエディターで行った変更は、再生モードを終了するとリセットされます。

エディターで再生モードに入るたびに、Unity は 2 つの重要なアクションを実行します。

  • Domain Reload(ドメインの再ロード):Unity が、スクリプトの状態をバックアップ、アンロード、再作成します。
  • Scene Reload(シーンの再ロード):Unity はシーンを破棄し、再ロードします。

この 2 つのアクションは、スクリプトやシーンが複雑になればなるほど、時間がかかります。

スクリプトを変更する予定がない場合は、Enter Play Mode 設定(Edit > Project Settings > Editor)を活用して、コンパイル時間を短縮してください。Unity には、ドメインの再ロード、シーンの再ロード、またはその両方を無効にするオプションがあります。これにより、再生モードを素早くオン・オフすることができます。

ただし、スクリプトに変更を加える場合は、ドメインの再ロードを再度有効にする必要があることに注意してください。同様に、シーンのヒエラルキーを変更した場合は、シーンの再ロードを再度有効にする必要があります。そうしないと、予期せぬ動作が発生する可能性があります。

The effects of disabling the Reload Domain and Reload Scene settings

アセンブリの管理によるコンパイルのコントロール

アセンブリとは、C# のコードライブラリであり、組み合わせて動作し、機能の論理的な単位を形成するように構築された、型とリソースのコレクションです。デフォルトでは、Unity はほぼすべてのゲームスクリプトを定義済みのアセンブリ、Assembly-CSharp.dll にコンパイルします。これは小さなプロジェクトには有効ですが、いくつかの欠点があります。

  • あるスクリプトを変更すると、そのたびに Unity は他のスクリプトも含めて全部のスクリプトを再コンパイルします。
  • あるスクリプトは、他のスクリプトで定義された型にアクセスできます。
  • すべてのスクリプトがすべてのプラットフォーム用にコンパイルされます。

スクリプトをカスタムアセンブリに整理することで、モジュール性と再利用性が向上します。これにより、デフォルトのアセンブリに自動的に追加されなくなり、あるスクリプトからアクセスできるスクリプトに制限をかけることができます。

上の図のように、コードを複数のアセンブリに分割することがあります。この場合、Main のコードを変更しても Stuff のコードには影響しません。同様に、Library は他のアセンブリに依存しないため、Library のコードを他のプロジェクトで簡単に再利用することができます。

Assemblies in .NET には、C# のアセンブリに関する一般的な情報があります。Unity で独自のアセンブリを定義する方法については、Unity ドキュメントの「Assembly Definitions」を参照してください。

スクリプトテンプレートを使って新しいスクリプトをカスタマイズ

新しいスクリプトを作成する際に、同じ変更を繰り返してしまうことはありませんか。また、何も考えずに名前空間を追加したり、Update イベント関数を削除したりしていませんか。お好みのスタートポイントにスクリプトテンプレートを設定することで、キー操作を省き、チーム全体で一貫性を保つことができます。

新しいスクリプトやシェーダーを作成するたびに、Unity は以下の場所に保存されているテンプレートを使用します。

%EDITOR_PATH%DataResources%ScriptTemplates

  • Windows の場合、これは C:Program Files\Unity\Editor\DataResources\ScriptTemplates となります。
  • Mac の場合、これは /Applications/Hub/Editor/[version]/Unity/Unity.app/Contents/Resources/ScriptTemplates となります。

デフォルトの MonoBehaviour テンプレートはこのファイルです。

81-C# Script-NewBehaviourScript.cs.txt

また、シェーダーやその他のビヘイビアスクリプト、アセンブリ定義などのテンプレートも用意されています。

プロジェクト固有のスクリプトテンプレートについては、Assets/ScriptTemplates フォルダーを作成し、スクリプトテンプレートをこのフォルダーにコピーしてデフォルトを上書きします。

また、すべてのプロジェクトのデフォルトのスクリプトテンプレートを直接変更することもできますが、変更する前に必ずオリジナルのバックアップを取っておいてください。

オリジナルの 81-C# Script-NewBehaviourScript.cs.txt ファイルは次のようになっています。

この 2 つのキーワードを覚えておくと便利です。

  • #SCRIPTNAME# は、入力されたファイル名またはデフォルトのファイル名(例:NewBehaviourScript)を示します。
  • #NOTRIM# は波括弧の中に一行分の空白が含まれていることを保証します。

Unity エディターを再起動すると、カスタムの MonoBehaviour を作成するたびに、変更内容が表示されるようになります。

また、他のテンプレートも同様に変更することができます。オリジナルのコピーと修正したものを、Unityプロジェクト以外の場所に保管しておくことを忘れないでください。

属性を利用してインスペクターなどをカスタマイズ

Unity には、特別な動作を示すために、クラス、プロパティ、関数の上に置くことができる様々な属性があります。C# では、属性名を角括弧で囲みます。 

ここでは、スクリプトに追加できる共通の属性を紹介します。

これは利用可能な数多くの属性のほんの一例に過ぎません。 変数の値を失わずに名前を変更したい場合や、空のゲームオブジェクトを使わずに何らかのロジックを起動したい場合に有用です。スクリプティング API のドキュメントで属性の完全なリストをチェックして、何ができるかを把握しておきましょう。

独自に PropertyAttribute を作成して、スクリプト変数のカスタム属性を定義することもできます。

カスタムウィンドウとインスペクター

Unity の最も強力な機能の 1 つは、拡張可能なエディターです。UI Toolkit パッケージまたは IMGUI モードを使用して、カスタムウィンドウやインスペクターなどのエディター UI を作成します。

UI Toolkit は、標準的な Web 開発と同じようなワークフローを持っています。HTML や XML からヒントを得て作られたマークアップ言語「UXML」を使って、ユーザーインターフェースや再利用可能な UI テンプレートを定義します。その後、Unity Style Sheets(USS) を適用して、UI のビジュアルスタイルや動作を調整します。

また前述のように、即時モードである IMGUI を使うこともできます。まず、Editor を基底クラスとして派生させ、CustomEditor 属性を使用します。

どちらのソリューションでも、カスタムインスペクター を作ることができます。

カスタムエディターでは、インスペクターでの MyPlayer スクリプトの表示方法が変更されています。

UI Toolkit または IMGUI のいずれかを使用してカスタムエディタースクリプトを実装する方法については、「ユーザーインターフェース (UI)」を参照してください。UI Toolkit の簡単な紹介は、「Getting started with Editor scripting」チュートリアルをご覧ください。

Addressable を使用してコンテンツ管理を簡略化する

Addressable アセットシステムは、ゲームを構成するアセットの管理を簡素化します。シーン、プレハブ、テキストアセットなど、あらゆるアセットを「アドレス可能(addressable)」とマークして、一意な名前を与えることができます。このエイリアスはどこからでも呼び出すことができます。

ゲームとそのアセットの間にこのような抽象化された層を挟むことで、個別のダウンロード可能なコンテンツパックを作成するといった作業を効率化することができます。また、このシステムは、ローカル、リモートを問わず、それらのアセットパックを参照することも容易にします。

この例では、Addressables はプレハブの一覧を追跡しています。

Addressables の使用を開始するには、パッケージマネージャーから Addressables パッケージをインストールし、プロジェクトにいくつかの基本的な設定を行います。プロジェクトの各アセットやプレハブには、「addressable」にするためのオプションが必要です。インスペクターのアセット名の下にあるオプションをチェックすると、そのアセットにデフォルトの一意なアドレスが割り当てられます。

Addressable オプションを有効にし、デフォルトの Addressable 名を設定します。

マークすると、対応するアセットが Window > Asset Management > Addressables > Groups を選択して表示されるウィンドウに表示されます。

Addressables Groups ウィンドウでは、各アセットのカスタムアドレスをその場所を組にして確認できます。

使いやすいように、アセットの各アドレスの名前を変更できます。アセットごとに Address フィールドでアドレスの名前を変更することもできますし、すべてのアセットのアドレスを一度に簡略化することもできます。

メニュー操作ひとつで Addressable Name を簡略化したり、個別に名前を変更したりすることができます。

デフォルトのビルドスクリプトを使って、Addressable Group のアセットバンドルを生成します。

これらのアセットをバンドルにして別の場所にあるサーバーでホスティングしたり、プロジェクト内でローカルに配布したりすることができます。各アセットがどこにあっても、システムは Addressable Name に入っている文字列を使ってアセットを見つけることができます。

Addressable API を使って、Addressable アセットを利用できるようになりました。

なお、Addressables がない場合、プレハブをシーンにインスタンス化するためには、以下のコードを実行する必要になります。

この方法の欠点は、参照されたプレハブ(上記の例では prefabToCreate)が、シーンで必要ではなくてもメモリにロードされてしまうことです。

Addressables を使う場合はこのようになります。

この方法では、必要になるまで(CreatedPrefabWithAddress の中で Addressables.Instantiate を呼び出すまで)、プレハブはメモリにロードされません。さらに、Addressables を使用して高レベルの参照カウントを行い、使用されなくなったバンドルとその関連アセットを自動的にアンロードすることができます。

最適化の最前線から:Addressables を使ってメモリを節約する」では、Addressables Groups を整理してメモリ効率を上げる方法の例を示しています。また「Addressables: Introduction to concepts」チュートリアルは、Addressable Asset システムが皆さんのプロジェクトでどのように機能するかを簡潔にまとめた内容となっています。

ライブゲームの運営:Addressables と Cloud Content Delivery の併用

ライブゲームを運営しているのであれば、Unity の Cloud Content Delivery(CCD)ソリューションと Addressables の併用を検討してみてはいかがでしょうか。Addressables システムは、ゲームアセットを保存し、カタログ化することで、ゲームアセットを自動的に見つけ、呼び出すことができます。そして、CCD はそのアセットを、コードとは完全に切り離して、プレイヤーに直接プッシュします。これにより、ビルドサイズが小さくなり、アップデートのたびにプレイヤーが新しいゲームバージョンをダウンロードしてインストールする必要がなくなります。詳しくは、Addressables と Cloud Content Delivery の統合について書いたこのブログをご覧ください。

プリプロセッサディレクティブによるコンパイルの制御

プラットフォーム依存コンパイル機能を使用すると、スクリプトを分割して、特定の対象プラットフォーム向けにコードをコンパイルおよび実行することができます。

この例では、既存のプラットフォーム #define ディレクティブと #if コンパイラーディレクティブを利用しています。

DEVELOPMENT_BUILD #define を使用して、スクリプトが Development Build オプション付きでビルドされたプレイヤーで実行されているかどうかを識別します。

特定の Unity のバージョンやスクリプトバックエンドに合わせて選択的にコンパイルしたり、エディターでテストする際に独自のカスタム #define ディレクティブを指定することもできます。 Other Settings パネル(Player Settings の一部)を開き、Scripting Define Symbols に移動します。

Unity のプリプロセッサディレクティブの詳細については、「プラットフォーム依存コンパイル」を参照してください。

ScriptableObject を活用する

ScriptableObject は、クラスのインスタンスとは別に、大量のデータを保存するデータコンテナーです。ScriptableObject を使うことで値のコピーを避けることができるので、プロジェクトのメモリ使用量を減らすことができます。完全版の e ブックには、ScriptableObjects の使用例もいくつか収録されています。また、アプリケーションで ScriptableObject を使用する際の詳細については、ScriptableObject のドキュメンテーションをご覧ください。

さらに詳細な情報をお探しの方は、「Better data with ScriptablesObjects in Unity」を見て概要をざっと掴み、「ScriptableObject を使ってシーンワークフローを改善しよう」を読んで ScriptableObject がどのようにシーン管理に役立つかを確認してください。

最適化のヒント

保存するデータは、JSON や XML などのテキストベースのものではなく、MessagePackProtocol Buffers などのバイナリ形式のシリアル化フォーマットを推奨します。プロジェクトレビューにおいて、これらのバイナリ形式のシリアル化フォーマットは、テキストベースのフォーマットにありがちなメモリやパフォーマンスの問題を軽減します。

好みの IDE を使う

Unity は、以下の統合開発環境(IDE)をサポートしています。

  • Visual Studio:Windows および macOS のデフォルトの IDE
  • Visual Studio Code(VS Code):Windows、macOS、Linux に対応
  • JetBrains Rider:Windows、macOS、Linux に対応

これら 3 つの環境に対応した IDE 統合は、パッケージマネージャーにパッケージとして表示されます。

パッケージとしての IDE 統合

Windows や macOS に Unity をインストールすると、デフォルトで Visual Studio がインストールされます。他の IDE を使用したい場合、Unity > Preferences > External Tools > External Script Editor でエディターを指定するだけで使うことができます。

Rider は ReSharper を基礎にして作られており、ReSharper のほとんどの機能を含んでいます。Unity の .NET 4.6 スクリプトランタイムでの C# デバッグをサポートしています(C# 8.0)。詳細については、JetBrains 社の Rider for Unity に関するドキュメントを参照してください。

VS Code は、デバッグ、タスク実行、バージョン管理をサポートする、無料の合理化されたコードエディタです。なお、Unity では、VS Codeを使用する場合、Mono (macOS および Linux)、Visual Studio Code C#Visual Studio Code Debugger for Unity (公式にはサポートされていません)が必要です。

IDE にはそれぞれの良さがあります。皆さんのニーズに合った IDE の選択については、統合開発環境(IDE)サポートをご参照ください。

プロジェクトに役立つショートカットのリストについては、e ブックをご覧ください。また、Visual Studio でのワークフローの改善については、「Visual Studio Tips and tricks to boost your productivity」をご覧ください。

JetBrains Rider についてもっと触れてみたいという方は、「Fast C# scripting in Unity with JetBrains Rider」や、「Unity で JetBrains Rider をコードエディターとして使用するためのヒント」をご覧ください。

再生モードでのデバッグ

Unity Debugger を使うと、Unity のエンティティが再生モードになっている間に C# コードをデバッグすることができます。コードエディター内にブレークポイントをアタッチし、実行時にスクリプトコードの状態や現在の変数を検査することができます。

Unity エディターのステータスバーの右下にある Code Optimization モードを Debug に設定します。 起動時のこのモードの設定を、Edit > Preferences > General > Code Optimization On Startup で変更することもできます。

デバッグモード

コードエディターで、デバッガーの実行を一時停止させたい箇所にブレークポイントを設定します。ブレークポイントを置きたいところの左余白(溝)の部分をクリックするだけです(またはそこを右クリックして、他のオプションを含むコンテキストメニューを表示することもできます)。ハイライトされた行の行番号の横に赤い丸が表示されます(下図参照)。

ブレークポイントのオン・オフ切り替え

コードエディターで「Attach to Unity」を選択し、Unity エディターでプロジェクトを実行します。

Unity にデバッガーをアタッチする

再生モードでは、ブレークポイントでアプリケーションが一時停止するので、変数を調べたり、意図しない動作について調べたりすることができます。

変数のデバッグ

上記のように、実行中にリストの項目が 1 つずつ積み重なっていく様子を見ていくことで、デバッグにおいて変数を検査することができます。

デバッグ制御:続行、ステップオーバー、ステップイン、ステップアウト

続行ステップオーバーステップインステップアウトの各制御ボタンを使って制御フロー内を行き来します。

デバッグ制御:停止

停止ボタンを押すと、デバッグを中止してエディターでの実行を再開します。 

Unity プレイヤーでもスクリプトコードのデバッグが可能です。ただ、プレイヤーをビルドする前に File > Build Settings を開き、Development BuildScript Debugging の両方が 有効になっていることを確認してください。Wait for Managed Debugger をチェックし、プレイヤーがスクリプトコードを実行するまでデバッガーを待機します。 コードエディターを Unity プレイヤーにアタッチするには、プレイヤーの IP アドレス(またはマシン名)とポートを選択します。その後、Visual Studio で Attach To Unity オプションを使用して通常の作業を行います。

その他のデバッグのヒント

Unity では、実行中のエディターの情報を視覚化するために、Debug クラスを提供しています。Console ウィンドウにメッセージや警告を表示する方法、シーンビューやゲームビューに視覚化のための線を描く方法、エディターの再生モードをスクリプトから一時停止する方法などをご確認ください。以下、ヒントを 2、3 個ご紹介します。

  1. Debug.Break で実行を一時停止できます。これは、アプリケーションを手動で一時停止するのが難しいが、インスペクターで特定の値を確認したいという時に便利です。  
  2. コンソールメッセージを表示するためのコマンドとして、Debug.LogDebug.LogWarningDebug.LogError はよくご存じかと思います。Debug.Assert も便利です。これは条件をアサートし、失敗時にはエラーをログに記録します。ただし、UNITY_ASSERTIONS シンボルが定義されている場合にのみ動作することに注意してください。 メッセージ、警告、エラーのログをコンソールに表示します。  
  3. Debug.Log を使用する際には、コンテキストとしてオブジェクトを渡すことができます。コンソールのメッセージをクリックすると、Unity は Hierarchy ウィンドウのゲームオブジェクトをハイライトします。  
  4. リッチテキストを使って、Debug.Log の内容をマークアップします。これにより、コンソールでのエラーレポートを見やすくすることができます。  
  5. Unity は、開発用ではないビルドから Debug ロギング API を自動的に取り除きません。Debug.Log 呼び出しをカスタムメソッドでラップし、[Conditional] 属性でデコレーションします。 Debug.Log を一度にコンパイルの対象から外すには、対応する Scripting Define Symbol を Player Settings から削除します。これは、#if... #endifのプリプロセッサブロックでラップするのと同じです。 詳細はこちらの「一般的な最適化」ガイドをご覧ください。  
  6. 物理演算のトラブルシューティングにおいては、Debug.DrawLineDebug.DrawRay が、レイキャストの状態を視覚化するのに役立ちます。

Debug.DrawLine

  1. Development Build が有効になっている間だけコードを実行したい場合は、Debug.isDebugBuild が true を返すかどうかを確認します。  
  2. Application.SetStackTraceLogType、または Player Settings の対応するチェックボックスを使って、スタックトレースを含むログメッセージの種類を決定します。スタックトレースは便利ですが、時間がかかりますし、ゴミも出ます。

コンソールログのエントリを好みに合わせて設定する

デフォルトでは、コンソールログのエントリは 2 行で表示されます。これを 1 行にまとめて読みやすくすることができます。やり方は以下の通りです。

コンソールログのエントリのオプション

また、長いエントリを多くの行を使って表示することもできます。

コンパイラーの状態をカスタマイズする

Unity のコンパイル時に、右下のアイコンが見えにくくなることがあります。このカスタムエディタースクリプトを使用して、EditorApplication.isCompiling を呼び出します。これにより、フローティングウィンドウが作成され、コンパイラーの状態が見やすくなります。

MenuItem を起動して、このウィンドウを初期化します。好みに合わせて、GUIStyle を新しく指定して外観を変更することもできます。

ソース管理

Unity は、PerforcePlastic SCM の 2 つのバージョン管理システムと統合されています。Unity プロジェクトの Perforce または Plastic SCM サーバーを設定するには、Project Settings > Editor メニューを開きます。Version Control の下にある、サーバーの設定(および Perforce のユーザー認証情報)の設定を行います。

バージョン管理を使用するようにプロジェクトを設定します。

Unity を導入しているチームは、Plastic SCM Cloud Edition を 5GB のストレージ・最大 3 人のユーザーの範囲内で無料で利用することができます。Plastic SCM for Unity を使えば、Unity で作業しつつ、自分の変更とチームメイトの作業を同期させたり、プロジェクトの履歴を参照したりすることができます。Plastic SCM の最近のアップデートについてはこちらの記事をご覧ください。

Git などの外部システム(および大規模アセットのより効率のよいバージョン管理に向いた Git LFS(Large File Support))を利用して、グラフィックやサウンドリソースなどの大きなアセットのバージョン管理を効率的に行うこともできます。 GitHub ホスティングサービスでの作業の利便性を高めるために、GitHub for Unity プラグインをインストールしてください。このオープンソースの拡張機能を使えば、プロジェクトの履歴を表示したり、ブランチで実験したり、変更点からコミットを作成したり、GitHub にコードをプッシュしたりといった操作を、すべて Unity の中で行えます。

Unity は、.gitignore ファイルを管理しています。これにより、Git リポジトリに入れるべきものと入れないものを決め、そのルールを徹底して遵守させることができます。

GitHub for Unity 拡張

Unity Teams を使うと、プロジェクト全体をクラウドに保存することができます。ワークフローを効率化するための選択肢の 1 つとして頭に入れておくべきでしょう。クラウドにプロジェクト全体を保存することでプロジェクトのバックアップを取ることができ、またどこからでもアクセスできるので、Unity プロジェクトの保存や共有、共に作業する全員の Unity プロジェクトを同期させることがこれまでよりはるかに簡単になります。

さらに生産性を向上させる e ブックをダウンロードしよう

e ブック

このシリーズで先に公開した 2 本のブログ記事、「エディターでのワークフローを高速化する 5 つの方法」と「アーティストワークフローをスピードアップ」をご覧ください。また、このシリーズでご紹介したものも含め、多数のヒントを 1 冊にまとめた e ブック「70+ tips to increase productivity with Unity 2020 LTS を無料でダウンロードしていただけます。

他に私たちにカバーしてほしいトピックや機能がありましたら、いつものようにコメントでお知らせいただけますと幸いです。また、皆さんご自身の生産性向上のコツをコミュニティでどんどん共有していってください。

2021年9月27日 カテゴリ: Engine & platform | 10 分 で読めます

Is this article helpful for you?

Thank you for your feedback!

取り上げているトピック