using UnityEngine; using UnityEditor; using JetBrains.Annotations; namespace LLM.Editor.Commands { [System.Serializable] public class CreatePrefabParams { public string sourceObjectQuery; // e.g., "Racer t:Model" public string defaultName; // e.g., "Racer.prefab" } [UsedImplicitly] public class CreatePrefabCommand : ICommand { // This key is used to pass the chosen path to subsequent commands. public const string CONTEXT_KEY_PREFAB_PATH = "lastCreatedPrefabPath"; private readonly CreatePrefabParams _params; public CreatePrefabCommand(string jsonParams) { _params = JsonUtility.FromJson(jsonParams); } public void Execute(Data.CommandContext context) { // Step 1: Ask the user for a save path. var path = EditorUtility.SaveFilePanel("Save New Prefab", "Assets/", _params.defaultName, "prefab"); if (string.IsNullOrEmpty(path)) { Debug.LogWarning("[CreatePrefabCommand] User cancelled save dialog. Aborting."); // We could clear the command queue here if we want cancellation to stop everything. return; } // We need a relative path for AssetDatabase var prefabPath = "Assets" + path[Application.dataPath.Length..]; // Step 2: Find the source asset. var guids = AssetDatabase.FindAssets(_params.sourceObjectQuery); if (guids.Length == 0) { Debug.LogError($"[CreatePrefabCommand] No asset found for query: '{_params.sourceObjectQuery}'"); return; } var assetPath = AssetDatabase.GUIDToAssetPath(guids[0]); var sourceAsset = AssetDatabase.LoadAssetAtPath(assetPath); // Step 3: Create the prefab. var instance = (GameObject)PrefabUtility.InstantiatePrefab(sourceAsset); PrefabUtility.SaveAsPrefabAsset(instance, prefabPath); Object.DestroyImmediate(instance); // Step 4: Store the chosen path in the context for the next commands. context.transientData[CONTEXT_KEY_PREFAB_PATH] = prefabPath; Debug.Log($"[CreatePrefabCommand] Created prefab at '{prefabPath}' from source '{assetPath}'."); } } }