12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- using UnityEngine;
- using UnityEditor;
- using LLM.Editor.Helper;
- using JetBrains.Annotations;
- namespace LLM.Editor.Commands
- {
- [System.Serializable]
- public class CreatePrefabParams
- {
- public string sourceObjectQuery;
- public string defaultName;
- }
- [UsedImplicitly]
- public class CreatePrefabCommand : ICommand
- {
- private readonly CreatePrefabParams _params;
- public CreatePrefabCommand(string jsonParams)
- {
- _params = jsonParams?.FromJson<CreatePrefabParams>();
- }
- public void Execute(Data.CommandContext context)
- {
- // Step 1: Find the source asset.
- var guids = AssetDatabase.FindAssets(_params.sourceObjectQuery);
- if (guids.Length == 0)
- {
- Debug.LogError($"[CreatePrefabCommand] No asset found for query: '{_params.sourceObjectQuery}'");
- var choice = TryGetAnyModelFromUserChoice(_params.sourceObjectQuery, out var objPath);
- if (!choice) return;
- var relativeObjPath = "Assets" + objPath[Application.dataPath.Length..];
- guids = new [] { AssetDatabase.AssetPathToGUID(relativeObjPath) };
- }
-
- var assetPath = AssetDatabase.GUIDToAssetPath(guids[0]);
- var sourceAsset = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
-
- // Step 2: 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 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.CurrentSubject = prefabPath;
- Debug.Log($"[CreatePrefabCommand] Created prefab at '{prefabPath}' from source '{assetPath}'.");
- }
- private static bool TryGetAnyModelFromUserChoice(string sourceObjectQuery, out string prefabPath)
- {
- const string message = "Do you want to select a model to create a prefab from? Choosing 'no' will fail to execute forthcoming commands as well.";
- var result = EditorUtility.DisplayDialog($"{sourceObjectQuery} is not found", message, "OK", "No");
- if (!result)
- {
- prefabPath = null;
- return false;
- }
- prefabPath = EditorUtility.OpenFilePanel("Choose the model to create prefab from", "", "obj,fbx,stl,gltf,glb,usdz,dae");
- if (string.IsNullOrEmpty(prefabPath))
- {
- prefabPath = null;
- return false;
- }
-
- Debug.Log($"[CreatePrefabCommand] User selected '{prefabPath}'.");
-
- var isInsideAssets = prefabPath.StartsWith(Application.dataPath);
- if (isInsideAssets) return true;
- prefabPath = null;
- return false;
- }
- }
- }
|