diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 163b281..0595817 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,9 +1,9 @@ { - "recommendations": [ - "editorconfig.editorconfig", - "jebbs.plantuml", - "visualstudiotoolsforunity.vstuc", - "ms-dotnettools.csharp", - "ms-dotnettools.csdevkit" - ] + "recommendations": [ + "editorconfig.editorconfig", + "jebbs.plantuml", + "visualstudiotoolsforunity.vstuc", + "ms-dotnettools.csharp", + "ms-dotnettools.csdevkit" + ] } diff --git a/.vscode/launch.json b/.vscode/launch.json index e65417c..a56490c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,10 +1,10 @@ { - "version": "0.2.0", - "configurations": [ - { - "name": "Attach to Unity", - "type": "vstuc", - "request": "attach" - } - ] + "version": "0.2.0", + "configurations": [ + { + "name": "Attach to Unity", + "type": "vstuc", + "request": "attach" + } + ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 5e54cda..5b65109 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,10 +1,10 @@ { - "editor.bracketPairColorization.enabled": true, - "editor.wordWrap": "on", - "[csharp]": { - "editor.tabSize": 4, - "editor.formatOnSave": true, - "editor.formatOnType": true - }, - "omnisharp.useModernNet": false + "editor.bracketPairColorization.enabled": true, + "editor.wordWrap": "on", + "[csharp]": { + "editor.tabSize": 4, + "editor.formatOnSave": true, + "editor.formatOnType": true + }, + "omnisharp.useModernNet": false } diff --git a/Assets/Resources/InGame/BlockSkin/RegularBlock01.png.meta b/Assets/Resources/InGame/BlockSkin/RegularBlock01.png.meta index b40430e..19318be 100644 --- a/Assets/Resources/InGame/BlockSkin/RegularBlock01.png.meta +++ b/Assets/Resources/InGame/BlockSkin/RegularBlock01.png.meta @@ -96,6 +96,19 @@ TextureImporter: ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 sprites: @@ -134,7 +147,8 @@ TextureImporter: secondaryTextures: [] spriteCustomMetadata: entries: [] - nameFileIdTable: {} + nameFileIdTable: + RegularBlock01_0: 229215520534054086 mipmapLimitGroupName: pSDRemoveMatte: 0 userData: diff --git a/Assets/Resources/InGame/ButtonSkin/NewLevelButton 1.png.meta b/Assets/Resources/InGame/ButtonSkin/NewLevelButton 1.png.meta index 12edd95..65c26aa 100644 --- a/Assets/Resources/InGame/ButtonSkin/NewLevelButton 1.png.meta +++ b/Assets/Resources/InGame/ButtonSkin/NewLevelButton 1.png.meta @@ -96,6 +96,19 @@ TextureImporter: ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 sprites: @@ -134,7 +147,8 @@ TextureImporter: secondaryTextures: [] spriteCustomMetadata: entries: [] - nameFileIdTable: {} + nameFileIdTable: + NewLevelButton 1_0: 4829622404114481491 mipmapLimitGroupName: pSDRemoveMatte: 0 userData: diff --git a/Assets/Resources/InGame/PortalsSkin/CubePortalLabelled.png.meta b/Assets/Resources/InGame/PortalsSkin/CubePortalLabelled.png.meta index 66aa567..0f5d43c 100644 --- a/Assets/Resources/InGame/PortalsSkin/CubePortalLabelled.png.meta +++ b/Assets/Resources/InGame/PortalsSkin/CubePortalLabelled.png.meta @@ -96,6 +96,19 @@ TextureImporter: ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 sprites: @@ -134,7 +147,8 @@ TextureImporter: secondaryTextures: [] spriteCustomMetadata: entries: [] - nameFileIdTable: {} + nameFileIdTable: + CubePortalLabelled_0: -799402021850825835 mipmapLimitGroupName: pSDRemoveMatte: 0 userData: diff --git a/Assets/Resources/InGame/PortalsSkin/ShipPortalLabelled.png.meta b/Assets/Resources/InGame/PortalsSkin/ShipPortalLabelled.png.meta index 29f3759..c711c35 100644 --- a/Assets/Resources/InGame/PortalsSkin/ShipPortalLabelled.png.meta +++ b/Assets/Resources/InGame/PortalsSkin/ShipPortalLabelled.png.meta @@ -96,6 +96,19 @@ TextureImporter: ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 sprites: @@ -134,7 +147,8 @@ TextureImporter: secondaryTextures: [] spriteCustomMetadata: entries: [] - nameFileIdTable: {} + nameFileIdTable: + ShipPortalLabelled_0: -1834338360412052916 mipmapLimitGroupName: pSDRemoveMatte: 0 userData: diff --git a/Assets/Resources/InGame/Remove.png.meta b/Assets/Resources/InGame/Remove.png.meta index 29b525f..f43ec3e 100644 --- a/Assets/Resources/InGame/Remove.png.meta +++ b/Assets/Resources/InGame/Remove.png.meta @@ -96,6 +96,19 @@ TextureImporter: ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 sprites: @@ -134,7 +147,8 @@ TextureImporter: secondaryTextures: [] spriteCustomMetadata: entries: [] - nameFileIdTable: {} + nameFileIdTable: + Remove_0: -6564193165698205349 mipmapLimitGroupName: pSDRemoveMatte: 0 userData: diff --git a/Assets/Scenes/CreateLevelScene.unity b/Assets/Scenes/CreateLevelScene.unity index a35b7f1..60ccd7d 100644 --- a/Assets/Scenes/CreateLevelScene.unity +++ b/Assets/Scenes/CreateLevelScene.unity @@ -306,6 +306,9 @@ GameObject: - component: {fileID: 678214373} - component: {fileID: 678214375} - component: {fileID: 678214374} + - component: {fileID: 678214377} + - component: {fileID: 678214376} + - component: {fileID: 678214378} m_Layer: 5 m_Name: Save m_TagString: Untagged @@ -370,6 +373,90 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 678214372} m_CullTransparentMesh: 1 +--- !u!114 &678214376 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 678214372} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 678214374} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 678214377} + m_TargetAssemblyTypeName: JSONExporter, Assembly-CSharp + m_MethodName: ExportJSON + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &678214377 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 678214372} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d3227fe18f4441647bdd19d3131efa02, type: 3} + m_Name: + m_EditorClassIdentifier: + editor: {fileID: 0} +--- !u!114 &678214378 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 678214372} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f5bf592d3d8430744a08058675701934, type: 3} + m_Name: + m_EditorClassIdentifier: + mapParent: {fileID: 0} + blockGroupContainer: {fileID: 394350961} + buttonPrefabTemplate: {fileID: 1993500743} --- !u!1 &739948034 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/JSONExporter.cs b/Assets/Scripts/JSONExporter.cs new file mode 100644 index 0000000..7845d31 --- /dev/null +++ b/Assets/Scripts/JSONExporter.cs @@ -0,0 +1,147 @@ +using UnityEngine; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using SimpleFileBrowser; +using TMPro; + +[RequireComponent(typeof(LevelEditor))] +public class JSONExporter : MonoBehaviour +{ + public TMP_Text statusText; + private LevelEditor editor; + private string levelsFolder; + + private void Awake() + { + editor = GetComponent(); + levelsFolder = Path.Combine(Application.dataPath, "Resources/Levels"); + if (!Directory.Exists(levelsFolder)) + Directory.CreateDirectory(levelsFolder); + + if (statusText == null) + { + var statusObj = GameObject.Find("StatusText"); + if (statusObj != null) + statusText = statusObj.GetComponent(); + } + } + + private void Start() + { + SetStatus("Ready to export...", Color.white); + } + + public void ExportJSON() + { + SetStatus("Exporting...", Color.yellow); + StartCoroutine(ShowSaveDialog()); + } + + private IEnumerator ShowSaveDialog() + { + yield return FileBrowser.WaitForSaveDialog( + FileBrowser.PickMode.Files, + false, + levelsFolder, + "NewLevel.json", + "Save Level JSON", + "Save" + ); + + if (!FileBrowser.Success) + { + SetStatus("Save canceled.", Color.red); + yield break; + } + + string chosenPath = FileBrowser.Result[0]; + string fileName = Path.GetFileNameWithoutExtension(chosenPath); + string destPath = Path.Combine(levelsFolder, fileName + ".json"); + + var elements = new List(); + var allCols = Object.FindObjectsByType(FindObjectsSortMode.None); + foreach (var col in allCols) + { + var go = col.gameObject; + if (!go.name.Contains("(Clone)") || go.name.ToLower().Contains("ground")) + continue; + + Vector3 scale = go.transform.localScale; + Vector3 pos = go.transform.position; + + elements.Add(new SerializableElement + { + type = go.name.Replace("(Clone)", ""), + x = Mathf.Round(pos.x * 100f) / 100f, + y = Mathf.Round(pos.y * 100f) / 100f, + scaleX = Mathf.Round(scale.x * 100f) / 100f, + scaleY = Mathf.Round(scale.y * 100f) / 100f + }); + } + + if (elements.Count == 0) + { + SetStatus("No elements to export.", Color.red); + yield break; + } + + LevelData data = new LevelData + { + name = fileName, + musicName = "", + order = 0, + elements = elements.ToArray() + }; + string json = JsonUtility.ToJson(data, prettyPrint: true); + + try + { + File.WriteAllText(destPath, json); + SetStatus("Export successful: " + fileName + ".json", Color.green); + } + catch (System.Exception e) + { + Debug.LogError("Export error: " + e); + SetStatus("Export error. See console.", Color.red); + } + +#if UNITY_EDITOR + UnityEditor.AssetDatabase.Refresh(); +#endif + var loader = Object.FindAnyObjectByType(); + if (loader != null) + loader.RefreshLevels(); + } + + private void SetStatus(string message, Color color) + { + if (statusText != null) + { + statusText.text = message; + statusText.color = color; + statusText.gameObject.SetActive(false); + statusText.gameObject.SetActive(true); + Canvas.ForceUpdateCanvases(); + } + } + + [System.Serializable] + private class SerializableElement + { + public string type; + public float x; + public float y; + public float scaleX; + public float scaleY; + } + + [System.Serializable] + private class LevelData + { + public string name; + public string musicName; + public int order; + public SerializableElement[] elements; + } +} diff --git a/Assets/Scripts/JSONExporter.cs.meta b/Assets/Scripts/JSONExporter.cs.meta new file mode 100644 index 0000000..ccb50d9 --- /dev/null +++ b/Assets/Scripts/JSONExporter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: d3227fe18f4441647bdd19d3131efa02 \ No newline at end of file diff --git a/Assets/Scripts/LevelEditor.cs b/Assets/Scripts/LevelEditor.cs index 6a9c8c7..9f3e716 100644 --- a/Assets/Scripts/LevelEditor.cs +++ b/Assets/Scripts/LevelEditor.cs @@ -41,6 +41,16 @@ public class LevelEditor : MonoBehaviour void GenerateButtons() { + if (buttonPrefabTemplate == null) + { + Debug.LogError("LevelEditor.GenerateButtons(): buttonPrefabTemplate n’est pas assigné !"); + return; + } + if (blockGroupContainer == null) + { + Debug.LogError("LevelEditor.GenerateButtons(): blockGroupContainer n’est pas assigné !"); + return; + } ClearCurrentButtons(); Transform container = blockGroupContainer; @@ -440,9 +450,4 @@ public class LevelEditor : MonoBehaviour currentBlock.transform.Rotate(0f, 0f, -90f); // ➔ Rotation de 90° dans le sens horaire Debug.Log("🔄 Bloc pivoté de 90° !"); } - - public void Save() - { - // TODO : Implémenter la sauvegarde du niveau - } }