LoginSignup
1
1

【Unity】 missing が存在する時自動でビルドをキャンセルする仕組み

Posted at

皆さんは missing について悩んだ事はありますか?

missing を探すアセットは世の中にたくさんありますが
ビルドするシーンに missing が存在する時に
自動でビルドをキャンセルする仕組みは
意外とありません。

そこで今回はその仕組みを提供してみたいと思います。
この仕組みを導入する以外の操作は必要なく
毎回実行する手間もありませんので
是非導入を検討して頂けると幸いです。

unitypackage 版も公開しますので
楽に導入したいならば
そちらも検討下さい。


https://drive.google.com/file/d/1sNoFsd5nST2H-uCkTlmhwkgEcV_wW9Wa/view?usp=sharing

unitypackage 版は
上記の URL からダウンロードして下さい。

SephirothStopOutputAtMissing.cs
以外のファイルは削除してかまいません。
HowToUse.pdf 等は容量が大きいため
削除する事を推奨します。


では仕組みを作成していきます。

Editor フォルダを作成して、その中に
SephirothStopOutputAtMissing.cs を新規作成して
下記の内容にして下さい。

SephirothStopOutputAtMissing.cs
#pragma warning disable 0618

namespace SephirothTools
{
    public class SephirothStopOutputAtMissing : UnityEditor.Build.IPreprocessBuild
    {

        public void OnPreprocessBuild(UnityEditor.BuildTarget target, string path)
        {
            string currentScenePath = UnityEngine.SceneManagement.SceneManager.GetActiveScene().path;
            foreach (var oneScene in UnityEditor.EditorBuildSettings.scenes)
            {
                UnityEditor.SceneManagement.EditorSceneManager.OpenScene(oneScene.path);

                foreach (var oneGameObject in UnityEngine.Object
            .FindObjectsOfType<UnityEngine.GameObject>(true))
                {
                    foreach (var oneComponent in oneGameObject.GetComponents<UnityEngine.Component>())
                    {
                        if (!oneComponent)
                        {
                            throw new UnityEditor.Build.BuildFailedException(oneScene.path + "'s objectName: " + oneGameObject.name + " is missing. Stop the app's output.");
                        }

                        UnityEditor.SerializedObject serializedObject = new UnityEditor.SerializedObject(oneComponent);

                        serializedObject.ApplyModifiedProperties();

                        UnityEditor.SerializedProperty property = serializedObject.GetIterator();

                        while (property.Next(true))
                        {
                            if (property.propertyType == UnityEditor.SerializedPropertyType.ObjectReference && property.objectReferenceValue == null && property.objectReferenceInstanceIDValue != 0)
                            {
                                throw new UnityEditor.Build.BuildFailedException(oneScene.path + "'s objectName: " + oneGameObject.name + " is missing. Stop the app's output.");
                            }
                        }
                    }
                }
            }
            UnityEditor.SceneManagement.EditorSceneManager.OpenScene(currentScenePath);
        }

        public int callbackOrder { get { return 0; } }
    }
}

ビルド対象のシーンに対して
missing が存在するときに
throw new UnityEditor.Build.BuildFailedException
が呼ばれているのが分かると思います。

BuildFailedException が実行されると
自動でビルドがキャンセルされます。
どのオブジェクトが missing なのかも
ログで分かるように作成しています。


あとがき

以上が missing が存在する時
自動でビルドをキャンセルする仕組みになります。

導入しておけば
それ以外の操作が必要ない点は
非常に便利なハズです。

この仕組みが
皆さんの開発の助けになれば幸いです。
閲覧ありがとうございました。

1
1
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
1
1