Merge remote-tracking branch 'origin/feat/inport-props' into feat/craft-discovery
# Conflicts: # Assets/External/Animated PBR Chest Demo/Materials/WoodChest.mat # Packages/com.distantlands.cozy.core/Content/Integration/Import for BiRP.unitypackage.meta # Packages/com.distantlands.cozy.core/Content/Integration/Import for HDRP.unitypackage.meta # Packages/com.distantlands.cozy.core/Content/Integration/Import for URP.unitypackage.meta
This commit is contained in:
@@ -181,8 +181,8 @@ namespace Ashwild.EditorTools
|
||||
|
||||
/// <summary>
|
||||
/// Target card: a Prefab/Mesh kind selector that filters the object picker to only those assets
|
||||
/// (so materials, scripts and the like never clutter it), the object field itself, plus quick
|
||||
/// Frame and auto-rotate controls that act on the loaded subject.
|
||||
/// (so materials, scripts and the like never clutter it), the object field itself, per-axis
|
||||
/// rotation sliders that pose the subject, plus quick Frame and auto-rotate controls.
|
||||
/// </summary>
|
||||
private VisualElement BuildTargetCard()
|
||||
{
|
||||
@@ -206,6 +206,13 @@ namespace Ashwild.EditorTools
|
||||
card.Add(kind);
|
||||
card.Add(field);
|
||||
|
||||
card.Add(SliderRow("Rotate X", 0f, 360f, stage.SubjectEuler.x,
|
||||
v => stage.SetSubjectRotation(new Vector3(v, stage.SubjectEuler.y, stage.SubjectEuler.z))));
|
||||
card.Add(SliderRow("Rotate Y", 0f, 360f, stage.SubjectEuler.y,
|
||||
v => stage.SetSubjectRotation(new Vector3(stage.SubjectEuler.x, v, stage.SubjectEuler.z))));
|
||||
card.Add(SliderRow("Rotate Z", 0f, 360f, stage.SubjectEuler.z,
|
||||
v => stage.SetSubjectRotation(new Vector3(stage.SubjectEuler.x, stage.SubjectEuler.y, v))));
|
||||
|
||||
VisualElement buttons = new VisualElement();
|
||||
buttons.AddToClassList("ss-buttons");
|
||||
|
||||
@@ -213,6 +220,10 @@ namespace Ashwild.EditorTools
|
||||
frame.AddToClassList("ss-btn");
|
||||
buttons.Add(frame);
|
||||
|
||||
Button resetRotation = new Button(() => { stage.SetSubjectRotation(Vector3.zero); RebuildControls(); RenderPreview(); }) { text = "Reset Rotation" };
|
||||
resetRotation.AddToClassList("ss-btn");
|
||||
buttons.Add(resetRotation);
|
||||
|
||||
Toggle rotate = new Toggle("Auto-rotate") { value = autoRotate };
|
||||
rotate.RegisterValueChangedCallback(evt => SetAutoRotate(evt.newValue));
|
||||
buttons.Add(rotate);
|
||||
@@ -355,7 +366,10 @@ namespace Ashwild.EditorTools
|
||||
|
||||
/// <summary>
|
||||
/// Builds the output-folder row: a read-only path label and a Browse button that opens a folder
|
||||
/// picker and remembers the choice in EditorPrefs.
|
||||
/// picker and remembers the choice in EditorPrefs. The picker starts from the resolved export
|
||||
/// folder (normalised to native separators) so it opens where the label points — the native
|
||||
/// Windows dialog ignores forward-slash paths like Application.dataPath and would otherwise fall
|
||||
/// back to the shell's last-used location (often another project entirely).
|
||||
/// </summary>
|
||||
private VisualElement BuildFolderRow()
|
||||
{
|
||||
@@ -364,11 +378,12 @@ namespace Ashwild.EditorTools
|
||||
|
||||
Label path = new Label(ShortFolder());
|
||||
path.AddToClassList("ss-path");
|
||||
path.tooltip = exportFolder;
|
||||
path.tooltip = ResolveFolder();
|
||||
|
||||
Button browse = new Button(() =>
|
||||
{
|
||||
string chosen = EditorUtility.OpenFolderPanel("Export folder", exportFolder, string.Empty);
|
||||
string start = ResolveFolder().Replace('/', Path.DirectorySeparatorChar);
|
||||
string chosen = EditorUtility.OpenFolderPanel("Export folder", start, string.Empty);
|
||||
if (string.IsNullOrEmpty(chosen)) return;
|
||||
exportFolder = chosen;
|
||||
EditorPrefs.SetString(FolderPrefKey, exportFolder);
|
||||
@@ -627,8 +642,8 @@ namespace Ashwild.EditorTools
|
||||
|
||||
/// <summary>
|
||||
/// Captures the current view at the export resolution and writes it as a PNG to the chosen folder,
|
||||
/// avoiding overwrites by auto-numbering, refreshing the AssetDatabase when the path is in-project,
|
||||
/// and revealing the file. Guards a missing target and failed writes with clear logs.
|
||||
/// avoiding overwrites by auto-numbering, importing it as a single-mode Sprite when the path is
|
||||
/// in-project, and revealing the file. Guards a missing target and failed writes with clear logs.
|
||||
/// </summary>
|
||||
private void ExportPng()
|
||||
{
|
||||
@@ -656,7 +671,7 @@ namespace Ashwild.EditorTools
|
||||
}
|
||||
|
||||
EditorPrefs.SetString(FilePrefKey, exportFileName);
|
||||
RefreshIfInProject(path);
|
||||
ImportAsSprite(path);
|
||||
Debug.Log($"[ScreenshotStudio] Exported {exportWidth}×{exportHeight} PNG → {path}");
|
||||
ShowNotification(new GUIContent($"Exported {Path.GetFileName(path)}"));
|
||||
}
|
||||
@@ -676,6 +691,7 @@ namespace Ashwild.EditorTools
|
||||
string folder = ResolveFolder();
|
||||
string baseName = Path.GetFileNameWithoutExtension(ResolveFileName());
|
||||
float startYaw = stage.Yaw;
|
||||
System.Collections.Generic.List<string> written = new System.Collections.Generic.List<string>();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -691,7 +707,9 @@ namespace Ashwild.EditorTools
|
||||
|
||||
byte[] png = frame.EncodeToPNG();
|
||||
DestroyImmediate(frame);
|
||||
File.WriteAllBytes(Path.Combine(folder, $"{baseName}_{i:000}.png"), png);
|
||||
string framePath = Path.Combine(folder, $"{baseName}_{i:000}.png");
|
||||
File.WriteAllBytes(framePath, png);
|
||||
written.Add(framePath);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -702,10 +720,10 @@ namespace Ashwild.EditorTools
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
stage.Yaw = startYaw;
|
||||
RefreshIfInProject(folder);
|
||||
foreach (string framePath in written) ImportAsSprite(framePath);
|
||||
RenderPreview();
|
||||
Debug.Log($"[ScreenshotStudio] Exported {turntableFrames}-frame turntable → {folder}");
|
||||
ShowNotification(new GUIContent($"Exported {turntableFrames} frames"));
|
||||
Debug.Log($"[ScreenshotStudio] Exported {written.Count}-frame turntable → {folder}");
|
||||
ShowNotification(new GUIContent($"Exported {written.Count} frames"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -752,15 +770,40 @@ namespace Ashwild.EditorTools
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports the written file so it appears in the Project window when it lives under Assets.
|
||||
/// The project-relative "Assets/…" path for a written file, or null when it lives outside the
|
||||
/// project — so external-folder exports skip the in-project import step entirely.
|
||||
/// </summary>
|
||||
private static void RefreshIfInProject(string path)
|
||||
private static string ToAssetPath(string path)
|
||||
{
|
||||
string full = Path.GetFullPath(path).Replace('\\', '/');
|
||||
string root = Path.GetFullPath(Application.dataPath).Replace('\\', '/');
|
||||
if (!full.StartsWith(root, StringComparison.OrdinalIgnoreCase)) return;
|
||||
if (!full.StartsWith(root, StringComparison.OrdinalIgnoreCase)) return null;
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
return "Assets" + full.Substring(root.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports the written file when it lives under Assets and retypes it as a single-mode Sprite, so
|
||||
/// studio exports drop straight into UI/inventory work without a manual texture-type change in the
|
||||
/// inspector. Files exported to an external folder are left untouched.
|
||||
/// </summary>
|
||||
private static void ImportAsSprite(string path)
|
||||
{
|
||||
string assetPath = ToAssetPath(path);
|
||||
if (assetPath == null) return;
|
||||
|
||||
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceSynchronousImport);
|
||||
|
||||
TextureImporter importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
|
||||
if (importer == null)
|
||||
{
|
||||
Debug.LogError($"[ScreenshotStudio] No TextureImporter for '{assetPath}' — cannot set Sprite type.");
|
||||
return;
|
||||
}
|
||||
|
||||
importer.textureType = TextureImporterType.Sprite;
|
||||
importer.spriteImportMode = SpriteImportMode.Single;
|
||||
importer.SaveAndReimport();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user