using UnityEngine; using UnityEditor; using System.IO; using System.Reflection; public class BlockDataCreatorEditor : EditorWindow { private GameObject prefab; private string saveFolder = "Assets/Resources/BlocksData/Final"; [MenuItem("Tools/Block Data Creator")] public static void ShowWindow() => GetWindow("Block Data Creator"); private void OnGUI() { GUILayout.Label("Block Data Creator", EditorStyles.boldLabel); EditorGUILayout.Space(); prefab = (GameObject)EditorGUILayout.ObjectField("Block Prefab", prefab, typeof(GameObject), false); EditorGUILayout.Space(); GUILayout.Label("Save Paths", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); saveFolder = EditorGUILayout.TextField("BlockData Folder", saveFolder); if (GUILayout.Button("Browse", GUILayout.Width(60))) saveFolder = BrowseFolder(saveFolder); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); GUI.enabled = prefab != null; if (GUILayout.Button("Create BlockData")) CreateBlockData(); GUI.enabled = true; if (prefab == null) EditorGUILayout.HelpBox("Assign a prefab to get started.", MessageType.Info); } public void CreateBlockData() { EnsureFolderExists(saveFolder); // ── 1. Create BlockData ─────────────────────────────────────────────── BlockData blockData = ScriptableObject.CreateInstance(); blockData.blockName = prefab.name; blockData.blockPrefab = prefab; string assetPath = AssetDatabase.GenerateUniqueAssetPath( $"{saveFolder}/{prefab.name}_BlockData.asset"); AssetDatabase.CreateAsset(blockData, assetPath); AssetDatabase.SaveAssets(); // ── 2. Assign BlockData back to the Block component on the prefab ───── Block block = prefab.GetComponent(); if (block != null) { SerializedObject so = new SerializedObject(block); SerializedProperty prop = so.FindProperty("BlockData"); if (prop != null) { prop.objectReferenceValue = blockData; so.ApplyModifiedProperties(); PrefabUtility.SavePrefabAsset(prefab); Debug.Log($"[BlockDataCreator] BlockData assigned to {prefab.name}."); } else Debug.LogWarning("[BlockDataCreator] 'BlockData' field not found on Block component."); } else Debug.LogWarning($"[BlockDataCreator] No Block component on {prefab.name}."); // ── 3. Ping the new asset ───────────────────────────────────────────── EditorUtility.FocusProjectWindow(); Selection.activeObject = blockData; EditorGUIUtility.PingObject(blockData); Debug.Log($"[BlockDataCreator] Created: {assetPath}"); } public BlockData CreateBlockData(GameObject Prefab) { EnsureFolderExists(saveFolder); // ── 1. Create BlockData ─────────────────────────────────────────────── BlockData blockData = ScriptableObject.CreateInstance(); blockData.blockName = Prefab.name; blockData.blockPrefab = Prefab; string assetPath = AssetDatabase.GenerateUniqueAssetPath( $"{saveFolder}/{Prefab.name}_BlockData.asset"); AssetDatabase.CreateAsset(blockData, assetPath); AssetDatabase.SaveAssets(); // ── 2. Assign BlockData back to the Block component on the prefab ───── Block block = Prefab.GetComponent(); if (block != null) { SerializedObject so = new SerializedObject(block); SerializedProperty prop = so.FindProperty("BlockData"); if (prop != null) { prop.objectReferenceValue = blockData; so.ApplyModifiedProperties(); PrefabUtility.SavePrefabAsset(Prefab); Debug.Log($"[BlockDataCreator] BlockData assigned to {Prefab.name}."); } else Debug.LogWarning("[BlockDataCreator] 'BlockData' field not found on Block component."); } else Debug.LogWarning($"[BlockDataCreator] No Block component on {Prefab.name}."); // ── 3. Ping the new asset ───────────────────────────────────────────── EditorUtility.FocusProjectWindow(); Selection.activeObject = blockData; EditorGUIUtility.PingObject(blockData); Debug.Log($"[BlockDataCreator] Created: {assetPath}"); // ── 4. Return the Block Data ────────────────────────────────────────── return blockData; } private string BrowseFolder(string current) { string abs = EditorUtility.OpenFolderPanel("Select Folder", current, ""); if (string.IsNullOrEmpty(abs)) return current; if (abs.StartsWith(Application.dataPath)) return "Assets" + abs.Substring(Application.dataPath.Length); Debug.LogWarning("[BlockDataCreator] Folder must be inside Assets."); return current; } private void EnsureFolderExists(string path) { if (AssetDatabase.IsValidFolder(path)) return; string parent = Path.GetDirectoryName(path).Replace("\\", "/"); EnsureFolderExists(parent); AssetDatabase.CreateFolder(parent, Path.GetFileName(path)); } }