using UnityEngine; using UnityEditor; using System.Collections.Generic; using System.Linq; using System; public partial class AbilityEditorWindow { private void DrawExistingAbilities() { EditorGUILayout.LabelField("Existing Abilities", EditorStyles.boldLabel); var abilities = GetAllAbilities(); foreach (var ability in abilities) { if (string.IsNullOrEmpty(searchQuery) || ability.name.ToLower().Contains(searchQuery.ToLower())) { EditorGUILayout.BeginVertical("box"); DrawAbilityItem(ability); EditorGUILayout.EndVertical(); } } } private void DrawAbilityItem(BaseAbility ability) { EditorGUILayout.BeginHorizontal(); if (ability.Icon != null) { GUILayout.Label(AssetPreview.GetAssetPreview(ability.Icon), GUILayout.Width(40), GUILayout.Height(40)); } EditorGUILayout.BeginVertical(); EditorGUILayout.LabelField(ability.name, EditorStyles.boldLabel); EditorGUILayout.LabelField($"Type: {ability.GetType().Name}"); EditorGUILayout.EndVertical(); if (GUILayout.Button("Clone", GUILayout.Width(50))) { CloneAbility(ability); } if (GUILayout.Button("Edit", GUILayout.Width(50))) { Selection.activeObject = ability; EditorUtility.FocusProjectWindow(); } EditorGUILayout.EndHorizontal(); } private void CloneAbility(BaseAbility sourceAbility) { string newName = $"{sourceAbility.name}_Clone"; string path = EditorUtility.SaveFilePanelInProject( "Save Cloned Ability", newName, "asset", "Save cloned ability asset" ); if (string.IsNullOrEmpty(path)) return; BaseAbility newAbility = (BaseAbility)CreateInstance(sourceAbility.GetType()); EditorUtility.CopySerialized(sourceAbility, newAbility); newAbility.name = newName; AssetDatabase.CreateAsset(newAbility, path); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); EditorUtility.FocusProjectWindow(); Selection.activeObject = newAbility; } private void CreateAbility() { if (selectedAbilityType == null) { EditorUtility.DisplayDialog("Error", "Please select an ability type!", "OK"); return; } if (string.IsNullOrEmpty(abilityData.name)) { EditorUtility.DisplayDialog("Error", "Ability name cannot be empty!", "OK"); return; } BaseAbility ability = (BaseAbility)CreateInstance(selectedAbilityType); ability.name = abilityData.name; ability.Icon = abilityData.icon; ability.animationType = abilityData.animationType; ability.manaCost = abilityData.manaCost; ability.healthCost = abilityData.healthCost; ability.cooldown = abilityData.cooldown; ability.castTime = abilityData.castTime; ability.castableWhileMoving = abilityData.castableWhileMoving; ApplyTypeSpecificData(ability); string path = EditorUtility.SaveFilePanelInProject( "Save Ability", abilityData.name, "asset", "Save ability asset" ); if (!string.IsNullOrEmpty(path)) { AssetDatabase.CreateAsset(ability, path); AssetDatabase.SaveAssets(); EditorUtility.FocusProjectWindow(); Selection.activeObject = ability; abilityData = new AbilityCreationData(); selectedAbilityType = null; } } private void ApplyTypeSpecificData(BaseAbility ability) { if (ability is ProjectileAbility projectileAbility) { projectileAbility.projectileSpeed = abilityData.GetOrCreateTypeSpecific("projectileSpeed"); projectileAbility.lifeSpan = abilityData.GetOrCreateTypeSpecific("lifeSpan"); projectileAbility.canPierce = abilityData.GetOrCreateTypeSpecific("canPierce"); projectileAbility.projectilePrefab = abilityData.GetOrCreateTypeSpecific("projectilePrefab"); } else if (ability is AreaOfEffectAbility aoeAbility) { aoeAbility.radius = abilityData.GetOrCreateTypeSpecific("radius"); aoeAbility.lifeSpan = abilityData.GetOrCreateTypeSpecific("duration"); aoeAbility.aoePrefab = abilityData.GetOrCreateTypeSpecific("aoePrefab"); } else if (ability is ChanneledAbility channeledAbility) { channeledAbility.duration = abilityData.GetOrCreateTypeSpecific("channelDuration"); channeledAbility.castableWhileMoving = abilityData.GetOrCreateTypeSpecific("canMove"); } } private BaseAbility[] GetAllAbilities() { return AssetDatabase.FindAssets("t:BaseAbility") .Select(guid => AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid))) .ToArray(); } }