mirror of
				https://github.com/boudji-ludwig-pett/cnam-geometry-dash.git
				synced 2025-06-27 11:58:51 +02:00 
			
		
		
		
	Map editor design (#59)
This commit is contained in:
		| @@ -109,6 +109,7 @@ TextureImporter: | |||||||
|     ignorePlatformSupport: 0 |     ignorePlatformSupport: 0 | ||||||
|     androidETC2FallbackOverride: 0 |     androidETC2FallbackOverride: 0 | ||||||
|     forceMaximumCompressionQuality_BC6H_BC7: 0 |     forceMaximumCompressionQuality_BC6H_BC7: 0 | ||||||
|  | >>>>>>> develop | ||||||
|   spriteSheet: |   spriteSheet: | ||||||
|     serializedVersion: 2 |     serializedVersion: 2 | ||||||
|     sprites: |     sprites: | ||||||
| @@ -147,8 +148,7 @@ TextureImporter: | |||||||
|     secondaryTextures: [] |     secondaryTextures: [] | ||||||
|     spriteCustomMetadata: |     spriteCustomMetadata: | ||||||
|       entries: [] |       entries: [] | ||||||
|     nameFileIdTable: |     nameFileIdTable: {} | ||||||
|       RegularBlock01_0: 229215520534054086 |  | ||||||
|   mipmapLimitGroupName:  |   mipmapLimitGroupName:  | ||||||
|   pSDRemoveMatte: 0 |   pSDRemoveMatte: 0 | ||||||
|   userData:  |   userData:  | ||||||
|   | |||||||
| @@ -147,8 +147,7 @@ TextureImporter: | |||||||
|     secondaryTextures: [] |     secondaryTextures: [] | ||||||
|     spriteCustomMetadata: |     spriteCustomMetadata: | ||||||
|       entries: [] |       entries: [] | ||||||
|     nameFileIdTable: |     nameFileIdTable: {} | ||||||
|       CubePortalLabelled_0: -799402021850825835 |  | ||||||
|   mipmapLimitGroupName:  |   mipmapLimitGroupName:  | ||||||
|   pSDRemoveMatte: 0 |   pSDRemoveMatte: 0 | ||||||
|   userData:  |   userData:  | ||||||
|   | |||||||
| @@ -147,8 +147,7 @@ TextureImporter: | |||||||
|     secondaryTextures: [] |     secondaryTextures: [] | ||||||
|     spriteCustomMetadata: |     spriteCustomMetadata: | ||||||
|       entries: [] |       entries: [] | ||||||
|     nameFileIdTable: |     nameFileIdTable: {} | ||||||
|       ShipPortalLabelled_0: -1834338360412052916 |  | ||||||
|   mipmapLimitGroupName:  |   mipmapLimitGroupName:  | ||||||
|   pSDRemoveMatte: 0 |   pSDRemoveMatte: 0 | ||||||
|   userData:  |   userData:  | ||||||
|   | |||||||
| @@ -222,63 +222,6 @@ MonoBehaviour: | |||||||
|           m_StringArgument:  |           m_StringArgument:  | ||||||
|           m_BoolArgument: 0 |           m_BoolArgument: 0 | ||||||
|         m_CallState: 2 |         m_CallState: 2 | ||||||
| --- !u!1001 &109370708 |  | ||||||
| PrefabInstance: |  | ||||||
|   m_ObjectHideFlags: 0 |  | ||||||
|   serializedVersion: 2 |  | ||||||
|   m_Modification: |  | ||||||
|     serializedVersion: 3 |  | ||||||
|     m_TransformParent: {fileID: 0} |  | ||||||
|     m_Modifications: |  | ||||||
|     - target: {fileID: 1771296619209216840, guid: e9dda45aef9258745a40efb48437d584, type: 3} |  | ||||||
|       propertyPath: m_Name |  | ||||||
|       value: BonusSlowSpeed |  | ||||||
|       objectReference: {fileID: 0} |  | ||||||
|     - target: {fileID: 6543394447596783970, guid: e9dda45aef9258745a40efb48437d584, type: 3} |  | ||||||
|       propertyPath: m_LocalPosition.x |  | ||||||
|       value: -5.4423084 |  | ||||||
|       objectReference: {fileID: 0} |  | ||||||
|     - target: {fileID: 6543394447596783970, guid: e9dda45aef9258745a40efb48437d584, type: 3} |  | ||||||
|       propertyPath: m_LocalPosition.y |  | ||||||
|       value: -2.783749 |  | ||||||
|       objectReference: {fileID: 0} |  | ||||||
|     - target: {fileID: 6543394447596783970, guid: e9dda45aef9258745a40efb48437d584, type: 3} |  | ||||||
|       propertyPath: m_LocalPosition.z |  | ||||||
|       value: 0 |  | ||||||
|       objectReference: {fileID: 0} |  | ||||||
|     - target: {fileID: 6543394447596783970, guid: e9dda45aef9258745a40efb48437d584, type: 3} |  | ||||||
|       propertyPath: m_LocalRotation.w |  | ||||||
|       value: 1 |  | ||||||
|       objectReference: {fileID: 0} |  | ||||||
|     - target: {fileID: 6543394447596783970, guid: e9dda45aef9258745a40efb48437d584, type: 3} |  | ||||||
|       propertyPath: m_LocalRotation.x |  | ||||||
|       value: 0 |  | ||||||
|       objectReference: {fileID: 0} |  | ||||||
|     - target: {fileID: 6543394447596783970, guid: e9dda45aef9258745a40efb48437d584, type: 3} |  | ||||||
|       propertyPath: m_LocalRotation.y |  | ||||||
|       value: 0 |  | ||||||
|       objectReference: {fileID: 0} |  | ||||||
|     - target: {fileID: 6543394447596783970, guid: e9dda45aef9258745a40efb48437d584, type: 3} |  | ||||||
|       propertyPath: m_LocalRotation.z |  | ||||||
|       value: 0 |  | ||||||
|       objectReference: {fileID: 0} |  | ||||||
|     - target: {fileID: 6543394447596783970, guid: e9dda45aef9258745a40efb48437d584, type: 3} |  | ||||||
|       propertyPath: m_LocalEulerAnglesHint.x |  | ||||||
|       value: 0 |  | ||||||
|       objectReference: {fileID: 0} |  | ||||||
|     - target: {fileID: 6543394447596783970, guid: e9dda45aef9258745a40efb48437d584, type: 3} |  | ||||||
|       propertyPath: m_LocalEulerAnglesHint.y |  | ||||||
|       value: 0 |  | ||||||
|       objectReference: {fileID: 0} |  | ||||||
|     - target: {fileID: 6543394447596783970, guid: e9dda45aef9258745a40efb48437d584, type: 3} |  | ||||||
|       propertyPath: m_LocalEulerAnglesHint.z |  | ||||||
|       value: 0 |  | ||||||
|       objectReference: {fileID: 0} |  | ||||||
|     m_RemovedComponents: [] |  | ||||||
|     m_RemovedGameObjects: [] |  | ||||||
|     m_AddedGameObjects: [] |  | ||||||
|     m_AddedComponents: [] |  | ||||||
|   m_SourcePrefab: {fileID: 100100000, guid: e9dda45aef9258745a40efb48437d584, type: 3} |  | ||||||
| --- !u!1 &245275147 | --- !u!1 &245275147 | ||||||
| GameObject: | GameObject: | ||||||
|   m_ObjectHideFlags: 0 |   m_ObjectHideFlags: 0 | ||||||
| @@ -434,6 +377,63 @@ CanvasRenderer: | |||||||
|   m_PrefabAsset: {fileID: 0} |   m_PrefabAsset: {fileID: 0} | ||||||
|   m_GameObject: {fileID: 487176671} |   m_GameObject: {fileID: 487176671} | ||||||
|   m_CullTransparentMesh: 1 |   m_CullTransparentMesh: 1 | ||||||
|  | --- !u!1001 &496264820 | ||||||
|  | PrefabInstance: | ||||||
|  |   m_ObjectHideFlags: 0 | ||||||
|  |   serializedVersion: 2 | ||||||
|  |   m_Modification: | ||||||
|  |     serializedVersion: 3 | ||||||
|  |     m_TransformParent: {fileID: 0} | ||||||
|  |     m_Modifications: | ||||||
|  |     - target: {fileID: 3025146551836412649, guid: 5d01d2d55c6c25541b0db90186e76c2b, type: 3} | ||||||
|  |       propertyPath: m_Name | ||||||
|  |       value: BonusBoostSpeed | ||||||
|  |       objectReference: {fileID: 0} | ||||||
|  |     - target: {fileID: 7134261581051338486, guid: 5d01d2d55c6c25541b0db90186e76c2b, type: 3} | ||||||
|  |       propertyPath: m_LocalPosition.x | ||||||
|  |       value: -2 | ||||||
|  |       objectReference: {fileID: 0} | ||||||
|  |     - target: {fileID: 7134261581051338486, guid: 5d01d2d55c6c25541b0db90186e76c2b, type: 3} | ||||||
|  |       propertyPath: m_LocalPosition.y | ||||||
|  |       value: -2.88 | ||||||
|  |       objectReference: {fileID: 0} | ||||||
|  |     - target: {fileID: 7134261581051338486, guid: 5d01d2d55c6c25541b0db90186e76c2b, type: 3} | ||||||
|  |       propertyPath: m_LocalPosition.z | ||||||
|  |       value: 0 | ||||||
|  |       objectReference: {fileID: 0} | ||||||
|  |     - target: {fileID: 7134261581051338486, guid: 5d01d2d55c6c25541b0db90186e76c2b, type: 3} | ||||||
|  |       propertyPath: m_LocalRotation.w | ||||||
|  |       value: 0.99681437 | ||||||
|  |       objectReference: {fileID: 0} | ||||||
|  |     - target: {fileID: 7134261581051338486, guid: 5d01d2d55c6c25541b0db90186e76c2b, type: 3} | ||||||
|  |       propertyPath: m_LocalRotation.x | ||||||
|  |       value: -0 | ||||||
|  |       objectReference: {fileID: 0} | ||||||
|  |     - target: {fileID: 7134261581051338486, guid: 5d01d2d55c6c25541b0db90186e76c2b, type: 3} | ||||||
|  |       propertyPath: m_LocalRotation.y | ||||||
|  |       value: -0 | ||||||
|  |       objectReference: {fileID: 0} | ||||||
|  |     - target: {fileID: 7134261581051338486, guid: 5d01d2d55c6c25541b0db90186e76c2b, type: 3} | ||||||
|  |       propertyPath: m_LocalRotation.z | ||||||
|  |       value: -0.079757296 | ||||||
|  |       objectReference: {fileID: 0} | ||||||
|  |     - target: {fileID: 7134261581051338486, guid: 5d01d2d55c6c25541b0db90186e76c2b, type: 3} | ||||||
|  |       propertyPath: m_LocalEulerAnglesHint.x | ||||||
|  |       value: 0 | ||||||
|  |       objectReference: {fileID: 0} | ||||||
|  |     - target: {fileID: 7134261581051338486, guid: 5d01d2d55c6c25541b0db90186e76c2b, type: 3} | ||||||
|  |       propertyPath: m_LocalEulerAnglesHint.y | ||||||
|  |       value: 0 | ||||||
|  |       objectReference: {fileID: 0} | ||||||
|  |     - target: {fileID: 7134261581051338486, guid: 5d01d2d55c6c25541b0db90186e76c2b, type: 3} | ||||||
|  |       propertyPath: m_LocalEulerAnglesHint.z | ||||||
|  |       value: -9.149 | ||||||
|  |       objectReference: {fileID: 0} | ||||||
|  |     m_RemovedComponents: [] | ||||||
|  |     m_RemovedGameObjects: [] | ||||||
|  |     m_AddedGameObjects: [] | ||||||
|  |     m_AddedComponents: [] | ||||||
|  |   m_SourcePrefab: {fileID: 100100000, guid: 5d01d2d55c6c25541b0db90186e76c2b, type: 3} | ||||||
| --- !u!1 &519420028 | --- !u!1 &519420028 | ||||||
| GameObject: | GameObject: | ||||||
|   m_ObjectHideFlags: 0 |   m_ObjectHideFlags: 0 | ||||||
| @@ -7475,4 +7475,4 @@ SceneRoots: | |||||||
|   - {fileID: 1371294550} |   - {fileID: 1371294550} | ||||||
|   - {fileID: 521952202} |   - {fileID: 521952202} | ||||||
|   - {fileID: 555497623} |   - {fileID: 555497623} | ||||||
|   - {fileID: 109370708} |   - {fileID: 496264820} | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| using UnityEngine; | using UnityEngine; | ||||||
| using UnityEngine.UI; | using UnityEngine.UI; | ||||||
|  | using UnityEngine.EventSystems; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
|  |  | ||||||
| public class LevelEditor : MonoBehaviour | public class LevelEditor : MonoBehaviour | ||||||
| @@ -34,6 +35,21 @@ public class LevelEditor : MonoBehaviour | |||||||
|         GenerateButtons(); |         GenerateButtons(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     void Update() | ||||||
|  |     { | ||||||
|  |         if (IsPointerOverUI()) return; | ||||||
|  |  | ||||||
|  |         if (isPlacingBlock && currentBlock != null) | ||||||
|  |             HandleBlockPlacement(); | ||||||
|  |         else | ||||||
|  |             HandleBlockSelection(); | ||||||
|  |  | ||||||
|  |         HandleBlockResizing(); | ||||||
|  |         HandleBlockDeletion(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     #region UI | ||||||
|  |  | ||||||
|     void LoadPrefabs() |     void LoadPrefabs() | ||||||
|     { |     { | ||||||
|         blockPrefabs.AddRange(Resources.LoadAll<GameObject>("Prefabs")); |         blockPrefabs.AddRange(Resources.LoadAll<GameObject>("Prefabs")); | ||||||
| @@ -41,21 +57,9 @@ public class LevelEditor : MonoBehaviour | |||||||
|  |  | ||||||
|     void GenerateButtons() |     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(); |         ClearCurrentButtons(); | ||||||
|  |  | ||||||
|         Transform container = blockGroupContainer; |         if (blockGroupContainer == null || buttonPrefabTemplate == null) | ||||||
|  |  | ||||||
|         if (container == null || buttonPrefabTemplate == null) |  | ||||||
|         { |         { | ||||||
|             Debug.LogError("UI Container ou prefab de bouton manquant."); |             Debug.LogError("UI Container ou prefab de bouton manquant."); | ||||||
|             return; |             return; | ||||||
| @@ -66,34 +70,10 @@ public class LevelEditor : MonoBehaviour | |||||||
|  |  | ||||||
|         for (int i = start; i < end; i++) |         for (int i = start; i < end; i++) | ||||||
|         { |         { | ||||||
|             GameObject button = Instantiate(buttonPrefabTemplate, container); |             GameObject button = Instantiate(buttonPrefabTemplate, blockGroupContainer); | ||||||
|             button.SetActive(true); |             button.SetActive(true); | ||||||
|  |  | ||||||
|             Transform canvas = button.transform.Find("Canvas"); |             SetupButtonVisual(button.transform, blockPrefabs[i], i - start); | ||||||
|             Transform bg = canvas?.Find("BlankSquare"); |  | ||||||
|             Transform icon = canvas?.Find("PrefabIcon"); |  | ||||||
|  |  | ||||||
|             if (bg == null || icon == null) |  | ||||||
|             { |  | ||||||
|                 Destroy(button); |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             float xOffset = -375f + (i - start) * 125f; |  | ||||||
|             bg.GetComponent<RectTransform>().anchoredPosition = new Vector2(xOffset, bg.GetComponent<RectTransform>().anchoredPosition.y); |  | ||||||
|             icon.GetComponent<RectTransform>().anchoredPosition = new Vector2(xOffset, icon.GetComponent<RectTransform>().anchoredPosition.y); |  | ||||||
|  |  | ||||||
|             Image bgImage = bg.GetComponent<Image>(); |  | ||||||
|             Image iconImage = icon.GetComponent<Image>(); |  | ||||||
|  |  | ||||||
|             bgImage.sprite = Resources.Load<Sprite>("InGame/ButtonSkin/BlankSquare"); |  | ||||||
|             iconImage.sprite = blockPrefabs[i].GetComponent<SpriteRenderer>()?.sprite; |  | ||||||
|  |  | ||||||
|             string prefabName = blockPrefabs[i].name.ToLower(); |  | ||||||
|             if (prefabName.Contains("smallspike") || prefabName.Contains("smallobstacle")) |  | ||||||
|                 icon.GetComponent<RectTransform>().sizeDelta = new Vector2(50, 25); |  | ||||||
|             else |  | ||||||
|                 icon.GetComponent<RectTransform>().sizeDelta = new Vector2(50, 50); |  | ||||||
|  |  | ||||||
|             GameObject prefab = blockPrefabs[i]; |             GameObject prefab = blockPrefabs[i]; | ||||||
|             button.GetComponent<Button>().onClick.AddListener(() => SelectPrefab(prefab)); |             button.GetComponent<Button>().onClick.AddListener(() => SelectPrefab(prefab)); | ||||||
| @@ -101,18 +81,40 @@ public class LevelEditor : MonoBehaviour | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     void SetupButtonVisual(Transform buttonTransform, GameObject prefab, int index) | ||||||
|  |     { | ||||||
|  |         Transform canvas = buttonTransform.Find("Canvas"); | ||||||
|  |         Transform bg = canvas?.Find("BlankSquare"); | ||||||
|  |         Transform icon = canvas?.Find("PrefabIcon"); | ||||||
|  |  | ||||||
|  |         if (bg == null || icon == null) | ||||||
|  |         { | ||||||
|  |             Destroy(buttonTransform.gameObject); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         float xOffset = -375f + index * 125f; | ||||||
|  |         bg.GetComponent<RectTransform>().anchoredPosition = new Vector2(xOffset, bg.GetComponent<RectTransform>().anchoredPosition.y); | ||||||
|  |         icon.GetComponent<RectTransform>().anchoredPosition = new Vector2(xOffset, icon.GetComponent<RectTransform>().anchoredPosition.y); | ||||||
|  |  | ||||||
|  |         bg.GetComponent<Image>().sprite = Resources.Load<Sprite>("InGame/ButtonSkin/BlankSquare"); | ||||||
|  |         icon.GetComponent<Image>().sprite = prefab.GetComponent<SpriteRenderer>()?.sprite; | ||||||
|  |  | ||||||
|  |         icon.GetComponent<RectTransform>().sizeDelta = prefab.name.ToLower().Contains("small") | ||||||
|  |             ? new Vector2(50, 25) | ||||||
|  |             : new Vector2(50, 50); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     void ClearCurrentButtons() |     void ClearCurrentButtons() | ||||||
|     { |     { | ||||||
|         foreach (var button in currentButtons) |         foreach (var button in currentButtons) | ||||||
|             Destroy(button); |             Destroy(button); | ||||||
|  |  | ||||||
|         currentButtons.Clear(); |         currentButtons.Clear(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void NextPage() |     public void NextPage() | ||||||
|     { |     { | ||||||
|         int maxPage = 3; |         int maxPage = Mathf.CeilToInt(blockPrefabs.Count / (float)buttonsPerPage); | ||||||
|         Debug.Log(currentPage); |  | ||||||
|         if (currentPage < maxPage - 1) |         if (currentPage < maxPage - 1) | ||||||
|         { |         { | ||||||
|             currentPage++; |             currentPage++; | ||||||
| @@ -122,7 +124,6 @@ public class LevelEditor : MonoBehaviour | |||||||
|  |  | ||||||
|     public void PreviousPage() |     public void PreviousPage() | ||||||
|     { |     { | ||||||
|         Debug.Log(currentPage); |  | ||||||
|         if (currentPage > 0) |         if (currentPage > 0) | ||||||
|         { |         { | ||||||
|             currentPage--; |             currentPage--; | ||||||
| @@ -130,308 +131,196 @@ public class LevelEditor : MonoBehaviour | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     #endregion | ||||||
|  |  | ||||||
|  |     #region Placement | ||||||
|  |  | ||||||
|     void SelectPrefab(GameObject prefab) |     void SelectPrefab(GameObject prefab) | ||||||
|     { |     { | ||||||
|         if (isPlacingBlock) return; |         if (isPlacingBlock) return; | ||||||
|  |  | ||||||
|         string name = prefab.name.ToLower(); |         currentScale = DetermineScaleFromName(prefab.name); | ||||||
|  |  | ||||||
|         if (name.Contains("portal")) |  | ||||||
|             currentScale = new Vector3(0.5f, 0.5f, 1); |  | ||||||
|         else if (name.Contains("small")) |  | ||||||
|             currentScale = new Vector3(0.15f, 0.07f, 1); |  | ||||||
|         else if (name.Contains("spike")) |  | ||||||
|             currentScale = new Vector3(0.15f, 0.15f, 1); |  | ||||||
|         else if (name.Contains("block")) |  | ||||||
|             currentScale = new Vector3(0.2f, 0.2f, 1); |  | ||||||
|         else if (name.Contains("bonus")) |  | ||||||
|             currentScale = new Vector3(0.3f, 0.3f, 1); |  | ||||||
|         else |  | ||||||
|             currentScale = new Vector3(1f, 1f, 1); |  | ||||||
|  |  | ||||||
|         InstantiateAndPrepare(prefab, currentScale); |         InstantiateAndPrepare(prefab, currentScale); | ||||||
|     } |     } | ||||||
|     void Update() |  | ||||||
|  |     Vector3 DetermineScaleFromName(string name) | ||||||
|     { |     { | ||||||
|         // Déplacement de l'objet en cours de placement |         name = name.ToLower(); | ||||||
|         if (isPlacingBlock && currentBlock != null) |  | ||||||
|  |         if (name.Contains("portal")) return new Vector3(0.5f, 0.5f, 1); | ||||||
|  |         if (name.Contains("small")) return new Vector3(0.15f, 0.07f, 1); | ||||||
|  |         if (name.Contains("spike")) return new Vector3(0.15f, 0.15f, 1); | ||||||
|  |         if (name.Contains("block")) return new Vector3(0.2f, 0.2f, 1); | ||||||
|  |         if (name.Contains("bonus")) return new Vector3(0.3f, 0.3f, 1); | ||||||
|  |  | ||||||
|  |         return new Vector3(1f, 1f, 1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void HandleBlockPlacement() | ||||||
|  |     { | ||||||
|  |         Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); | ||||||
|  |         currentBlock.transform.position = new Vector3(Mathf.Round(mousePos.x), Mathf.Round(mousePos.y), -1); | ||||||
|  |  | ||||||
|  |         if (Input.GetKeyDown(KeyCode.R)) | ||||||
|  |             HandleBlockRotation(); | ||||||
|  |  | ||||||
|  |         if (!currentBlock.name.ToLower().Contains("portal")) | ||||||
|         { |         { | ||||||
|             Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); |             float scroll = Input.GetAxis("Mouse ScrollWheel"); | ||||||
|             currentBlock.transform.position = new Vector3(Mathf.Round(mousePos.x), Mathf.Round(mousePos.y), -1); |             if (scroll != 0) | ||||||
|  |  | ||||||
|             if (currentBlock != null && Input.GetKeyDown(KeyCode.R)) |  | ||||||
|             { |             { | ||||||
|                 HandleBlockRotation(); // ✅ Nouvelle rotation |                 float newScale = Mathf.Max(0.1f, currentScale.x + scroll * scaleStep); | ||||||
|             } |                 currentScale = new Vector3(newScale, newScale, 1); | ||||||
|  |                 currentBlock.transform.localScale = currentScale; | ||||||
|             if (!currentBlock.name.ToLower().Contains("portal")) |  | ||||||
|             { |  | ||||||
|                 float scroll = Input.GetAxis("Mouse ScrollWheel"); |  | ||||||
|                 if (scroll != 0) |  | ||||||
|                 { |  | ||||||
|                     float newScale = Mathf.Max(0.1f, currentScale.x + scroll * scaleStep); |  | ||||||
|                     currentScale = new Vector3(newScale, newScale, 1); |  | ||||||
|                     currentBlock.transform.localScale = currentScale; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (Input.GetMouseButtonDown(0)) |  | ||||||
|             { |  | ||||||
|                 Collider2D[] overlaps = Physics2D.OverlapBoxAll( |  | ||||||
|                     currentBlock.transform.position, |  | ||||||
|                     currentBlock.GetComponent<Collider2D>().bounds.size, |  | ||||||
|                     0f |  | ||||||
|                 ); |  | ||||||
|  |  | ||||||
|                 if (overlaps.Length > 1) |  | ||||||
|                 { |  | ||||||
|                     Debug.Log("Placement annulé : un objet est déjà présent à cet endroit."); |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 PlaceBlock(); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         else if (Input.GetMouseButtonDown(0)) // Clic gauche pour reprendre un objet déjà placé |  | ||||||
|  |         if (Input.GetMouseButtonDown(0)) | ||||||
|  |         { | ||||||
|  |             if (!IsPlacementValid()) | ||||||
|  |             { | ||||||
|  |                 Debug.Log("Placement annulé : collision."); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             PlaceBlock(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     bool IsPlacementValid() | ||||||
|  |     { | ||||||
|  |         Collider2D[] overlaps = Physics2D.OverlapBoxAll( | ||||||
|  |             currentBlock.transform.position, | ||||||
|  |             currentBlock.GetComponent<Collider2D>().bounds.size, | ||||||
|  |             0f | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         foreach (var col in overlaps) | ||||||
|  |         { | ||||||
|  |             if (col.transform.root == currentBlock.transform || col.CompareTag("Ground")) | ||||||
|  |                 continue; | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void HandleBlockSelection() | ||||||
|  |     { | ||||||
|  |         if (Input.GetMouseButtonDown(0)) | ||||||
|         { |         { | ||||||
|             Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); |             Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); | ||||||
|             Collider2D hit = Physics2D.OverlapPoint(mousePos); |             Collider2D hit = Physics2D.OverlapPoint(mousePos); | ||||||
|  |  | ||||||
|             if (hit != null && hit.transform != null) |             if (hit != null && !hit.CompareTag("Ground")) | ||||||
|             { |             { | ||||||
|                 if (hit.CompareTag("Ground")) |  | ||||||
|                 { |  | ||||||
|                     Debug.Log("Impossible de déplacer le sol (tag Ground)."); |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|                 currentBlock = hit.gameObject; |                 currentBlock = hit.gameObject; | ||||||
|                 isPlacingBlock = true; |                 isPlacingBlock = true; | ||||||
|                 currentScale = currentBlock.transform.localScale; |                 currentScale = currentBlock.transform.localScale; | ||||||
|                 Debug.Log($"Déplacement de l'objet : {currentBlock.name}"); |                 Debug.Log($"Bloc sélectionné : {currentBlock.name}"); | ||||||
|                 return; |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // Redimensionnement d'un objet déjà placé |  | ||||||
|         if (Input.GetMouseButtonDown(0) && Input.GetKey(KeyCode.LeftShift) && !isPlacingBlock) |  | ||||||
|         { |  | ||||||
|             Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); |  | ||||||
|             Collider2D hit = Physics2D.OverlapPoint(mousePos); |  | ||||||
|  |  | ||||||
|             if (hit != null && hit.transform != null && !hit.CompareTag("Ground")) |  | ||||||
|             { |  | ||||||
|                 resizingTarget = hit.gameObject; |  | ||||||
|                 originalMousePos = mousePos; |  | ||||||
|                 originalScale = resizingTarget.transform.localScale; |  | ||||||
|  |  | ||||||
|                 Vector2 localClick = mousePos - (Vector2)resizingTarget.transform.position; |  | ||||||
|                 float ratio = resizingTarget.GetComponent<Collider2D>().bounds.size.x / |  | ||||||
|                 resizingTarget.GetComponent<Collider2D>().bounds.size.y; |  | ||||||
|  |  | ||||||
|                 currentResizeAxis = Mathf.Abs(localClick.x) > Mathf.Abs(localClick.y * ratio) |  | ||||||
|                     ? ResizeAxis.Horizontal |  | ||||||
|                     : ResizeAxis.Vertical; |  | ||||||
|  |  | ||||||
|                 isResizing = true; |  | ||||||
|                 Debug.Log($"Début de redimensionnement : {resizingTarget.name}, axe = {currentResizeAxis}"); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (isResizing && resizingTarget != null) |  | ||||||
|         { |  | ||||||
|             Vector3 currentMousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); |  | ||||||
|             Vector3 delta = currentMousePos - originalMousePos; |  | ||||||
|  |  | ||||||
|             Vector3 newScale = originalScale; |  | ||||||
|  |  | ||||||
|             if (currentResizeAxis == ResizeAxis.Horizontal) |  | ||||||
|                 newScale.x = Mathf.Max(0.1f, originalScale.x + delta.x); |  | ||||||
|             else if (currentResizeAxis == ResizeAxis.Vertical) |  | ||||||
|                 newScale.y = Mathf.Max(0.1f, originalScale.y + delta.y); |  | ||||||
|  |  | ||||||
|             // Temporarily apply the new scale for collision testing |  | ||||||
|             Vector3 originalPos = resizingTarget.transform.position; |  | ||||||
|             resizingTarget.transform.localScale = newScale; |  | ||||||
|  |  | ||||||
|             Bounds bounds = resizingTarget.GetComponent<Collider2D>().bounds; |  | ||||||
|             Collider2D[] overlaps = Physics2D.OverlapBoxAll(bounds.center, bounds.size, 0f); |  | ||||||
|  |  | ||||||
|             bool hasCollision = false; |  | ||||||
|             foreach (var col in overlaps) |  | ||||||
|             { |  | ||||||
|                 if (col.gameObject != resizingTarget) |  | ||||||
|                 { |  | ||||||
|                     hasCollision = true; |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (hasCollision) |  | ||||||
|             { |  | ||||||
|                 resizingTarget.transform.localScale = originalScale; // revert |  | ||||||
|                 Debug.Log("Étirement annulé : collision détectée."); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (Input.GetMouseButtonUp(0)) |  | ||||||
|             { |  | ||||||
|                 isResizing = false; |  | ||||||
|                 resizingTarget = null; |  | ||||||
|                 currentResizeAxis = ResizeAxis.None; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|         // Clic droit pour supprimer un objet déjà placé (sauf le sol) |  | ||||||
|         if (Input.GetMouseButtonDown(1)) |  | ||||||
|         { |  | ||||||
|             Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); |  | ||||||
|             Collider2D hit = Physics2D.OverlapPoint(mousePos); |  | ||||||
|  |  | ||||||
|             if (hit != null && hit.transform != null) |  | ||||||
|             { |  | ||||||
|                 if (hit.CompareTag("Ground")) |  | ||||||
|                 { |  | ||||||
|                     Debug.Log("Impossible de supprimer le sol (tag Ground)."); |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 Destroy(hit.gameObject); |  | ||||||
|                 Debug.Log($"Objet supprimé : {hit.name}"); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void PlaceBlock() |     void PlaceBlock() | ||||||
|     { |     { | ||||||
|         bool skipVerticalSnap = false; |         string name = currentBlock.name.ToLower(); | ||||||
|  |  | ||||||
|         if (currentBlock.name.ToLower().Contains("smallobstacle") || currentBlock.name.ToLower().Contains("portal")) |         bool grounded = name.Contains("spike") || name.Contains("bonus") || name.Contains("smallobstacle"); | ||||||
|  |  | ||||||
|  |         if (grounded) | ||||||
|         { |         { | ||||||
|             skipVerticalSnap = true; // On saute l'alignement vertical pour ces cas-là |             StickBlockToGround(); | ||||||
|  |         } | ||||||
|  |         else if (!ShouldSkipVerticalSnap(name)) | ||||||
|  |         { | ||||||
|  |             SnapBlockVertically(); | ||||||
|  |             TrySnapToNearbyBlock(); // ✅ seulement ici | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             TrySnapToNearbyBlock(); // ex: autres blocs | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!skipVerticalSnap) |  | ||||||
|         { |  | ||||||
|             Vector2 origin = currentBlock.transform.position; |  | ||||||
|             RaycastHit2D[] hitsBelow = Physics2D.RaycastAll(origin, Vector2.down, 100f); |  | ||||||
|  |  | ||||||
|             float highestY = -Mathf.Infinity; |  | ||||||
|             GameObject bestTargetBelow = null; |  | ||||||
|  |  | ||||||
|             foreach (var hit in hitsBelow) |  | ||||||
|             { |  | ||||||
|                 if (hit.collider != null && hit.collider.gameObject != currentBlock) |  | ||||||
|                 { |  | ||||||
|                     float topOfObject = hit.collider.bounds.max.y; |  | ||||||
|                     if (topOfObject > highestY) |  | ||||||
|                     { |  | ||||||
|                         highestY = topOfObject; |  | ||||||
|                         bestTargetBelow = hit.collider.gameObject; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (bestTargetBelow != null) |  | ||||||
|             { |  | ||||||
|                 float height = currentBlock.GetComponent<Collider2D>().bounds.size.y; |  | ||||||
|                 currentBlock.transform.position = new Vector3(currentBlock.transform.position.x, highestY + height / 2f, -1); |  | ||||||
|             } |  | ||||||
|             else |  | ||||||
|             { |  | ||||||
|                 float height = currentBlock.GetComponent<Collider2D>().bounds.size.y; |  | ||||||
|                 currentBlock.transform.position = new Vector3(currentBlock.transform.position.x, height / 2f, -1); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         // ➔ Toujours essayer de snap sur la droite et en bas même pour Portal et SmallObstacle |  | ||||||
|         TrySnapToNearbyBlock(); |         TrySnapToNearbyBlock(); | ||||||
|  |  | ||||||
|         isPlacingBlock = false; |         isPlacingBlock = false; | ||||||
|         currentBlock = null; |         currentBlock = null; | ||||||
|     } |     } | ||||||
|  |     void StickBlockToGround() | ||||||
|  |  | ||||||
|     private void TrySnapToNearbyBlock() |  | ||||||
|     { |     { | ||||||
|         if (currentBlock == null) |         Collider2D col = currentBlock.GetComponent<Collider2D>(); | ||||||
|             return; |         Bounds bounds = col.bounds; | ||||||
|  |  | ||||||
|         Collider2D blockCollider = currentBlock.GetComponent<Collider2D>(); |         Vector2 origin = new Vector2(bounds.center.x, bounds.min.y); | ||||||
|         Bounds bounds = blockCollider.bounds; |         float rayLength = 100f; // on descend loin pour être sûr de toucher le sol | ||||||
|  |  | ||||||
|         float snapDistance = 1f; // Distance de snap (en Unity units) |         RaycastHit2D hit = Physics2D.Raycast(origin, Vector2.down, rayLength); | ||||||
|  |  | ||||||
|         // Zone de scan à droite |         if (hit.collider != null && hit.collider.gameObject != currentBlock) | ||||||
|         Vector2 rightAreaStart = new Vector2(bounds.max.x, bounds.min.y); |  | ||||||
|         Vector2 rightAreaEnd = new Vector2(bounds.max.x + snapDistance, bounds.max.y); |  | ||||||
|  |  | ||||||
|         // Zone de scan à gauche |  | ||||||
|         Vector2 leftAreaStart = new Vector2(bounds.min.x - snapDistance, bounds.min.y); |  | ||||||
|         Vector2 leftAreaEnd = new Vector2(bounds.min.x, bounds.max.y); |  | ||||||
|  |  | ||||||
|         // Zone de scan en dessous |  | ||||||
|         Vector2 bottomAreaStart = new Vector2(bounds.min.x, bounds.min.y - snapDistance); |  | ||||||
|         Vector2 bottomAreaEnd = new Vector2(bounds.max.x, bounds.min.y); |  | ||||||
|  |  | ||||||
|         // Zone de scan au dessus |  | ||||||
|         Vector2 topAreaStart = new Vector2(bounds.min.x, bounds.max.y); |  | ||||||
|         Vector2 topAreaEnd = new Vector2(bounds.max.x, bounds.max.y + snapDistance); |  | ||||||
|  |  | ||||||
|         Collider2D[] hitsRight = Physics2D.OverlapAreaAll(rightAreaStart, rightAreaEnd); |  | ||||||
|         Collider2D[] hitsLeft = Physics2D.OverlapAreaAll(leftAreaStart, leftAreaEnd); |  | ||||||
|         Collider2D[] hitsBelow = Physics2D.OverlapAreaAll(bottomAreaStart, bottomAreaEnd); |  | ||||||
|         Collider2D[] hitsAbove = Physics2D.OverlapAreaAll(topAreaStart, topAreaEnd); |  | ||||||
|  |  | ||||||
|         // ➔ Priorité : droite > gauche > bas > haut |  | ||||||
|  |  | ||||||
|         foreach (var hit in hitsRight) |  | ||||||
|         { |         { | ||||||
|             if (hit != null && hit.gameObject != currentBlock) |             float topY = hit.collider.bounds.max.y; | ||||||
|             { |             float height = bounds.size.y; | ||||||
|                 float theirLeft = hit.bounds.min.x; |             float newY = topY + height / 2f; | ||||||
|                 float ourWidth = bounds.size.x; |  | ||||||
|                 currentBlock.transform.position = new Vector3(theirLeft - ourWidth / 2f, currentBlock.transform.position.y, -1); |  | ||||||
|                 Debug.Log("✅ Snap automatique à droite !"); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         foreach (var hit in hitsLeft) |             currentBlock.transform.position = new Vector3(currentBlock.transform.position.x, newY, -1f); | ||||||
|         { |             Debug.Log($"📌 Bloc descendu sur {hit.collider.name} à Y={newY}"); | ||||||
|             if (hit != null && hit.gameObject != currentBlock) |  | ||||||
|             { |  | ||||||
|                 float theirRight = hit.bounds.max.x; |  | ||||||
|                 float ourWidth = bounds.size.x; |  | ||||||
|                 currentBlock.transform.position = new Vector3(theirRight + ourWidth / 2f, currentBlock.transform.position.y, -1); |  | ||||||
|                 Debug.Log("✅ Snap automatique à gauche !"); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             Debug.Log("❗ Aucun support trouvé en dessous pour aligner le bloc."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     bool ShouldSkipVerticalSnap(string name) | ||||||
|  |     { | ||||||
|  |         name = name.ToLower(); | ||||||
|  |         return name.Contains("smallobstacle") || name.Contains("portal"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void SnapBlockVertically() | ||||||
|  |     { | ||||||
|  |         Collider2D col = currentBlock.GetComponent<Collider2D>(); | ||||||
|  |         Bounds bounds = col.bounds; | ||||||
|  |  | ||||||
|  |         float snapThreshold = 0.1f; // ➜ 0.1 unité = environ 2 pixels | ||||||
|  |  | ||||||
|  |         Vector2 checkStart = new Vector2(bounds.min.x, bounds.min.y - snapThreshold); | ||||||
|  |         Vector2 checkEnd = new Vector2(bounds.max.x, bounds.min.y); | ||||||
|  |  | ||||||
|  |         Collider2D[] hitsBelow = Physics2D.OverlapAreaAll(checkStart, checkEnd); | ||||||
|  |  | ||||||
|  |         float highestY = -Mathf.Infinity; | ||||||
|  |         GameObject bestTarget = null; | ||||||
|  |  | ||||||
|         foreach (var hit in hitsBelow) |         foreach (var hit in hitsBelow) | ||||||
|         { |         { | ||||||
|             if (hit != null && hit.gameObject != currentBlock) |             if (hit == null || hit.gameObject == currentBlock || hit.transform.IsChildOf(currentBlock.transform)) | ||||||
|  |                 continue; | ||||||
|  |  | ||||||
|  |             float top = hit.bounds.max.y; | ||||||
|  |             if (top > highestY) | ||||||
|             { |             { | ||||||
|                 float theirTop = hit.bounds.max.y; |                 highestY = top; | ||||||
|                 float ourHeight = bounds.size.y; |                 bestTarget = hit.gameObject; | ||||||
|                 currentBlock.transform.position = new Vector3(currentBlock.transform.position.x, theirTop + ourHeight / 2f, -1); |  | ||||||
|                 Debug.Log("✅ Snap automatique en bas !"); |  | ||||||
|                 return; |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         foreach (var hit in hitsAbove) |         if (bestTarget != null) | ||||||
|         { |         { | ||||||
|             if (hit != null && hit.gameObject != currentBlock) |             float blockHeight = bounds.size.y; | ||||||
|             { |             float snapY = highestY + blockHeight / 2f; | ||||||
|                 float theirBottom = hit.bounds.min.y; |  | ||||||
|                 float ourHeight = bounds.size.y; |             currentBlock.transform.position = new Vector3(currentBlock.transform.position.x, snapY, -1f); | ||||||
|                 currentBlock.transform.position = new Vector3(currentBlock.transform.position.x, theirBottom - ourHeight / 2f, -1); |             Debug.Log($"✅ Snap vertical à {snapY} sur {bestTarget.name}"); | ||||||
|                 Debug.Log("✅ Snap automatique en haut !"); |         } | ||||||
|                 return; |         else | ||||||
|             } |         { | ||||||
|  |             Debug.Log("❌ Aucun bloc trouvé assez proche en dessous pour snap."); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     void InstantiateAndPrepare(GameObject prefab, Vector3? scaleOverride = null) |     void InstantiateAndPrepare(GameObject prefab, Vector3? scaleOverride = null) | ||||||
|     { |     { | ||||||
|         GameObject obj = Instantiate(prefab); |         GameObject obj = Instantiate(prefab); | ||||||
| @@ -439,15 +328,194 @@ public class LevelEditor : MonoBehaviour | |||||||
|         obj.transform.localScale = scaleOverride ?? currentScale; |         obj.transform.localScale = scaleOverride ?? currentScale; | ||||||
|  |  | ||||||
|         try { obj.tag = prefab.name; } |         try { obj.tag = prefab.name; } | ||||||
|         catch { Debug.LogWarning($"Le tag '{prefab.name}' n'existe pas. Ajoutez-le dans Project Settings > Tags."); } |         catch { Debug.LogWarning($"Le tag '{prefab.name}' est manquant."); } | ||||||
|  |  | ||||||
|         currentBlock = obj; |         currentBlock = obj; | ||||||
|         isPlacingBlock = true; |         isPlacingBlock = true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void HandleBlockRotation() |     void HandleBlockRotation() | ||||||
|     { |     { | ||||||
|         currentBlock.transform.Rotate(0f, 0f, -90f); // ➔ Rotation de 90° dans le sens horaire |         currentBlock.transform.Rotate(0f, 0f, -90f); | ||||||
|         Debug.Log("🔄 Bloc pivoté de 90° !"); |         Debug.Log("🔄 Bloc pivoté de 90° !"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     #endregion | ||||||
|  |  | ||||||
|  |     #region Resizing & Deletion | ||||||
|  |  | ||||||
|  |     void HandleBlockResizing() | ||||||
|  |     { | ||||||
|  |         if (Input.GetMouseButtonDown(0) && Input.GetKey(KeyCode.LeftShift) && !isPlacingBlock) | ||||||
|  |         { | ||||||
|  |             Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); | ||||||
|  |             Collider2D hit = Physics2D.OverlapPoint(mousePos); | ||||||
|  |  | ||||||
|  |             if (hit != null && !hit.CompareTag("Ground")) | ||||||
|  |             { | ||||||
|  |                 BeginResizing(hit.gameObject, mousePos); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (isResizing && resizingTarget != null) | ||||||
|  |         { | ||||||
|  |             PerformResizing(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void BeginResizing(GameObject target, Vector2 mousePos) | ||||||
|  |     { | ||||||
|  |         resizingTarget = target; | ||||||
|  |         originalMousePos = mousePos; | ||||||
|  |         originalScale = target.transform.localScale; | ||||||
|  |  | ||||||
|  |         Vector2 localClick = mousePos - (Vector2)target.transform.position; | ||||||
|  |         float ratio = target.GetComponent<Collider2D>().bounds.size.x / target.GetComponent<Collider2D>().bounds.size.y; | ||||||
|  |  | ||||||
|  |         currentResizeAxis = Mathf.Abs(localClick.x) > Mathf.Abs(localClick.y * ratio) | ||||||
|  |             ? ResizeAxis.Horizontal | ||||||
|  |             : ResizeAxis.Vertical; | ||||||
|  |  | ||||||
|  |         isResizing = true; | ||||||
|  |         Debug.Log($"🧰 Début du redimensionnement : {target.name} (axe : {currentResizeAxis})"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void PerformResizing() | ||||||
|  |     { | ||||||
|  |         Vector3 currentMousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); | ||||||
|  |         Vector3 delta = currentMousePos - originalMousePos; | ||||||
|  |  | ||||||
|  |         Vector3 newScale = originalScale; | ||||||
|  |         if (currentResizeAxis == ResizeAxis.Horizontal) | ||||||
|  |             newScale.x = Mathf.Max(0.1f, originalScale.x + delta.x); | ||||||
|  |         else if (currentResizeAxis == ResizeAxis.Vertical) | ||||||
|  |             newScale.y = Mathf.Max(0.1f, originalScale.y + delta.y); | ||||||
|  |  | ||||||
|  |         resizingTarget.transform.localScale = newScale; | ||||||
|  |  | ||||||
|  |         if (IsOverlapping(resizingTarget)) | ||||||
|  |         { | ||||||
|  |             resizingTarget.transform.localScale = originalScale; | ||||||
|  |             Debug.Log("❌ Redimensionnement annulé : collision."); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (Input.GetMouseButtonUp(0)) | ||||||
|  |         { | ||||||
|  |             isResizing = false; | ||||||
|  |             resizingTarget = null; | ||||||
|  |             currentResizeAxis = ResizeAxis.None; | ||||||
|  |             Debug.Log("✅ Fin du redimensionnement"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     bool IsOverlapping(GameObject obj) | ||||||
|  |     { | ||||||
|  |         Bounds bounds = obj.GetComponent<Collider2D>().bounds; | ||||||
|  |         Collider2D[] overlaps = Physics2D.OverlapBoxAll(bounds.center, bounds.size, 0f); | ||||||
|  |  | ||||||
|  |         foreach (var col in overlaps) | ||||||
|  |         { | ||||||
|  |             if (col.gameObject != obj) | ||||||
|  |                 return true; | ||||||
|  |         } | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void HandleBlockDeletion() | ||||||
|  |     { | ||||||
|  |         if (Input.GetMouseButtonDown(1)) | ||||||
|  |         { | ||||||
|  |             Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); | ||||||
|  |             Collider2D hit = Physics2D.OverlapPoint(mousePos); | ||||||
|  |  | ||||||
|  |             if (hit != null && !hit.CompareTag("Ground")) | ||||||
|  |             { | ||||||
|  |                 GameObject toDestroy = hit.gameObject; | ||||||
|  |  | ||||||
|  |                 // ✅ Cas spécial : ObstacleBlock ou ses enfants | ||||||
|  |                 if (toDestroy.name.Contains("ObstacleSafer") || toDestroy.name.Contains("ObstacleKiller")) | ||||||
|  |                 { | ||||||
|  |                     Transform parent = toDestroy.transform.parent; | ||||||
|  |                     if (parent != null && parent.name.Contains("ObstacleBlock")) | ||||||
|  |                     { | ||||||
|  |                         toDestroy = parent.gameObject; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 if (toDestroy == currentBlock) | ||||||
|  |                 { | ||||||
|  |                     currentBlock = null; | ||||||
|  |                     isPlacingBlock = false; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 Destroy(toDestroy); | ||||||
|  |                 Debug.Log($"🗑️ Supprimé : {toDestroy.name}"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     #endregion | ||||||
|  |  | ||||||
|  |     #region Utility | ||||||
|  |  | ||||||
|  |     bool IsPointerOverUI() | ||||||
|  |     { | ||||||
|  |         return EventSystem.current != null && EventSystem.current.IsPointerOverGameObject(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void TrySnapToNearbyBlock() | ||||||
|  |     { | ||||||
|  |         if (currentBlock == null) return; | ||||||
|  |  | ||||||
|  |         Collider2D blockCollider = currentBlock.GetComponent<Collider2D>(); | ||||||
|  |         Bounds bounds = blockCollider.bounds; | ||||||
|  |         float snapDistance = 1f; | ||||||
|  |  | ||||||
|  |         Vector2[] directions = | ||||||
|  |         { | ||||||
|  |             Vector2.right, Vector2.left, Vector2.down, Vector2.up | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         foreach (var dir in directions) | ||||||
|  |         { | ||||||
|  |             Vector2 extent2D = new Vector2(bounds.extents.x, bounds.extents.y); | ||||||
|  |             Vector2 start = (Vector2)bounds.center + dir * (extent2D + Vector2.one * (snapDistance / 2f)); | ||||||
|  |             Collider2D[] hits = Physics2D.OverlapCircleAll(start, snapDistance); | ||||||
|  |  | ||||||
|  |             foreach (var hit in hits) | ||||||
|  |             { | ||||||
|  |                 if (hit != null && hit.gameObject != currentBlock) | ||||||
|  |                 { | ||||||
|  |                     SnapToTarget(hit, dir); | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void SnapToTarget(Collider2D hit, Vector2 dir) | ||||||
|  |     { | ||||||
|  |         Bounds hitBounds = hit.bounds; | ||||||
|  |         Bounds ourBounds = currentBlock.GetComponent<Collider2D>().bounds; | ||||||
|  |  | ||||||
|  |         Vector3 newPos = currentBlock.transform.position; | ||||||
|  |  | ||||||
|  |         if (dir == Vector2.right) | ||||||
|  |             newPos.x = hitBounds.min.x - ourBounds.size.x / 2f; | ||||||
|  |         else if (dir == Vector2.left) | ||||||
|  |             newPos.x = hitBounds.max.x + ourBounds.size.x / 2f; | ||||||
|  |         else if (dir == Vector2.down) | ||||||
|  |             newPos.y = hitBounds.max.y + ourBounds.size.y / 2f; | ||||||
|  |         else if (dir == Vector2.up) | ||||||
|  |             newPos.y = hitBounds.min.y - ourBounds.size.y / 2f; | ||||||
|  |  | ||||||
|  |         currentBlock.transform.position = new Vector3(newPos.x, newPos.y, -1); | ||||||
|  |         Debug.Log("✅ Snap à " + dir); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void Save() | ||||||
|  |     { | ||||||
|  |         // TODO : Sauvegarde du niveau | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     #endregion | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user