feat: edit a level (#64)

This commit is contained in:
M VINCENT PETT 2025-05-16 13:19:44 +02:00 committed by GitHub
parent f818a9a8a7
commit bdd238f524
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 1551 additions and 33 deletions

View File

@ -202,9 +202,9 @@ MonoBehaviour:
m_OnClick:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 0}
- m_Target: {fileID: 1858033414}
m_TargetAssemblyTypeName: MainMenu, Assembly-CSharp
m_MethodName: OpenImport
m_MethodName: EditLevel
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
@ -859,7 +859,7 @@ MonoBehaviour:
m_Calls:
- m_Target: {fileID: 1858033414}
m_TargetAssemblyTypeName: MainMenu, Assembly-CSharp
m_MethodName: LevelEditor
m_MethodName: CreateVoidLevel
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}

View File

@ -4964,7 +4964,6 @@ GameObject:
- component: {fileID: 78453694}
- component: {fileID: 78453693}
- component: {fileID: 78453692}
- component: {fileID: 78453696}
- component: {fileID: 78453697}
m_Layer: 0
m_Name: LevelEditorPlayer
@ -5117,18 +5116,6 @@ Transform:
- {fileID: 39537682}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &78453696
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 78453690}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 680dadbbc97b91b47a86bde6254fde4d, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &78453697
MonoBehaviour:
m_ObjectHideFlags: 0
@ -5837,7 +5824,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: f5bf592d3d8430744a08058675701934, type: 3}
m_Name:
m_EditorClassIdentifier:
mapParent: {fileID: 0}
blockGroupContainer: {fileID: 394350961}
buttonPrefabTemplate: {fileID: 1993500743}
--- !u!114 &746393166
@ -6019,6 +6005,153 @@ SpriteRenderer:
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!1 &1479180207
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1479180210}
- component: {fileID: 1479180209}
- component: {fileID: 1479180208}
m_Layer: 0
m_Name: LevelLoader
m_TagString: LevelLoader
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!82 &1479180208
AudioSource:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1479180207}
m_Enabled: 1
serializedVersion: 4
OutputAudioMixerGroup: {fileID: 0}
m_audioClip: {fileID: 0}
m_Resource: {fileID: 0}
m_PlayOnAwake: 1
m_Volume: 1
m_Pitch: 1
Loop: 0
Mute: 0
Spatialize: 0
SpatializePostEffects: 0
Priority: 128
DopplerLevel: 1
MinDistance: 1
MaxDistance: 500
Pan2D: 0
rolloffMode: 0
BypassEffects: 0
BypassListenerEffects: 0
BypassReverbZones: 0
rolloffCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 1
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
panLevelCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
spreadCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
reverbZoneMixCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
--- !u!114 &1479180209
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1479180207}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 017ea60a517f31bf3af976010911be25, type: 3}
m_Name:
m_EditorClassIdentifier:
levelsLoader: {fileID: 0}
createMode: 0
editMode: 1
audioSource: {fileID: 1479180208}
progressionText: {fileID: 0}
--- !u!4 &1479180210
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1479180207}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 8.485552, y: 2.2081068, z: -0.13737443}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1561821047
GameObject:
m_ObjectHideFlags: 0
@ -6873,3 +7006,4 @@ SceneRoots:
- {fileID: 1724106027}
- {fileID: 2030873961}
- {fileID: 78453695}
- {fileID: 1479180210}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2fabb6c6015f46541a57baf21011fa51
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -4,6 +4,7 @@ using UnityEngine.SceneManagement;
public class NormalGameMode : IGameMode
{
public bool editMode { get; set; } = false;
private const float HorizontalSpeed = 8.6f;
private const float JumpForce = 26.6581f;
private const KeyCode JumpKey = KeyCode.Space;
@ -18,6 +19,7 @@ public class NormalGameMode : IGameMode
if (player.IsColliding && Input.GetKey(JumpKey) && !isRotating)
{
Debug.Log("Player is Jumping");
Jump(player);
}
@ -89,7 +91,18 @@ public class NormalGameMode : IGameMode
if (collision.gameObject.CompareTag("Kill"))
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
if (editMode)
{
GameObject spawn = new GameObject("AutoSpawnPoint");
spawn.transform.position = new Vector3(-16, -3, 0f);
player.transform.position = spawn.transform.position;
player.RigidBody.linearVelocity = Vector2.zero;
player.SpeedMultiplier = 1f;
}
else
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
if (collision.gameObject.CompareTag("Win"))

View File

@ -0,0 +1,153 @@
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using SimpleFileBrowser;
using TMPro;
[System.Serializable]
public class BlockData
{
public string prefabName;
public Vector3 position;
public float rotationZ;
public Vector3 scale;
}
[System.Serializable]
public class LevelData
{
public string levelName;
public List<BlockData> blocks = new List<BlockData>();
}
public class JSONLevelEditor : MonoBehaviour
{
[Header("UI")]
public TMP_Dropdown levelDropdown;
public Button loadButton;
public Button saveButton;
public TMP_Text statusText;
[Header("Editor")]
public Transform editRoot; // où on instancie les blocs
public List<GameObject> blockPrefabs; // à remplir dans linspecteur (mêmes noms que dans JSON)
private LevelData currentLevel;
private string currentJsonPath;
private void Start()
{
// Remplir la dropdown avec les JSON disponibles dans Resources/Levels
var assets = Resources.LoadAll<TextAsset>("Levels");
levelDropdown.options.Clear();
foreach (var txt in assets)
levelDropdown.options.Add(new TMP_Dropdown.OptionData(txt.name));
levelDropdown.RefreshShownValue();
loadButton.onClick.AddListener(OnLoadClicked);
saveButton.onClick.AddListener(OnSaveClicked);
UpdateStatus("Prêt.", Color.white);
}
private void OnLoadClicked()
{
string lvlName = levelDropdown.options[levelDropdown.value].text;
TextAsset json = Resources.Load<TextAsset>($"Levels/{lvlName}");
if (json == null)
{
UpdateStatus($"Niveau '{lvlName}' introuvable.", Color.red);
return;
}
currentJsonPath = Path.Combine(Application.dataPath, "Resources/Levels", lvlName + ".json");
currentLevel = JsonUtility.FromJson<LevelData>(json.text);
if (currentLevel == null)
{
UpdateStatus("Impossible de parser le JSON.", Color.red);
return;
}
ClearEditRoot();
foreach (var bd in currentLevel.blocks)
{
var prefab = blockPrefabs.Find(p => p.name == bd.prefabName);
if (prefab == null) continue;
var go = Instantiate(prefab, editRoot);
go.transform.localPosition = bd.position;
go.transform.localEulerAngles = new Vector3(0, 0, bd.rotationZ);
go.transform.localScale = bd.scale;
// vous pouvez ajouter un script pour manipuler ce 'go' dans léditeur
}
UpdateStatus($"Niveau '{lvlName}' chargé.", Color.green);
}
private void OnSaveClicked()
{
if (currentLevel == null)
{
UpdateStatus("Aucun niveau chargé.", Color.red);
return;
}
// Reconstruire le LevelData depuis les enfants de editRoot
currentLevel.blocks.Clear();
foreach (Transform child in editRoot)
{
var bd = new BlockData
{
prefabName = child.name.Replace("(Clone)", ""),
position = child.localPosition,
rotationZ = child.localEulerAngles.z,
scale = child.localScale
};
currentLevel.blocks.Add(bd);
}
// Demande path de sauvegarde
StartCoroutine(DoSaveDialog());
}
private IEnumerator DoSaveDialog()
{
yield return FileBrowser.WaitForSaveDialog(
FileBrowser.PickMode.Files, false, null, "json",
"Save JSON", "Save");
if (!FileBrowser.Success)
{
UpdateStatus("Sauvegarde annulée.", Color.red);
yield break;
}
string dest = FileBrowser.Result[0];
if (!dest.EndsWith(".json")) dest += ".json";
string jsonText = JsonUtility.ToJson(currentLevel, true);
try
{
File.WriteAllText(dest, jsonText);
UpdateStatus($"Sauvegardé : {dest}", Color.green);
}
catch (System.Exception e)
{
Debug.LogError(e);
UpdateStatus("Erreur lors de la sauvegarde.", Color.red);
}
}
private void ClearEditRoot()
{
for (int i = editRoot.childCount - 1; i >= 0; i--)
DestroyImmediate(editRoot.GetChild(i).gameObject);
}
private void UpdateStatus(string msg, Color col)
{
if (statusText == null) return;
statusText.text = msg;
statusText.color = col;
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4a995a69086a0184d830aa300b3c2843

View File

@ -5,6 +5,8 @@ using System.IO;
public class LevelLoader : MonoBehaviour
{
public LevelsLoader levelsLoader;
public bool editMode;
public bool createMode;
public AudioSource audioSource;
public Text progressionText;
private readonly float groundY = -6.034f;
@ -49,27 +51,36 @@ public class LevelLoader : MonoBehaviour
instance.transform.localScale = new Vector3(newScaleX, newScaleY, originalScale.z);
}
GameObject groundPrefab = GetPrefab("Ground");
GameObject groundInstance = Instantiate(groundPrefab, new Vector3(current.LastX / 2, groundY, 0), Quaternion.identity);
float groundWidth = current.LastX;
groundInstance.transform.localScale = new Vector3(groundWidth / 5f * 2, 1, 1);
if (!editMode)
{
GameObject groundPrefab = GetPrefab("Ground");
GameObject groundInstance = Instantiate(groundPrefab, new Vector3(current.LastX / 2, groundY, 0), Quaternion.identity);
float groundWidth = current.LastX;
groundInstance.transform.localScale = new Vector3(groundWidth / 5f * 2, 1, 1);
}
Instantiate(GetPrefab("WinnerWall"), new Vector3(current.LastX, 0, 0), Quaternion.Euler(0, 0, 90));
}
public void Start()
{
levelsLoader = GameObject.FindGameObjectWithTag("LevelsLoader").GetComponent<LevelsLoader>();
levelsLoader.IncreaseTotalAttempts();
createMode = PlayerPrefs.GetInt("CreateMode", 0) == 1;
if (!createMode)
{
levelsLoader = GameObject.FindGameObjectWithTag("LevelsLoader").GetComponent<LevelsLoader>();
levelsLoader.IncreaseTotalAttempts();
LoadAudio();
LoadElements();
LoadElements();
if (!editMode)
LoadAudio();
}
}
public void Update()
{
Level current = levelsLoader.levelCurrent;
progressionText.text = current.ProgressionPercent + "%";
if (!editMode)
{
Level current = levelsLoader.levelCurrent;
progressionText.text = current.ProgressionPercent + "%";
}
}
}

View File

@ -5,6 +5,8 @@ public class LevelHomeButton : MonoBehaviour
{
public void GoToHome()
{
PlayerPrefs.SetInt("CreateMode", 0);
PlayerPrefs.SetInt("EditMode", 0);
SceneManager.LoadScene("HomeScene");
}
}

View File

@ -7,4 +7,9 @@ public class LevelNameButton : MonoBehaviour
{
SceneManager.LoadScene("LevelScene");
}
public void EditLevel()
{
PlayerPrefs.SetInt("CreateMode", 0);
SceneManager.LoadScene("LevelEditorScene");
}
}

View File

@ -23,13 +23,19 @@ public class MainMenu : MonoBehaviour
SceneManager.LoadSceneAsync("LevelEditorScene");
}
public void CreateVoidLevel()
{
PlayerPrefs.SetInt("CreateMode", 1);
SceneManager.LoadScene("LevelEditorScene");
}
public void EditorChoice()
{
SceneManager.LoadSceneAsync("EditorChoiceScene");
}
public void CreateLevel()
public void EditLevel()
{
SceneManager.LoadSceneAsync("CreateLevelScene");
SceneManager.LoadSceneAsync("SelectLevelToEditScene");
}
}

View File

@ -27,6 +27,7 @@ public class TestManager : MonoBehaviour
else
{
gameMode = new NormalGameMode();
((NormalGameMode)gameMode).editMode = true;
currentPlayer.ChangeGameMode(gameMode);
currentPlayer.SpeedMultiplier = 0f;
@ -68,12 +69,15 @@ public class TestManager : MonoBehaviour
}
if (editorUI != null)
{
Debug.LogError("editor UI null");
editorUI.SetActive(false);
}
currentPlayer.transform.position = spawnPoint.position;
currentPlayer.RigidBody.linearVelocity = Vector2.zero;
currentPlayer.SpeedMultiplier = 1f;
currentPlayer.SpriteRenderer.sprite = Resources.Load<Sprite>("Shapes/BaseSquare");
// currentPlayer.SpriteRenderer.sprite = Resources.Load<Sprite>("Shapes/BaseSquare");
currentPlayer.ChangeGameMode(gameMode);
isTesting = true;

View File

@ -17,6 +17,17 @@ EditorBuildSettings:
- enabled: 1
path: Assets/Scenes/LevelScene.unity
guid: 8c9cfa26abfee488c85f1582747f6a02
- enabled: 1
path: Assets/Scenes/ImportScene.unity
guid: 079203ac02d460d48a1208a03134d373
- enabled: 1
path: Assets/Scenes/EditorChoiceScene.unity
guid: 200c916866fde6f4bb0123b72f22771f
- enabled: 1
path: Assets/Scenes/SelectLevelToEditScene.unity
guid: 2fabb6c6015f46541a57baf21011fa51
- enabled: 1
path: Assets/Scenes/CreateLevelScene.unity
- enabled: 0
path: Assets/Scenes/LevelEditorScene.unity
guid: 73b983a44d701df4bb6d8ceb94e05a2b