using UnityEngine; using UnityEditor; using System.IO; /// /// Editor utility for creating enemy characters from EnemyCharacterData /// Adds menu items under "RPG/Characters" for enemy creation workflow /// public class EnemyCharacterCreator : EditorWindow { private EnemyCharacterData selectedEnemyData; private string outputPath = "Assets/Scripts/Characters/Enemies/Generated/"; private Vector2 scrollPosition; [MenuItem("RPG/Characters/Enemy Creator Window")] public static void ShowWindow() { GetWindow("Enemy Character Creator"); } [MenuItem("Assets/RPG/Generate Enemy Character Script", true)] public static bool ValidateGenerateEnemyScript() { return Selection.activeObject is EnemyCharacterData; } [MenuItem("Assets/RPG/Generate Enemy Character Script")] public static void GenerateEnemyScriptFromSelected() { if (Selection.activeObject is EnemyCharacterData enemyData) { GenerateEnemyCharacterScript(enemyData); } } void OnGUI() { GUILayout.Label("Enemy Character Creator", EditorStyles.boldLabel); EditorGUILayout.Space(); // Enemy data selection EditorGUILayout.LabelField("Select Enemy Data:", EditorStyles.boldLabel); selectedEnemyData = (EnemyCharacterData)EditorGUILayout.ObjectField( "Enemy Data", selectedEnemyData, typeof(EnemyCharacterData), false); EditorGUILayout.Space(); // Output path EditorGUILayout.LabelField("Output Settings:", EditorStyles.boldLabel); outputPath = EditorGUILayout.TextField("Output Path:", outputPath); if (GUILayout.Button("Browse Output Folder")) { string selectedPath = EditorUtility.OpenFolderPanel("Select Output Folder", Application.dataPath, ""); if (!string.IsNullOrEmpty(selectedPath)) { outputPath = "Assets" + selectedPath.Substring(Application.dataPath.Length) + "/"; } } EditorGUILayout.Space(); // Preview if (selectedEnemyData != null) { EditorGUILayout.LabelField("Preview:", EditorStyles.boldLabel); using (var scrollScope = new EditorGUILayout.ScrollViewScope(scrollPosition, GUILayout.Height(200))) { scrollPosition = scrollScope.scrollPosition; EditorGUILayout.LabelField("Generated Class Name:", selectedEnemyData.enemyName.Replace(" ", "") + "Character"); EditorGUILayout.LabelField("Health:", selectedEnemyData.maxHealth.ToString()); EditorGUILayout.LabelField("Attack:", selectedEnemyData.attack.ToString()); EditorGUILayout.LabelField("Armor Class:", selectedEnemyData.armorClass.ToString()); EditorGUILayout.LabelField("Weapon Type:", selectedEnemyData.preferredWeapon.weaponType.ToString()); EditorGUILayout.LabelField("Threat Level:", selectedEnemyData.threatLevel.ToString()); EditorGUILayout.Space(); EditorGUILayout.LabelField("Special Abilities:"); if (selectedEnemyData.canCastSpells) EditorGUILayout.LabelField("• Can Cast Spells"); if (selectedEnemyData.hasRangedAttack) EditorGUILayout.LabelField("• Has Ranged Attack"); if (selectedEnemyData.canFly) EditorGUILayout.LabelField("• Can Fly"); if (selectedEnemyData.regeneratesHealth) EditorGUILayout.LabelField($"• Regenerates {selectedEnemyData.healthRegenPerTurn} HP per turn"); } EditorGUILayout.Space(); // Generate button GUI.enabled = selectedEnemyData != null; if (GUILayout.Button("Generate Enemy Character Script", GUILayout.Height(30))) { GenerateEnemyCharacterScript(selectedEnemyData); } GUI.enabled = true; } else { EditorGUILayout.HelpBox("Select an EnemyCharacterData asset to generate a character script.", MessageType.Info); } EditorGUILayout.Space(); // Quick actions EditorGUILayout.LabelField("Quick Actions:", EditorStyles.boldLabel); if (GUILayout.Button("Create New Enemy Data Asset")) { CreateNewEnemyData(); } if (GUILayout.Button("Open Generated Scripts Folder")) { EditorUtility.RevealInFinder(Path.Combine(Application.dataPath, "Scripts/Characters/Enemies/Generated")); } } public static void GenerateEnemyCharacterScript(EnemyCharacterData enemyData) { if (enemyData == null) { return; } // Ensure output directory exists string fullOutputPath = Path.Combine(Application.dataPath, "Scripts/Characters/Enemies/Generated"); if (!Directory.Exists(fullOutputPath)) { Directory.CreateDirectory(fullOutputPath); } // Generate script content string scriptContent = enemyData.GenerateCharacterScript(); string className = enemyData.enemyName.Replace(" ", "") + "Character"; string fileName = className + ".cs"; string fullPath = Path.Combine(fullOutputPath, fileName); // Write the file try { File.WriteAllText(fullPath, scriptContent); // Refresh asset database to show the new file AssetDatabase.Refresh(); // Select the generated file in the project window string assetPath = "Assets/Scripts/Characters/Enemies/Generated/" + fileName; Object asset = AssetDatabase.LoadAssetAtPath(assetPath); if (asset != null) { Selection.activeObject = asset; EditorGUIUtility.PingObject(asset); } EditorUtility.DisplayDialog("Success", $"Generated enemy character script: {className}\n\nThe script has been created at:\n{assetPath}", "OK"); } catch (System.Exception e) { Debug.LogError($"Failed to generate enemy character script: {e.Message}"); EditorUtility.DisplayDialog("Error", $"Failed to generate enemy character script:\n{e.Message}", "OK"); } } private void CreateNewEnemyData() { string path = EditorUtility.SaveFilePanelInProject( "Create New Enemy Data", "NewEnemy", "asset", "Choose where to save the new enemy data asset"); if (!string.IsNullOrEmpty(path)) { EnemyCharacterData newEnemy = CreateInstance(); AssetDatabase.CreateAsset(newEnemy, path); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Selection.activeObject = newEnemy; selectedEnemyData = newEnemy; } } } /// /// Additional menu items for RPG character creation /// public class RPGCharacterMenuItems { [MenuItem("RPG/Characters/Create Enemy Data Asset")] public static void CreateEnemyDataAsset() { string path = EditorUtility.SaveFilePanelInProject( "Create Enemy Data Asset", "NewEnemy", "asset", "Choose location for the enemy data asset", "Assets/Scripts/Characters/Enemies"); if (!string.IsNullOrEmpty(path)) { EnemyCharacterData enemyData = ScriptableObject.CreateInstance(); AssetDatabase.CreateAsset(enemyData, path); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Selection.activeObject = enemyData; EditorGUIUtility.PingObject(enemyData); } } [MenuItem("RPG/Characters/Batch Generate All Enemy Scripts")] public static void BatchGenerateEnemyScripts() { string[] guids = AssetDatabase.FindAssets("t:EnemyCharacterData"); int count = 0; foreach (string guid in guids) { string path = AssetDatabase.GUIDToAssetPath(guid); EnemyCharacterData enemyData = AssetDatabase.LoadAssetAtPath(path); if (enemyData != null) { EnemyCharacterCreator.GenerateEnemyCharacterScript(enemyData); count++; } } EditorUtility.DisplayDialog("Batch Generation Complete", $"Generated {count} enemy character scripts.", "OK"); } [MenuItem("RPG/Characters/Open Enemy Scripts Folder")] public static void OpenEnemyScriptsFolder() { string folderPath = Path.Combine(Application.dataPath, "Scripts/Characters/Enemies"); if (Directory.Exists(folderPath)) { EditorUtility.RevealInFinder(folderPath); } else { Debug.LogWarning("Enemy scripts folder does not exist: " + folderPath); } } }