30
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Unityでのゲーム開発では、多くのGameObjectやPrefabそしてAssetが必要で、それらは他のGameObjectやAssetへの参照を持っています。その参照関係を正しく管理・運用するのは大規模なゲーム・長期間のプロジェクトではとても難しいです。「間違って使っているAssetを削除してしまい、それを参照している部分が原因で不具合が発生した」という経験はありませんか。このような不具合を、どうやったら防げるでしょうか?

自分のおすすめは、Odin Validatorを用いたプロジェクト全体の自動検証です。Odi Validatorを用いれば「ここは必ず何かしらのAssetを参照しないといけないと設定する。もし参照していない場合は、エラーを表示する」という設定が実現できます。「間違って使っているAssetを削除してしまい、それを参照している部分が原因で不具合が発生した」という不具合を検知し、事前に防ぐことができます。

この投稿では、Odin Validatorを用いた、プロジェクトの自動検証を紹介します。

参照しているやつがなくなってしまった!

Unityでのゲーム開発では、多くのGameObjectやPrefabそしてAssetが必要で、それらは他のGameObjectやAssetへの参照を持っています。その参照関係を正しく管理・運用するのはとても難しいです。特に、大規模なゲームで長期間のプロジェクトとなれば、なおさらでしょう。

たとえば、次のようなScriptableObjectのクラスがあるとします。

using UnityEngine;

[CreateAssetMenu]
public class Enemy : ScriptableObject
{
    [SerializeField] private string enemyName;
    public string EnemyName => enemyName;

    [SerializeField] private Sprite sprite;
    public Sprite Sprite => sprite;

    [SerializeField] private GameObject model;
    public GameObject Model => model;

    // 略
}

次のようにEnemy000というScriptableObjectを作成し、Inspectorから参照を設定したとしましょう。

odin_scriptable_object_enemy_normal.png

さて、プロジェクトがすすみ、Assetも多くなってきて管理が難しくなってきたとします。本当は必要だったAsset(EnemySprite0)を誰かがうっかりプロジェクトから消してしまいました。その場合、次のようにSpriteの参照が「None」という状態になってしまいます。

odin_scriptable_object_enemy_none.png

もしこの状態で、ビルド・実行したらおそらく表示すべきSpriteが表示されない不具合が発生してしまいます。

このような「間違って使っているAssetを削除してしまい、それを参照している部分が原因で不具合が発生した」という不具合を経験した方も多いのではないでしょうか?ここで紹介した例は「Spriteが表示されない」でしたが、ゲームが進行不可能になったり、課金関連の不具合が発生したりと、もっと大きは不具合が発生してしまうことも考えられます。

このような不具合に、対応するために自分は、Odin Validatorを用いたプロジェクト全体の自動検証を導入することをおすすめします。

Odin Validatorとは?

Odin Validatorの前に、まずOdinを紹介します。

OdinOdin - Inspector and Serializer)はUnity向けのツール・ユーティリティカテゴリのライブラリです。非常に強力で豊富な機能を持っている人気のライブラリです。主な機能は次のとおりです。Inspectorの強化をはじめ、エディター拡張のユーティリティの提供します。Odin - Inspector and Serializerは、Asset Store・もしくはOdinの公式ページから購入が可能です。

odin_asset_store_screenshot.png

自分の、Odinのおすすめ機能は「Required属性」です。Required属性がついたSerialize対象のフィールドは、「必ず参照や値を設定する必要がある」という条件が追加されます。もし参照や値を設定していない場合、次のようにInspectorに設定されていないことをわかりやすく表示してくれます。

odin_scriptable_object_enemy_required_error.png

Odinを使って制約や条件を追加してみよう

Odin - Inspector and Serializerでは、多くの属性とそれに対応するValidatorを提供しています。これらの属性が付与されたフィールドは、ValidatorによりInspectorからの入力に条件や制約を加えることができます。

Odin Project Validatorでは、これらの属性を用いて付与された条件や制約を検証できます。この節では、Odin - Inspector and Serializerで提供されている属性とValidatorの使い方の一部を紹介します。

Required

Required属性をつけることで、参照の設定・値の入力を必須にできます。

次のようなScriptableObjectのクラスがあります。

using UnityEngine;
using Sirenix.OdinInspector;

[CreateAssetMenu]
public class ExampleRequire : ScriptableObject
{
    // 本当はプロパティを準備したほうがいいが、サンプルのためpublicフィールド
    [Required] public string stringValue;
    [Required] public GameObject gameObjectReference;
    [Required] public Transform transformReference;
    
    [Required] public int intValue;
    [Required] public double doubleValue;
}

このScriptableObjectのInspectorは次のようになります。stringValue、gameObjectReference、transformReferenceの上部に「stringValue is Required」などのエラーメッセージが表示されていることに注目してください。Required属性を付与することで、そのフィールドの参照・値を設定していない箇所をエラー表示できます。

odin_example_require_error.png

stringValueなどに参照・値を設定すると次のようにエラー表示が解消されます。

odin_example_require_valid.png

intやdoubleなどのフィールドには、Requiredをつけてもエラーメッセージが表示されないことに注意してください。

ValidateInput

ValidateInput属性をつけることで、指定したstaticメソッドを用いて検証できます。たとえば、次のコードは「ListなtargetAssetsが要素を1つ以上持っているか」を検証します。

using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;

[CreateAssetMenu]
public class ExampleValidateInput : ScriptableObject
{
    [Required] [ValidateInput(nameof(ValidateNotEmpty))]
    public List<GameObject> targetAssets;

    private static bool ValidateNotEmpty(
        List<GameObject> targetAssets,
        ref string message
    )
    {
        if (targetAssets.Count == 0)
        {
            message = "List is empty.";
            return false;
        }

        return true;
    }
}

このScriptableObjectのInspectorは次のようになります。targetAssetsは要素を1つも持っていないので、上部に「List is empty.」というエラーメッセージが表示されています。

odin_example_validate_input_error.png

targetAssetsが要素を1つ以上もつようになると、エラーメッセージが消えます。

odin_example_validate_input_valid.png

このようにValidateInputを使うと、自分で指定したstaticメソッドにより、独自の検証を行うことができます。

AssetsOnly と SceneObjectsOnly と ChildGameObjectsOnly

AssetsOnly、SceneObjectsOnly、ChildGameObjectsOnly属性をつけることで、参照の設定を次のように条件づけできます。

  • AssetsOnly・・・プロジェクトのAsset限定
  • SceneObjectsOnly・・・シーン上のGameObjectやComponent限定
  • ChildGameObjectsOnly・・・シーン上の自分の子GameObject限定

AssetsOnlyを指定しているフィールドに、シーン上のGameObjectやComponentは参照設定できません。SceneObjectsOnlyを指定しているフィールドに、プロジェクト上のAssetは参照設定できません。ChildGameObjectsOnlyはIncludeSelfという引数があり、自身も許可するかどうかを指定できます。

次のコードのtargetは、プロジェクト中のPrefabもシーン上のGameObjectも、どちらも参照設定できてしまいます。本来はどちらかしか設定できるべきではありません。

using UnityEngine;

public class Example : MonoBehaviour
{

    // プロジェクト中のPrefabもシーン上のGameObjectも
    // どちらも参照設定できてしまう
    [SerializeField] GameObject target;

    // プロジェクト中のAsset(Prefab)を指定すべき場合は、AssetsOnlyを
    // [SerializeField, AssetsOnly] GameObject target;

    // シーン上のGameObjectを指定すべき場合はSceneObjectsOnlyを
    // [SerializeField, AssetsOnly] GameObject target;
}

プロジェクト中のAsset(Prefab)を指定すべき場合はAssetsOnlyを、シーン上のGameObjectを指定すべき場合はSceneObjectsOnlyをつけることをおすすめします。

Odin Validatorを使ってみよう

RequiredやValidateInput、AssetsOnlyなどOdin - Inspector and Serializerの属性を使うことで、入力に条件や制約を加えそれを満たさなかった場合、Inspectorにエラー表示できます。しかしそのエラー表示に気がつかなかったとしたら、結局不具合が発生してしまいます。しかし、せっかくのわかりやすいエラー表示も、みのがしてしまったら意味がありませんね。そこでOdin Validatorの出番です。

Odin Validatorは、Odin - Inspector and SerializerのAddonです。Odin Validatorを用いると、Required属性などの条件を満たしていないAsestやPrefab、GameObjectが存在しないか検証し、その結果を次のようにわかりやすく確認できます。Odin Validatorは、公式サイトから購入することができます。

odin_project_validator_error_example.png

検証する範囲も、「今開いてるシーン」や「プロジェクト全体」など指定できます。また、その検証のタイミングをゲームプレイ実行時、ビルド実行時など指定できます。Odin Validatorを用いることで、「間違って使っているAssetを削除してしまい、それを参照している部分がきっかけでシーンが壊れてしまった」という不具合を回避できます。

Odin ValidatorはOdin公式ページから購入が可能です。この投稿の執筆時点では、2019年5月28日より前にOdinを購入したユーザーはOdi Validatorを無料でダウンロードできるようです。価格・購入については、最新の公式情報を参照してください。

変更を加えるたびに、いちいちプロジェクトにあるSceneやPrefab、ScriptableObjectすべてにエラー表示がないかを確認することは、現実的ではありません。Requiredなどを使っていたとしても、「使っていないと思ったAssetを削除したら、最近まったく更新していないシーンで使っていて、それが原因で不具合が発生してしまった」ということは起きてしまいます。

先に説明した通り、このような不具合は、Odin Validator使うことで回避できます。
@{Odin Project Validator}を使えば、RequiredやValidateInput、AssetsOnlyなどの属性がついている部分を自動で検証し、満たしていない箇所をわかりやすく表示してくれます。
いちいちプロジェクト全体を目視で確認する必要はありません。

OdinOdin Validatorをプロジェクトに導入し、メニューの「Tools > Odin Project Validator」を選択すると次のようなウィンドウが開きます。

odin_project_validator_top.png

一番上の「Scan Entire Project」を押すと次のような状態に遷移します。

odin_project_validator_entire_project.png

このウィンドウの右上にある「Run Scan Entire Project」というボタンを押下します。もしプロジェクトにRequiredやValidateInput、AssetsOnlyを満たさないものがあった場合、次のようにそれを一覧表示できます。

odin_project_validator_result_error.png

検証した内容を一覧できます。また、条件を満たしていなかったAssetやGameObjectをこのウィンドウから直接編集できます。

もしプロジェクトにRequiredやValidateInput、AssetsOnlyを満たさないものがなければ、次のようになります。

odin_project_validator_result_valid.png

「Scan Entire Project」はプロジェクト全体を検証します。Odin Project Validatorでは、これ以外にも次のような設定も提供しています。

名称 対象
Scan Entire Project プロジェクトにあるすべてのScene・Assetを検証する
Scan All Assets プロジェクトにあるすべてのAssetを検証する
Scan All Scenes プロジェクトにあるすべてのSceneを検証する
Scan Open Scenes 現在開いているSceneを検証する
Scan Scenes From Build Options ビルド対象に設定されているSceneを検証する

自分で設定を作ることも、既存の設定を変更することもできます。必要に応じて自分のプロジェクト運用にあった設定を試してみてください。

Automate Validation

Odin Validatorでプロジェクトの検証を行えば、参照や値の設定の間違いに気が付くことができます。しかし、ビルドする前にOdin Validatorでの検証を忘れてしまったら、結局不具合が発生してしまう可能性があります。Odin Validatorによる検証を忘れないために、Automate Validationを設定することをお勧めします。

メニューの「Tools > Odin Project Validator」からウィンドウを開き、右上部にある「Automate Validator」ボタンを押すと次のようなAutomate Validationウィンドウが開きます。

odin_automate_validation.png

ウィンドウ内のチェックボックスにチェックをつけて、Automate Validationを有効にするとそれぞれのタイミングで、指定した検証を実行できます。

  • On Play ・・・ デバック実行
  • On Build ・・・ ビルド実行
  • On Project Startup ・・・ プロジェクトの起動

odin_automate_validation_settings.png

また、ビルド実行時に検証を行うように設定し、もし設定した条件を満たさない箇所をみつけたら、ビルドを失敗させる、ということも可能です。こうすることで、ゲーム出荷・リリースする前に必ず条件を満たすことを保証することができます。

まとめ

この章では、Odin Validatorを紹介しました。

間違って使っているAssetを削除してしまい、それを参照している部分が原因で不具合が発生した」という不具合の経験がある人は多いのではないでしょうか。
こういう不具合を防ぐために、ぜひOdin Validatorを導入してみてください!

補足

各種バージョン

  • Unity 2019.4.8f1
  • Odin Inspector 3.0.2
  • Odin Validator 3.0.2
30
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?