using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.EventSystems; using Yarn.Compiler; using Yarn.Unity; using Yarn.Unity.Editor; public static class YarnDemoSetup { const string YarnProjectPath = "Assets/Dialogue/NightclubArcadia.yarnproject"; const string ScenePath = NightclubArcadia.EditorTools.ScenePaths.Sandbox; [MenuItem("Tools/Nightclub Arcadia/Set Up Yarn Sandbox Scene")] public static void SetUpYarnDialogueTest() { // This menu BUILDS A SCENE FROM SCRATCH and saves over ScenePath. Pointed at a // real level it silently destroys it, which is exactly what happened when it // was briefly retargeted at SC101_ConferenceHall. The guard is the fix; do not // remove it, and do not point ScenePath outside Scenes/Dev. if (!NightclubArcadia.EditorTools.ScenePaths.IsDisposable(ScenePath)) { Debug.LogError($"Refusing to run: '{ScenePath}' is not under Assets/Scenes/Dev/. " + "This menu overwrites its target scene wholesale."); return; } if (!AssetDatabase.IsValidFolder("Assets/Scenes/Dev")) { AssetDatabase.CreateFolder("Assets/Scenes", "Dev"); } if (!AssetDatabase.IsValidFolder("Assets/TextMesh Pro")) { Debug.LogWarning("TextMesh Pro essential resources are missing. Run Window → TextMeshPro → Import TMP Essential Resources."); } if (!AssetDatabase.IsValidFolder("Assets/Dialogue")) { AssetDatabase.CreateFolder("Assets", "Dialogue"); } if (!AssetDatabase.IsValidFolder("Assets/Scenes")) { AssetDatabase.CreateFolder("Assets", "Scenes"); } var yarnProject = AssetDatabase.LoadAssetAtPath(YarnProjectPath); if (yarnProject == null) { // YarnProjectUtility.CreateDefaultYarnProject is internal, so // construct the same default project here. var project = new Project { ExcludeFilePatterns = new[] { "**/*~/*", "./Samples/Yarn Spinner*/*" }, }; YarnEditorUtility.CreateYarnProject(YarnProjectPath, project); AssetDatabase.Refresh(); yarnProject = AssetDatabase.LoadAssetAtPath(YarnProjectPath); } var scene = EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single); var runner = CreateDialogueRunnerMenuItem.CreateDialogueRunner(); var so = new SerializedObject(runner); so.FindProperty("yarnProject").objectReferenceValue = yarnProject; so.ApplyModifiedPropertiesWithoutUndo(); runner.autoStart = true; runner.startNode = "Start"; EditorUtility.SetDirty(runner); #if UNITY_2023_1_OR_NEWER var eventSystems = Object.FindObjectsByType(FindObjectsInactive.Include); #else var eventSystems = Object.FindObjectsOfType(true); #endif foreach (var eventSystem in eventSystems) { if (eventSystem.GetComponent() != null) { continue; } #if ENABLE_INPUT_SYSTEM eventSystem.gameObject.AddComponent(); #endif } EditorSceneManager.SaveScene(scene, ScenePath); AssetDatabase.SaveAssets(); Debug.Log($"Yarn dialogue test setup complete. Scene saved to {ScenePath}"); } }