public static void Execute()
        {
            var templateIdItems = new Dictionary <ItemTemplateId, IItem>();

            ItemTemplateId GetOrCreateTemplateId(IItem item, IEnumerable <CreateItemGimmick> createItemGimmicks)
            {
                ItemTemplateId templateId;

                foreach (var createItemGimmick in createItemGimmicks)
                {
                    templateId = createItemGimmick.ItemTemplateId;
                    if (templateId.Value == 0 || templateIdItems.ContainsKey(templateId))
                    {
                        continue;
                    }
                    templateIdItems.Add(templateId, item);
                    return(templateId);
                }

                do
                {
                    templateId = ItemTemplateId.Create();
                }while (templateId.Value == 0 || templateIdItems.ContainsKey(templateId));
                templateIdItems.Add(templateId, item);
                return(templateId);
            }

            var scene = SceneManager.GetActiveScene();
            var createItemGimmickGroup = ItemTemplateGatherer.GatherCreateItemGimmicksForItemTemplates(scene);

            foreach (var gimmicks in createItemGimmickGroup)
            {
                var item       = gimmicks.Key;
                var templateId = GetOrCreateTemplateId(item, gimmicks);
                foreach (var gimmick in gimmicks)
                {
                    if (gimmick.ItemTemplateId.Equals(templateId))
                    {
                        continue;
                    }
                    gimmick.ItemTemplateId = templateId;
                    if (!Application.isPlaying)
                    {
                        EditorUtility.SetDirty(gimmick);
                    }
                }
            }

            if (!Application.isPlaying)
            {
                EditorSceneManager.MarkSceneDirty(scene);
            }
        }
        public static bool ValidateVenue(out string errorMessage, out GameObject[] invalidObjects)
        {
            var scene            = SceneManager.GetActiveScene();
            var sceneRootObjects = scene.GetRootGameObjects();

            var despawnHeights = sceneRootObjects.SelectMany(x => x.GetComponentsInChildren <DespawnHeight>(true));

            if (despawnHeights.Count() != 1)
            {
                errorMessage   = $"{nameof(DespawnHeight)}はワールドに1つ配置されている必要があります。現在配置されている{nameof(DespawnHeight)}の数は {despawnHeights.Count()} です";
                invalidObjects = despawnHeights.Select(x => x.gameObject).ToArray();
                return(false);
            }

            var spawnPoints = sceneRootObjects.SelectMany(x => x.GetComponentsInChildren <SpawnPoint>(true));
            var entrances   = spawnPoints.Where(x => x.SpawnType == SpawnType.Entrance);

            if (!entrances.Any())
            {
                errorMessage   = $"ワールドには{nameof(SpawnPoint)}が「{nameof(SpawnType.Entrance)}」の{nameof(SpawnPoint)}が1つ以上配置されている必要があります";
                invalidObjects = spawnPoints.Select(x => x.gameObject).ToArray();
                return(false);
            }

            var itemTemplates  = ItemTemplateGatherer.GatherItemTemplates(scene);
            var allRootObjects = sceneRootObjects.Concat(itemTemplates.Select(t => t.gameObject)).ToArray();

            var mainCameras = allRootObjects.SelectMany(x => x.GetComponentsInChildren <Camera>(true))
                              .Where(camera => camera.gameObject.CompareTag("MainCamera"));

            if (mainCameras.Any())
            {
                errorMessage   = $"ワールドにはTagが「MainCamera」の{nameof(Camera)}を配置できません";
                invalidObjects = mainCameras.Select(x => x.gameObject).ToArray();
                return(false);
            }

            var eventSystems = allRootObjects.SelectMany(x => x.GetComponentsInChildren <EventSystem>(true));

            if (eventSystems.Any())
            {
                errorMessage   = $"ワールドには{nameof(EventSystem)}を配置できません";
                invalidObjects = eventSystems.Select(x => x.gameObject).ToArray();
                return(false);
            }

            var items       = allRootObjects.SelectMany(x => x.GetComponentsInChildren <Item.Implements.Item>(true));
            var nestedItems = items.Where(i => i.transform.parent != null && i.transform.parent.GetComponentsInParent <Item.Implements.Item>(true).FirstOrDefault() != null).ToArray();

            if (nestedItems.Any())
            {
                errorMessage   = $"{nameof(Item.Implements.Item)}の子に{nameof(Item.Implements.Item)}は配置できません";
                invalidObjects = nestedItems.Select(x => x.gameObject)
                                 .Concat(nestedItems.Select(i => i.transform.parent.GetComponentsInParent <Item.Implements.Item>(true).First().gameObject))
                                 .Distinct()
                                 .ToArray();
                return(false);
            }

            var canvases                = allRootObjects.SelectMany(x => x.GetComponentsInChildren <Canvas>(true));
            var screenSpaceCanvases     = canvases.Where(c => c.isRootCanvas && (c.renderMode == RenderMode.ScreenSpaceCamera || c.renderMode == RenderMode.ScreenSpaceOverlay));
            var unmanagedPlayerLocalUIs = screenSpaceCanvases.Where(c => c.GetComponent <IPlayerLocalUI>() == null).ToArray();

            if (unmanagedPlayerLocalUIs.Any())
            {
                errorMessage   = $"{nameof(RenderMode)}が ScreenSpace である {nameof(Canvas)} には {nameof(PlayerLocalUI)} を追加する必要があります";
                invalidObjects = unmanagedPlayerLocalUIs.Select(x => x.gameObject).ToArray();
                return(false);
            }

            var globalGimmicks = allRootObjects.SelectMany(x => x.GetComponentsInChildren <IGlobalGimmick>(true));
            var invalidPlayerLocalGlobalGimmick = globalGimmicks.Where(g => !LocalPlayerGimmickValidation.IsValid(g)).ToArray();

            if (invalidPlayerLocalGlobalGimmick.Any())
            {
                errorMessage   = LocalPlayerGimmickValidation.ErrorMessage;
                invalidObjects = invalidPlayerLocalGlobalGimmick.Select(x => ((Component)x).gameObject).ToArray();
                return(false);
            }

            foreach (var itemTemplate in itemTemplates)
            {
                var result = ItemTemplateValidator.Validate(itemTemplate, onlyErrors: true);
                if (result.Errors.Any())
                {
                    var firstError = result.Errors.First();
                    errorMessage   = firstError.Message;
                    invalidObjects = new GameObject[] { itemTemplate.gameObject }; // Validation結果ではprefab内部がSelectされないためrootを返している
                    return(false);
                }
            }

            Debug.Log("Venue Validation is Passed.");
            errorMessage   = "";
            invalidObjects = new GameObject[] {};
            return(true);
        }