private void OnGUI()
        {
            Initialize();

            if (targets == null || targets.Length == 0)
            {
                if (GUILayout.Button("Create New ProjectBuilder Asset"))
                {
                    Selection.activeObject = BuilderUtil.CreateBuilderAsset();
                }
                return;
            }

            using (EditorGUILayout.ScrollViewScope svs = new EditorGUILayout.ScrollViewScope(scrollPosition))
            {
                scrollPosition = svs.scrollPosition;

                serializedObject = serializedObject ?? new SerializedObject(targets);
                serializedObject.Update();

                GUILayout.Label(contentTitle, styleTitle);

                DrawCustomProjectBuilder();
                DrawApplicationBuildSettings();
                DrawBuildTargetSettings();
                DrawControlPanel();


                serializedObject.ApplyModifiedProperties();
            }
        }
        private void Initialize()
        {
            if (styleCommand != null)
            {
                return;
            }

            styleTitle = new GUIStyle("IN BigTitle")
            {
                alignment = TextAnchor.UpperLeft, fontSize = 12, stretchWidth = true, margin = new RectOffset()
            };

            styleCommand = new GUIStyle(EditorStyles.textArea)
            {
                stretchWidth = false, fontSize = 9
            };
            contentOpen = new GUIContent(EditorGUIUtility.FindTexture("project"));

            Builder            dummy = CreateInstance <Builder>();
            SerializedProperty sp    = new SerializedObject(dummy).GetIterator();

            sp.Next(true);
            while (sp.Next(false))
            {
                endBasePropertyName = sp.name;
            }

            roSceneList = new ReorderableList(new List <Builder.SceneSetting>(), typeof(Builder.SceneSetting));
            roSceneList.drawElementCallback += (rect, index, isActive, isFocused) =>
            {
                SerializedProperty element = roSceneList.serializedProperty.GetArrayElementAtIndex(index);
                EditorGUI.PropertyField(new Rect(rect.x, rect.y, 16, rect.height - 2),
                                        element.FindPropertyRelative("enable"), GUIContent.none);
                EditorGUIEx.TextFieldWithTemplate(new Rect(rect.x + 16, rect.y, rect.width - 16, rect.height - 2),
                                                  element.FindPropertyRelative("name"), GUIContent.none, availableScenes, false);
            };
            roSceneList.headerHeight  = 0;
            roSceneList.elementHeight = 18;

            roExcludeDirectoriesList = new ReorderableList(new List <string>(), typeof(string));
            roExcludeDirectoriesList.drawElementCallback += (rect, index, isActive, isFocused) =>
            {
                SerializedProperty element = roExcludeDirectoriesList.serializedProperty.GetArrayElementAtIndex(index);
                EditorGUIEx.DirectoryPathField(rect, element, GUIContent.none, "Select exclude directory in build.");
            };
            roExcludeDirectoriesList.headerHeight  = 0;
            roExcludeDirectoriesList.elementHeight = 18;

            roBuilderList = new ReorderableList(buildersInProject, typeof(Builder))
            {
                onSelectCallback = list => Selection.activeObject = list.list[list.index] as Builder
            };
            roBuilderList.onAddCallback += list =>
            {
                EditorApplication.delayCall += () =>
                {
                    BuilderUtil.CreateBuilderAsset();
                    OnSelectionChanged();
                };
            };
            roBuilderList.onRemoveCallback += list =>
            {
                EditorApplication.delayCall += () =>
                {
                    AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(list.list[list.index] as Builder));
                    AssetDatabase.Refresh();
                    OnSelectionChanged();
                };
            };
            roBuilderList.drawElementCallback += (rect, index, isActive, isFocused) =>
            {
                Builder b = roBuilderList.list[index] as Builder;
                if (!b)
                {
                    return;
                }

                GUI.DrawTexture(new Rect(rect.x, rect.y + 2, 16, 16), GetBuildTargetIcon(b));
                GUI.Label(new Rect(rect.x + 16, rect.y + 2, rect.width - 16, rect.height - 2),
                          new GUIContent($"{b.name} ({b.productName})"));
            };
            roBuilderList.headerHeight = 0;
            roBuilderList.draggable    = false;

            contentTitle = new GUIContent(Util.GetAssets <Texture2D>(typeof(Builder).Name + " Icon").FirstOrDefault());
            DestroyImmediate(dummy);
        }
        private void DrawControlPanel()
        {
            Builder builder = serializedObject.targetObject as Builder;

            if (builder == null)
            {
                return;
            }

            GUILayout.FlexibleSpace();
            using (new EditorGUILayout.VerticalScope("box"))
            {
                GUILayout.Label(
                    new GUIContent(
                        $"{builder.productName} ver.{builder.version} ({builder.versionCode})",
                        GetBuildTargetIcon(builder)), EditorStyles.largeLabel);

                using (new EditorGUILayout.HorizontalScope())
                {
                    if (GUILayout.Button(new GUIContent("Apply Setting", EditorGUIUtility.FindTexture("vcs_check"))))
                    {
                        builder.ApplySettings();
                    }

                    if (GUILayout.Button(
                            new GUIContent("Player Setting", EditorGUIUtility.FindTexture("EditorSettings Icon")),
                            GUILayout.Height(21), GUILayout.Width(110)))
                    {
                        Selection.activeObject = Unsupported.GetSerializedAssetInterfaceSingleton("PlayerSettings");
                    }
                }

                using (new EditorGUILayout.HorizontalScope())
                {
                    if (GUILayout.Button(new GUIContent("Build Addressable Assets",
                                                        EditorGUIUtility.FindTexture("vcs_check"))))
                    {
                        Builder.BuildAddressableAssets();
                    }
                }

                EditorGUI.BeginDisabledGroup(builder.ActualBuildTarget != EditorUserBuildSettings.activeBuildTarget);

                using (new EditorGUILayout.HorizontalScope())
                {
                    if (GUILayout.Button(
                            new GUIContent($"Build to '{builder.BuildName}'",
                                           EditorGUIUtility.FindTexture("preAudioPlayOff")), "LargeButton"))
                    {
                        EditorApplication.delayCall += () => BuilderUtil.StartBuild(builder, false);
                    }

                    var r = EditorGUILayout.GetControlRect(false, GUILayout.Width(15));
                    if (GUI.Button(new Rect(r.x - 2, r.y + 5, 20, 20), contentOpen, EditorStyles.label))
                    {
                        BuilderUtil.RevealOutputInFinder(builder.OutputFolderPath);
                    }
                    EditorGUI.EndDisabledGroup();
                }

                if (GUILayout.Button(new GUIContent("Build & Run", EditorGUIUtility.FindTexture("preAudioPlayOn")),
                                     "LargeButton"))
                {
                    EditorApplication.delayCall += () => BuilderUtil.StartBuild(builder, true);
                }

                EditorGUI.EndDisabledGroup();

                if (GUILayout.Button("Convert to JSON (console log)"))
                {
                    Debug.Log(JsonUtility.ToJson(builder, true));
                }

                GUILayout.Space(10);
                GUILayout.Label("Available Project Builders", EditorStyles.boldLabel);
                roBuilderList.list  = buildersInProject;
                roBuilderList.index = buildersInProject.FindIndex(x => x == serializedObject.targetObject);
                roBuilderList.DoLayoutList();
            }
        }