Add a sprite variant generator and create monster prefabs for heads
This commit is contained in:
@@ -3,34 +3,74 @@ using UnityEngine;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityEditor.Experimental.SceneManagement;
|
using System.Text;
|
||||||
|
|
||||||
namespace Editor
|
namespace Editor
|
||||||
{
|
{
|
||||||
public class PrefabVariantGeneratorWindow : EditorWindow
|
public class PrefabVariantGeneratorWindow : EditorWindow
|
||||||
{
|
{
|
||||||
|
// Renderer configuration class to track sprite renderers and their assigned sprites
|
||||||
|
[System.Serializable]
|
||||||
|
private class RendererConfig
|
||||||
|
{
|
||||||
|
public string Path; // Hierarchy path to the renderer
|
||||||
|
public string Name; // Display name for the renderer
|
||||||
|
public SpriteRenderer Renderer; // Reference to the actual renderer
|
||||||
|
public Sprite CurrentSprite; // Current sprite in the renderer
|
||||||
|
public List<Sprite> AssignedSprites = new List<Sprite>(); // Sprites to use for variants
|
||||||
|
public bool Enabled = true; // Whether to include in variant generation
|
||||||
|
public bool Expanded = true; // UI expanded state
|
||||||
|
public Vector2 ScrollPosition; // Scroll position for sprite list
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main fields
|
||||||
private GameObject sourcePrefab;
|
private GameObject sourcePrefab;
|
||||||
private GameObject previousSourcePrefab;
|
private GameObject previousSourcePrefab;
|
||||||
private List<Sprite> selectedSprites = new List<Sprite>();
|
private List<RendererConfig> detectedRenderers = new List<RendererConfig>();
|
||||||
private Vector2 scrollPosition;
|
private Vector2 mainScrollPosition;
|
||||||
private string variantSaveFolder = "Assets/Prefabs/Variants";
|
private string variantSaveFolder = "Assets/Prefabs/Variants";
|
||||||
private string namingPattern = "{0}_{1}"; // {0} = prefab name, {1} = sprite name
|
private string namingPattern = "{0}_{1}"; // Default: {0} = prefab name, {1} = first renderer sprite
|
||||||
private bool userChangedSavePath = false;
|
private bool userChangedSavePath = false;
|
||||||
|
private int estimatedVariantCount = 0;
|
||||||
|
private int maxSafeVariantCount = 100; // Warn above this number
|
||||||
|
private GUIStyle boldFoldoutStyle;
|
||||||
|
private bool showDefaultHelp = true;
|
||||||
|
|
||||||
[MenuItem("Tools/Prefab Variant Generator")]
|
// Editor window setup
|
||||||
|
[MenuItem("Tools/Sprite Variant Generator")]
|
||||||
public static void ShowWindow()
|
public static void ShowWindow()
|
||||||
{
|
{
|
||||||
var window = GetWindow<PrefabVariantGeneratorWindow>("Prefab Variant Generator");
|
var window = GetWindow<PrefabVariantGeneratorWindow>("Prefab Variant Generator");
|
||||||
window.minSize = new Vector2(400, 500);
|
window.minSize = new Vector2(500, 600);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
// Initialize styles on enable to avoid null reference issues
|
||||||
|
boldFoldoutStyle = new GUIStyle(EditorStyles.foldout)
|
||||||
|
{
|
||||||
|
fontStyle = FontStyle.Bold
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGUI()
|
private void OnGUI()
|
||||||
{
|
{
|
||||||
|
// Initialize styles if needed
|
||||||
|
if (boldFoldoutStyle == null)
|
||||||
|
{
|
||||||
|
boldFoldoutStyle = new GUIStyle(EditorStyles.foldout)
|
||||||
|
{
|
||||||
|
fontStyle = FontStyle.Bold
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
EditorGUILayout.LabelField("Prefab Variant Generator", EditorStyles.boldLabel);
|
EditorGUILayout.LabelField("Prefab Variant Generator", EditorStyles.boldLabel);
|
||||||
EditorGUILayout.HelpBox("This tool generates prefab variants with different sprites assigned to a sprite renderer.", MessageType.Info);
|
EditorGUILayout.HelpBox("Create multiple prefab variants with different sprites assigned to renderers.", MessageType.Info);
|
||||||
EditorGUILayout.Space();
|
|
||||||
|
mainScrollPosition = EditorGUILayout.BeginScrollView(mainScrollPosition);
|
||||||
|
|
||||||
// Source Prefab Selection
|
// Source Prefab Selection
|
||||||
|
EditorGUILayout.Space();
|
||||||
EditorGUILayout.LabelField("Step 1: Select Source Prefab", EditorStyles.boldLabel);
|
EditorGUILayout.LabelField("Step 1: Select Source Prefab", EditorStyles.boldLabel);
|
||||||
|
|
||||||
// Store previous selection to detect changes
|
// Store previous selection to detect changes
|
||||||
@@ -51,6 +91,15 @@ namespace Editor
|
|||||||
variantSaveFolder = Path.GetDirectoryName(prefabPath).Replace("\\", "/");
|
variantSaveFolder = Path.GetDirectoryName(prefabPath).Replace("\\", "/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find sprite renderers in the prefab
|
||||||
|
FindRenderersInPrefab();
|
||||||
|
|
||||||
|
// Clear default help once a prefab is selected
|
||||||
|
if (sourcePrefab != null)
|
||||||
|
{
|
||||||
|
showDefaultHelp = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warn if not a prefab
|
// Warn if not a prefab
|
||||||
@@ -59,116 +108,42 @@ namespace Editor
|
|||||||
EditorGUILayout.HelpBox("Please select a prefab asset.", MessageType.Warning);
|
EditorGUILayout.HelpBox("Please select a prefab asset.", MessageType.Warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sprite Selection
|
// Display default help if no prefab selected
|
||||||
|
if (showDefaultHelp && sourcePrefab == null)
|
||||||
|
{
|
||||||
|
EditorGUILayout.HelpBox(
|
||||||
|
"This tool lets you create prefab variants with different sprites.\n\n" +
|
||||||
|
"1. Select a source prefab\n" +
|
||||||
|
"2. Assign sprites to each detected sprite renderer\n" +
|
||||||
|
"3. Generate all combinations as prefab variants",
|
||||||
|
MessageType.Info
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only show the rest if a valid prefab is selected
|
||||||
|
if (sourcePrefab != null)
|
||||||
|
{
|
||||||
|
// Renderer sections
|
||||||
EditorGUILayout.Space();
|
EditorGUILayout.Space();
|
||||||
EditorGUILayout.LabelField("Step 2: Select Sprites", EditorStyles.boldLabel);
|
EditorGUILayout.LabelField("Step 2: Configure Sprite Renderers", EditorStyles.boldLabel);
|
||||||
EditorGUILayout.BeginHorizontal();
|
|
||||||
|
|
||||||
// Drag and drop area for sprites
|
if (detectedRenderers.Count == 0)
|
||||||
EditorGUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.Height(80));
|
|
||||||
EditorGUILayout.LabelField("Drag and drop sprites here", EditorStyles.centeredGreyMiniLabel);
|
|
||||||
|
|
||||||
Rect dropArea = GUILayoutUtility.GetRect(0, 50, GUILayout.ExpandWidth(true));
|
|
||||||
Event evt = Event.current;
|
|
||||||
switch (evt.type)
|
|
||||||
{
|
{
|
||||||
case EventType.DragUpdated:
|
EditorGUILayout.HelpBox("No sprite renderers found in prefab. A new renderer will be created.", MessageType.Info);
|
||||||
case EventType.DragPerform:
|
|
||||||
if (!dropArea.Contains(evt.mousePosition))
|
|
||||||
break;
|
|
||||||
|
|
||||||
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
|
|
||||||
|
|
||||||
if (evt.type == EventType.DragPerform)
|
|
||||||
{
|
|
||||||
DragAndDrop.AcceptDrag();
|
|
||||||
|
|
||||||
foreach (var draggedObject in DragAndDrop.objectReferences)
|
|
||||||
{
|
|
||||||
if (draggedObject is Sprite sprite)
|
|
||||||
{
|
|
||||||
if (!selectedSprites.Contains(sprite))
|
|
||||||
selectedSprites.Add(sprite);
|
|
||||||
}
|
}
|
||||||
else if (draggedObject is Texture2D texture)
|
else
|
||||||
{
|
{
|
||||||
// Try to get sprites from texture
|
EditorGUILayout.HelpBox($"{detectedRenderers.Count} sprite renderer{(detectedRenderers.Count > 1 ? "s" : "")} found in prefab.", MessageType.Info);
|
||||||
string texturePath = AssetDatabase.GetAssetPath(texture);
|
|
||||||
var sprites = AssetDatabase.LoadAllAssetsAtPath(texturePath)
|
|
||||||
.OfType<Sprite>()
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
foreach (var s in sprites)
|
|
||||||
{
|
|
||||||
if (!selectedSprites.Contains(s))
|
|
||||||
selectedSprites.Add(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
evt.Use();
|
// Display each renderer configuration
|
||||||
}
|
for (int i = 0; i < detectedRenderers.Count; i++)
|
||||||
break;
|
|
||||||
}
|
|
||||||
EditorGUILayout.EndVertical();
|
|
||||||
|
|
||||||
if (GUILayout.Button("Add Selected Sprites", GUILayout.Width(120), GUILayout.Height(80)))
|
|
||||||
{
|
{
|
||||||
var selectedObjects = Selection.objects;
|
DrawRendererSection(detectedRenderers[i], i);
|
||||||
foreach (var obj in selectedObjects)
|
|
||||||
{
|
|
||||||
if (obj is Sprite sprite)
|
|
||||||
{
|
|
||||||
if (!selectedSprites.Contains(sprite))
|
|
||||||
selectedSprites.Add(sprite);
|
|
||||||
}
|
|
||||||
else if (obj is Texture2D texture)
|
|
||||||
{
|
|
||||||
// Try to get sprites from texture
|
|
||||||
string texturePath = AssetDatabase.GetAssetPath(texture);
|
|
||||||
var sprites = AssetDatabase.LoadAllAssetsAtPath(texturePath)
|
|
||||||
.OfType<Sprite>()
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
foreach (var s in sprites)
|
|
||||||
{
|
|
||||||
if (!selectedSprites.Contains(s))
|
|
||||||
selectedSprites.Add(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorGUILayout.EndHorizontal();
|
// Update estimated variant count
|
||||||
|
UpdateVariantCount();
|
||||||
if (GUILayout.Button("Clear Sprites"))
|
|
||||||
{
|
|
||||||
selectedSprites.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display selected sprites
|
|
||||||
EditorGUILayout.Space();
|
|
||||||
EditorGUILayout.LabelField($"Selected Sprites ({selectedSprites.Count}):", EditorStyles.boldLabel);
|
|
||||||
|
|
||||||
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition, GUILayout.Height(150));
|
|
||||||
for (int i = selectedSprites.Count - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
EditorGUILayout.BeginHorizontal();
|
|
||||||
selectedSprites[i] = (Sprite)EditorGUILayout.ObjectField(selectedSprites[i], typeof(Sprite), false);
|
|
||||||
|
|
||||||
// Preview sprite
|
|
||||||
if (selectedSprites[i] != null)
|
|
||||||
{
|
|
||||||
GUILayout.Box(selectedSprites[i].texture, GUILayout.Width(40), GUILayout.Height(40));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GUILayout.Button("Remove", GUILayout.Width(60)))
|
|
||||||
{
|
|
||||||
selectedSprites.RemoveAt(i);
|
|
||||||
}
|
|
||||||
EditorGUILayout.EndHorizontal();
|
|
||||||
}
|
|
||||||
EditorGUILayout.EndScrollView();
|
|
||||||
|
|
||||||
// Output settings
|
// Output settings
|
||||||
EditorGUILayout.Space();
|
EditorGUILayout.Space();
|
||||||
@@ -189,7 +164,6 @@ namespace Editor
|
|||||||
}
|
}
|
||||||
EditorGUILayout.EndHorizontal();
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
// Naming pattern
|
|
||||||
// Add a reset button if user changed the path and a valid prefab is selected
|
// Add a reset button if user changed the path and a valid prefab is selected
|
||||||
if (userChangedSavePath && sourcePrefab != null)
|
if (userChangedSavePath && sourcePrefab != null)
|
||||||
{
|
{
|
||||||
@@ -204,23 +178,405 @@ namespace Editor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Naming pattern field
|
||||||
EditorGUILayout.BeginHorizontal();
|
EditorGUILayout.BeginHorizontal();
|
||||||
EditorGUILayout.PrefixLabel("Naming Pattern");
|
EditorGUILayout.PrefixLabel("Naming Pattern");
|
||||||
namingPattern = EditorGUILayout.TextField(namingPattern);
|
namingPattern = EditorGUILayout.TextField(namingPattern);
|
||||||
EditorGUILayout.EndHorizontal();
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
EditorGUILayout.HelpBox("Use {0} for prefab name and {1} for sprite name", MessageType.Info);
|
// Help text for naming pattern
|
||||||
|
StringBuilder helpText = new StringBuilder("Naming placeholders:\n");
|
||||||
|
helpText.AppendLine("{0} = Prefab name");
|
||||||
|
for (int i = 0; i < detectedRenderers.Count; i++)
|
||||||
|
{
|
||||||
|
helpText.AppendLine($"{{{i+1}}} = {detectedRenderers[i].Name} sprite name");
|
||||||
|
}
|
||||||
|
EditorGUILayout.HelpBox(helpText.ToString(), MessageType.Info);
|
||||||
|
|
||||||
|
// Variant count display
|
||||||
|
string variantCountText = $"Will generate {estimatedVariantCount} variant{(estimatedVariantCount != 1 ? "s" : "")}";
|
||||||
|
if (estimatedVariantCount > maxSafeVariantCount)
|
||||||
|
{
|
||||||
|
EditorGUILayout.HelpBox($"Warning: {variantCountText}. This might take some time.", MessageType.Warning);
|
||||||
|
}
|
||||||
|
else if (estimatedVariantCount > 0)
|
||||||
|
{
|
||||||
|
EditorGUILayout.HelpBox(variantCountText, MessageType.Info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorGUILayout.HelpBox("Please assign at least one sprite to each enabled renderer to generate variants.", MessageType.Warning);
|
||||||
|
}
|
||||||
|
|
||||||
// Generate button
|
// Generate button
|
||||||
EditorGUILayout.Space();
|
EditorGUILayout.Space();
|
||||||
GUI.enabled = sourcePrefab != null && selectedSprites.Count > 0;
|
GUI.enabled = estimatedVariantCount > 0;
|
||||||
if (GUILayout.Button("Generate Prefab Variants", GUILayout.Height(30)))
|
if (GUILayout.Button("Generate Prefab Variants", GUILayout.Height(30)))
|
||||||
{
|
{
|
||||||
|
// Show warning for large numbers of variants
|
||||||
|
if (estimatedVariantCount > maxSafeVariantCount)
|
||||||
|
{
|
||||||
|
bool proceed = EditorUtility.DisplayDialog(
|
||||||
|
"Generate Many Variants?",
|
||||||
|
$"You are about to generate {estimatedVariantCount} prefab variants. This might take some time and use significant disk space. Continue?",
|
||||||
|
"Generate",
|
||||||
|
"Cancel"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!proceed) return;
|
||||||
|
}
|
||||||
|
|
||||||
GeneratePrefabVariants();
|
GeneratePrefabVariants();
|
||||||
}
|
}
|
||||||
GUI.enabled = true;
|
GUI.enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.EndScrollView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawRendererSection(RendererConfig config, int index)
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
||||||
|
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
// Expand/collapse button
|
||||||
|
config.Expanded = EditorGUILayout.Foldout(config.Expanded, "", boldFoldoutStyle);
|
||||||
|
|
||||||
|
// Enable/disable toggle
|
||||||
|
bool newEnabled = EditorGUILayout.Toggle(config.Enabled, GUILayout.Width(20));
|
||||||
|
if (newEnabled != config.Enabled)
|
||||||
|
{
|
||||||
|
config.Enabled = newEnabled;
|
||||||
|
UpdateVariantCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Renderer name/title
|
||||||
|
EditorGUILayout.LabelField(config.Name, EditorStyles.boldLabel);
|
||||||
|
|
||||||
|
// Current sprite preview if available
|
||||||
|
if (config.CurrentSprite != null)
|
||||||
|
{
|
||||||
|
GUILayout.Box(
|
||||||
|
AssetPreview.GetAssetPreview(config.CurrentSprite),
|
||||||
|
GUILayout.Width(40),
|
||||||
|
GUILayout.Height(40)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
// Only show contents if expanded
|
||||||
|
if (config.Expanded)
|
||||||
|
{
|
||||||
|
// Path display
|
||||||
|
if (!string.IsNullOrEmpty(config.Path))
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField($"Path: {config.Path}", EditorStyles.miniLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUI.BeginDisabledGroup(!config.Enabled);
|
||||||
|
|
||||||
|
// Sprite selection controls
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
|
||||||
|
// Drag and drop area for sprites
|
||||||
|
EditorGUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.Height(60));
|
||||||
|
EditorGUILayout.LabelField("Drag and drop sprites here", EditorStyles.centeredGreyMiniLabel);
|
||||||
|
|
||||||
|
Rect dropArea = GUILayoutUtility.GetRect(0, 40, GUILayout.ExpandWidth(true));
|
||||||
|
HandleDragAndDrop(dropArea, config);
|
||||||
|
|
||||||
|
EditorGUILayout.EndVertical();
|
||||||
|
|
||||||
|
if (GUILayout.Button("Add Selected", GUILayout.Width(100), GUILayout.Height(60)))
|
||||||
|
{
|
||||||
|
AddSelectedSpritesToConfig(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
if (GUILayout.Button("Clear Sprites"))
|
||||||
|
{
|
||||||
|
config.AssignedSprites.Clear();
|
||||||
|
UpdateVariantCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display selected sprites
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
EditorGUILayout.LabelField($"Selected Sprites ({config.AssignedSprites.Count}):", EditorStyles.miniBoldLabel);
|
||||||
|
|
||||||
|
// Sprite list
|
||||||
|
config.ScrollPosition = EditorGUILayout.BeginScrollView(config.ScrollPosition, GUILayout.Height(120));
|
||||||
|
for (int i = config.AssignedSprites.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
config.AssignedSprites[i] = (Sprite)EditorGUILayout.ObjectField(
|
||||||
|
config.AssignedSprites[i],
|
||||||
|
typeof(Sprite),
|
||||||
|
false,
|
||||||
|
GUILayout.ExpandWidth(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Preview sprite
|
||||||
|
if (config.AssignedSprites[i] != null)
|
||||||
|
{
|
||||||
|
GUILayout.Box(
|
||||||
|
AssetPreview.GetAssetPreview(config.AssignedSprites[i]),
|
||||||
|
GUILayout.Width(40),
|
||||||
|
GUILayout.Height(40)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button("Remove", GUILayout.Width(60)))
|
||||||
|
{
|
||||||
|
config.AssignedSprites.RemoveAt(i);
|
||||||
|
UpdateVariantCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndScrollView();
|
||||||
|
|
||||||
|
EditorGUI.EndDisabledGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.EndVertical();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleDragAndDrop(Rect dropArea, RendererConfig config)
|
||||||
|
{
|
||||||
|
Event evt = Event.current;
|
||||||
|
switch (evt.type)
|
||||||
|
{
|
||||||
|
case EventType.DragUpdated:
|
||||||
|
case EventType.DragPerform:
|
||||||
|
if (!dropArea.Contains(evt.mousePosition))
|
||||||
|
break;
|
||||||
|
|
||||||
|
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
|
||||||
|
|
||||||
|
if (evt.type == EventType.DragPerform)
|
||||||
|
{
|
||||||
|
DragAndDrop.AcceptDrag();
|
||||||
|
bool added = false;
|
||||||
|
|
||||||
|
foreach (var draggedObject in DragAndDrop.objectReferences)
|
||||||
|
{
|
||||||
|
if (draggedObject is Sprite sprite)
|
||||||
|
{
|
||||||
|
if (!config.AssignedSprites.Contains(sprite))
|
||||||
|
{
|
||||||
|
config.AssignedSprites.Add(sprite);
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (draggedObject is Texture2D texture)
|
||||||
|
{
|
||||||
|
// Try to get sprites from texture
|
||||||
|
string texturePath = AssetDatabase.GetAssetPath(texture);
|
||||||
|
var sprites = AssetDatabase.LoadAllAssetsAtPath(texturePath)
|
||||||
|
.OfType<Sprite>()
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
foreach (var s in sprites)
|
||||||
|
{
|
||||||
|
if (!config.AssignedSprites.Contains(s))
|
||||||
|
{
|
||||||
|
config.AssignedSprites.Add(s);
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (added)
|
||||||
|
{
|
||||||
|
UpdateVariantCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
evt.Use();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddSelectedSpritesToConfig(RendererConfig config)
|
||||||
|
{
|
||||||
|
var selectedObjects = Selection.objects;
|
||||||
|
bool added = false;
|
||||||
|
|
||||||
|
foreach (var obj in selectedObjects)
|
||||||
|
{
|
||||||
|
if (obj is Sprite sprite)
|
||||||
|
{
|
||||||
|
if (!config.AssignedSprites.Contains(sprite))
|
||||||
|
{
|
||||||
|
config.AssignedSprites.Add(sprite);
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (obj is Texture2D texture)
|
||||||
|
{
|
||||||
|
// Try to get sprites from texture
|
||||||
|
string texturePath = AssetDatabase.GetAssetPath(texture);
|
||||||
|
var sprites = AssetDatabase.LoadAllAssetsAtPath(texturePath)
|
||||||
|
.OfType<Sprite>()
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
foreach (var s in sprites)
|
||||||
|
{
|
||||||
|
if (!config.AssignedSprites.Contains(s))
|
||||||
|
{
|
||||||
|
config.AssignedSprites.Add(s);
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (added)
|
||||||
|
{
|
||||||
|
UpdateVariantCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FindRenderersInPrefab()
|
||||||
|
{
|
||||||
|
detectedRenderers.Clear();
|
||||||
|
|
||||||
|
if (sourcePrefab == null) return;
|
||||||
|
|
||||||
|
// Get all renderers in prefab (including children)
|
||||||
|
GameObject instance = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
instance = (GameObject)PrefabUtility.InstantiatePrefab(sourcePrefab);
|
||||||
|
SpriteRenderer[] renderers = instance.GetComponentsInChildren<SpriteRenderer>(true);
|
||||||
|
|
||||||
|
for (int i = 0; i < renderers.Length; i++)
|
||||||
|
{
|
||||||
|
var renderer = renderers[i];
|
||||||
|
string path = GetRelativePath(instance.transform, renderer.transform);
|
||||||
|
string name = renderer.gameObject.name;
|
||||||
|
|
||||||
|
// For root object, use "Main"
|
||||||
|
if (string.IsNullOrEmpty(path))
|
||||||
|
{
|
||||||
|
name = "Main";
|
||||||
|
}
|
||||||
|
// For objects with the same name, add index
|
||||||
|
else if (renderers.Count(r => r.gameObject.name == renderer.gameObject.name) > 1)
|
||||||
|
{
|
||||||
|
name = $"{name} ({i+1})";
|
||||||
|
}
|
||||||
|
|
||||||
|
detectedRenderers.Add(new RendererConfig
|
||||||
|
{
|
||||||
|
Path = path,
|
||||||
|
Name = name,
|
||||||
|
Renderer = renderer,
|
||||||
|
CurrentSprite = renderer.sprite,
|
||||||
|
AssignedSprites = renderer.sprite != null ?
|
||||||
|
new List<Sprite> { renderer.sprite } :
|
||||||
|
new List<Sprite>()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (instance != null)
|
||||||
|
DestroyImmediate(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no renderers found, create a default entry
|
||||||
|
if (detectedRenderers.Count == 0)
|
||||||
|
{
|
||||||
|
detectedRenderers.Add(new RendererConfig
|
||||||
|
{
|
||||||
|
Path = "",
|
||||||
|
Name = "Main",
|
||||||
|
Renderer = null,
|
||||||
|
CurrentSprite = null,
|
||||||
|
AssignedSprites = new List<Sprite>()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateVariantCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetRelativePath(Transform root, Transform target)
|
||||||
|
{
|
||||||
|
if (target == root) return "";
|
||||||
|
|
||||||
|
string path = target.name;
|
||||||
|
Transform parent = target.parent;
|
||||||
|
|
||||||
|
while (parent != null && parent != root)
|
||||||
|
{
|
||||||
|
path = parent.name + "/" + path;
|
||||||
|
parent = parent.parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateVariantCount()
|
||||||
|
{
|
||||||
|
// Calculate estimated variants
|
||||||
|
estimatedVariantCount = 0;
|
||||||
|
|
||||||
|
// Get only enabled renderers with at least one sprite
|
||||||
|
var enabledConfigs = detectedRenderers
|
||||||
|
.Where(r => r.Enabled && r.AssignedSprites.Count > 0)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (enabledConfigs.Count > 0)
|
||||||
|
{
|
||||||
|
// Start with count of first renderer's sprites
|
||||||
|
estimatedVariantCount = enabledConfigs[0].AssignedSprites.Count;
|
||||||
|
|
||||||
|
// Multiply by subsequent renderers' sprite counts
|
||||||
|
for (int i = 1; i < enabledConfigs.Count; i++)
|
||||||
|
{
|
||||||
|
estimatedVariantCount *= enabledConfigs[i].AssignedSprites.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<List<Sprite>> GenerateAllCombinations()
|
||||||
|
{
|
||||||
|
var enabledConfigs = detectedRenderers
|
||||||
|
.Where(r => r.Enabled && r.AssignedSprites.Count > 0)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (enabledConfigs.Count == 0)
|
||||||
|
return new List<List<Sprite>>();
|
||||||
|
|
||||||
|
// Initialize with first renderer's sprites
|
||||||
|
var combinations = enabledConfigs[0].AssignedSprites
|
||||||
|
.Select(s => new List<Sprite> { s })
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// Add each subsequent renderer's sprites
|
||||||
|
for (int i = 1; i < enabledConfigs.Count; i++)
|
||||||
|
{
|
||||||
|
var newCombinations = new List<List<Sprite>>();
|
||||||
|
foreach (var combo in combinations)
|
||||||
|
{
|
||||||
|
foreach (var sprite in enabledConfigs[i].AssignedSprites)
|
||||||
|
{
|
||||||
|
var newCombo = new List<Sprite>(combo) { sprite };
|
||||||
|
newCombinations.Add(newCombo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
combinations = newCombinations;
|
||||||
|
}
|
||||||
|
|
||||||
|
return combinations;
|
||||||
|
}
|
||||||
|
|
||||||
private void GeneratePrefabVariants()
|
private void GeneratePrefabVariants()
|
||||||
{
|
{
|
||||||
if (sourcePrefab == null)
|
if (sourcePrefab == null)
|
||||||
@@ -229,44 +585,78 @@ namespace Editor
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedSprites.Count == 0)
|
// Get enabled renderer configurations
|
||||||
|
var enabledConfigs = detectedRenderers
|
||||||
|
.Where(r => r.Enabled && r.AssignedSprites.Count > 0)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (enabledConfigs.Count == 0)
|
||||||
{
|
{
|
||||||
EditorUtility.DisplayDialog("Error", "Please select at least one sprite.", "OK");
|
EditorUtility.DisplayDialog("Error", "Please assign at least one sprite to a renderer.", "OK");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the save folder exists
|
// Ensure the save folder exists
|
||||||
if (!AssetDatabase.IsValidFolder(variantSaveFolder))
|
EnsureFolderExists(variantSaveFolder);
|
||||||
{
|
|
||||||
string[] folderPath = variantSaveFolder.Split('/');
|
|
||||||
string currentPath = folderPath[0];
|
|
||||||
|
|
||||||
for (int i = 1; i < folderPath.Length; i++)
|
// Generate all sprite combinations
|
||||||
{
|
var combinations = GenerateAllCombinations();
|
||||||
string folderName = folderPath[i];
|
|
||||||
string newPath = Path.Combine(currentPath, folderName);
|
|
||||||
|
|
||||||
if (!AssetDatabase.IsValidFolder(newPath))
|
|
||||||
{
|
|
||||||
AssetDatabase.CreateFolder(currentPath, folderName);
|
|
||||||
}
|
|
||||||
|
|
||||||
currentPath = newPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
AssetDatabase.Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
string sourcePrefabPath = AssetDatabase.GetAssetPath(sourcePrefab);
|
string sourcePrefabPath = AssetDatabase.GetAssetPath(sourcePrefab);
|
||||||
string prefabName = Path.GetFileNameWithoutExtension(sourcePrefabPath);
|
string prefabName = Path.GetFileNameWithoutExtension(sourcePrefabPath);
|
||||||
int successCount = 0;
|
int successCount = 0;
|
||||||
|
|
||||||
// For each sprite, create a prefab variant
|
// Show progress bar
|
||||||
foreach (var sprite in selectedSprites)
|
EditorUtility.DisplayProgressBar("Generating Prefab Variants", "Preparing...", 0f);
|
||||||
{
|
|
||||||
if (sprite == null) continue;
|
try
|
||||||
|
{
|
||||||
|
// For each combination, create a prefab variant
|
||||||
|
for (int i = 0; i < combinations.Count; i++)
|
||||||
|
{
|
||||||
|
// Update progress
|
||||||
|
if (i % 5 == 0 || i == combinations.Count - 1)
|
||||||
|
{
|
||||||
|
float progress = (float)i / combinations.Count;
|
||||||
|
if (EditorUtility.DisplayCancelableProgressBar(
|
||||||
|
"Generating Prefab Variants",
|
||||||
|
$"Creating variant {i+1} of {combinations.Count}",
|
||||||
|
progress))
|
||||||
|
{
|
||||||
|
// User canceled
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var combination = combinations[i];
|
||||||
|
|
||||||
|
// Generate variant name
|
||||||
|
string variantName = prefabName;
|
||||||
|
string[] spriteNames = new string[combination.Count];
|
||||||
|
|
||||||
|
for (int j = 0; j < combination.Count; j++)
|
||||||
|
{
|
||||||
|
spriteNames[j] = combination[j].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format with the naming pattern
|
||||||
|
object[] formatArgs = new object[spriteNames.Length + 1];
|
||||||
|
formatArgs[0] = prefabName;
|
||||||
|
for (int j = 0; j < spriteNames.Length; j++)
|
||||||
|
{
|
||||||
|
formatArgs[j + 1] = spriteNames[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
variantName = string.Format(namingPattern, formatArgs);
|
||||||
|
}
|
||||||
|
catch (System.FormatException)
|
||||||
|
{
|
||||||
|
// Fallback if format fails
|
||||||
|
variantName = $"{prefabName}_{string.Join("_", spriteNames)}";
|
||||||
|
}
|
||||||
|
|
||||||
string variantName = string.Format(namingPattern, prefabName, sprite.name);
|
|
||||||
variantName = PrefabEditorUtility.SanitizeFileName(variantName);
|
variantName = PrefabEditorUtility.SanitizeFileName(variantName);
|
||||||
string variantPath = Path.Combine(variantSaveFolder, variantName + ".prefab").Replace("\\", "/");
|
string variantPath = Path.Combine(variantSaveFolder, variantName + ".prefab").Replace("\\", "/");
|
||||||
|
|
||||||
@@ -275,16 +665,37 @@ namespace Editor
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Check if it has a SpriteRenderer
|
// Apply sprites to renderers
|
||||||
SpriteRenderer spriteRenderer = prefabInstance.GetComponent<SpriteRenderer>();
|
for (int j = 0; j < enabledConfigs.Count; j++)
|
||||||
if (spriteRenderer == null)
|
|
||||||
{
|
{
|
||||||
// Add a SpriteRenderer if it doesn't exist
|
SpriteRenderer renderer = null;
|
||||||
spriteRenderer = prefabInstance.AddComponent<SpriteRenderer>();
|
|
||||||
|
// Find the corresponding renderer in the instance
|
||||||
|
if (string.IsNullOrEmpty(enabledConfigs[j].Path))
|
||||||
|
{
|
||||||
|
// Root object
|
||||||
|
renderer = prefabInstance.GetComponent<SpriteRenderer>();
|
||||||
|
if (renderer == null)
|
||||||
|
{
|
||||||
|
renderer = prefabInstance.AddComponent<SpriteRenderer>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Child object
|
||||||
|
Transform child = prefabInstance.transform.Find(enabledConfigs[j].Path);
|
||||||
|
if (child != null)
|
||||||
|
{
|
||||||
|
renderer = child.GetComponent<SpriteRenderer>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign the sprite
|
// Apply sprite if renderer was found
|
||||||
spriteRenderer.sprite = sprite;
|
if (renderer != null)
|
||||||
|
{
|
||||||
|
renderer.sprite = combination[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create the prefab variant
|
// Create the prefab variant
|
||||||
GameObject prefabVariant = PrefabUtility.SaveAsPrefabAsset(prefabInstance, variantPath);
|
GameObject prefabVariant = PrefabUtility.SaveAsPrefabAsset(prefabInstance, variantPath);
|
||||||
@@ -304,9 +715,62 @@ namespace Editor
|
|||||||
DestroyImmediate(prefabInstance);
|
DestroyImmediate(prefabInstance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
}
|
||||||
|
|
||||||
AssetDatabase.Refresh();
|
AssetDatabase.Refresh();
|
||||||
EditorUtility.DisplayDialog("Prefab Variants Created", $"Successfully created {successCount} prefab variants.", "OK");
|
|
||||||
|
if (successCount > 0)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog(
|
||||||
|
"Prefab Variants Created",
|
||||||
|
$"Successfully created {successCount} prefab variants in {variantSaveFolder}.",
|
||||||
|
"OK"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Open the folder in Project view
|
||||||
|
var folderObject = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(variantSaveFolder);
|
||||||
|
if (folderObject != null)
|
||||||
|
{
|
||||||
|
Selection.activeObject = folderObject;
|
||||||
|
EditorGUIUtility.PingObject(folderObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog(
|
||||||
|
"Prefab Variants",
|
||||||
|
"No prefab variants were created. Please check the console for errors.",
|
||||||
|
"OK"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnsureFolderExists(string folderPath)
|
||||||
|
{
|
||||||
|
if (!AssetDatabase.IsValidFolder(folderPath))
|
||||||
|
{
|
||||||
|
string[] folderParts = folderPath.Split('/');
|
||||||
|
string currentPath = folderParts[0];
|
||||||
|
|
||||||
|
for (int i = 1; i < folderParts.Length; i++)
|
||||||
|
{
|
||||||
|
string folderName = folderParts[i];
|
||||||
|
string newPath = Path.Combine(currentPath, folderName);
|
||||||
|
|
||||||
|
if (!AssetDatabase.IsValidFolder(newPath))
|
||||||
|
{
|
||||||
|
AssetDatabase.CreateFolder(currentPath, folderName);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentPath = newPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1001 &7921038058497292108
|
||||||
|
PrefabInstance:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Modification:
|
||||||
|
serializedVersion: 3
|
||||||
|
m_TransformParent: {fileID: 0}
|
||||||
|
m_Modifications:
|
||||||
|
- target: {fileID: 2015720985618639356, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_Name
|
||||||
|
value: QuarryMonster_monster_head1_1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.x
|
||||||
|
value: 2.46
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.y
|
||||||
|
value: -1.79
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.w
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
m_RemovedComponents: []
|
||||||
|
m_RemovedGameObjects: []
|
||||||
|
m_AddedGameObjects: []
|
||||||
|
m_AddedComponents: []
|
||||||
|
m_SourcePrefab: {fileID: 100100000, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cd5c27c38c427524988b8932e7205d81
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1001 &7839076539202245770
|
||||||
|
PrefabInstance:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Modification:
|
||||||
|
serializedVersion: 3
|
||||||
|
m_TransformParent: {fileID: 0}
|
||||||
|
m_Modifications:
|
||||||
|
- target: {fileID: 2015720985618639356, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_Name
|
||||||
|
value: QuarryMonster_monster_head2_0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.x
|
||||||
|
value: 2.46
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.y
|
||||||
|
value: -1.79
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.w
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 8447572436637192077, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_Sprite
|
||||||
|
value:
|
||||||
|
objectReference: {fileID: -7812277834941893986, guid: e9ac6c3e349f9b247a0ea03665da57ce, type: 3}
|
||||||
|
m_RemovedComponents: []
|
||||||
|
m_RemovedGameObjects: []
|
||||||
|
m_AddedGameObjects: []
|
||||||
|
m_AddedComponents: []
|
||||||
|
m_SourcePrefab: {fileID: 100100000, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7c45910be7187144b8d2af12ff772353
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1001 &4541086625678702007
|
||||||
|
PrefabInstance:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Modification:
|
||||||
|
serializedVersion: 3
|
||||||
|
m_TransformParent: {fileID: 0}
|
||||||
|
m_Modifications:
|
||||||
|
- target: {fileID: 2015720985618639356, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_Name
|
||||||
|
value: QuarryMonster_monster_head3_0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.x
|
||||||
|
value: 2.46
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.y
|
||||||
|
value: -1.79
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.w
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 8447572436637192077, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_Sprite
|
||||||
|
value:
|
||||||
|
objectReference: {fileID: 4139348639081821586, guid: 1043ceca06eb2ac48b22c20d281278b0, type: 3}
|
||||||
|
m_RemovedComponents: []
|
||||||
|
m_RemovedGameObjects: []
|
||||||
|
m_AddedGameObjects: []
|
||||||
|
m_AddedComponents: []
|
||||||
|
m_SourcePrefab: {fileID: 100100000, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c0d4b6d8a3b9a2447b883a78c568826c
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1001 &1190377006705176201
|
||||||
|
PrefabInstance:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Modification:
|
||||||
|
serializedVersion: 3
|
||||||
|
m_TransformParent: {fileID: 0}
|
||||||
|
m_Modifications:
|
||||||
|
- target: {fileID: 2015720985618639356, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_Name
|
||||||
|
value: QuarryMonster_monster_head4_0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.x
|
||||||
|
value: 2.46
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.y
|
||||||
|
value: -1.79
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.w
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6779310478082390115, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 8447572436637192077, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
|
propertyPath: m_Sprite
|
||||||
|
value:
|
||||||
|
objectReference: {fileID: -3471612407960728276, guid: c85ce41979ed896429c62330c546d3ce, type: 3}
|
||||||
|
m_RemovedComponents: []
|
||||||
|
m_RemovedGameObjects: []
|
||||||
|
m_AddedGameObjects: []
|
||||||
|
m_AddedComponents: []
|
||||||
|
m_SourcePrefab: {fileID: 100100000, guid: 7754d064d743d1b419acb859c2db6121, type: 3}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5d23561cb618e86409a2b7ccbf08e37d
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Reference in New Issue
Block a user