load et save feature pour level

sauvegarder et charger des niveaux à partir d'un tilemap

un scriptable object contient les informations pour le niveau

un script avec un custom editor permet de sauvegarder un ensemble de tilemaps, ou de charger l'information contenue dans un scriptable object
This commit is contained in:
Felix Boucher 2023-05-10 17:05:36 -04:00
parent 92146f563c
commit 9e07d7f882
13 changed files with 570 additions and 0 deletions

8
Assets/LevelEditor.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0ca30b5ca281be24bb62d7e48cc2bec8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,17 @@
using UnityEditor;
using UnityEngine;
using UnityEngine.Tilemaps;
namespace GatherAndDefend.LevelEditor
{
public class LevelEditor : MonoBehaviour
{
[SerializeField]
private Map _level;
public Map Level
{
get => _level;
set => _level = value;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f2aa8eca66833af4ba45af1319c90803
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,53 @@
using UnityEditor;
using UnityEngine.Tilemaps;
using UnityEngine;
using System.IO;
namespace GatherAndDefend.LevelEditor
{
[CustomEditor(typeof(LevelEditor))]
public class LevelEditorEditor : Editor
{
const string defaultName = "Level";
const string extension = ".asset";
string Path => "Assets/";
public override void OnInspectorGUI()
{
DrawDefaultInspector();
var targ = (LevelEditor)target;
if (GUILayout.Button("Save"))
{
string name;
if (targ.Level) name = targ.Level.name;
else name = defaultName;
if (File.Exists(Path + name + extension))
{
File.Delete(Path + name + extension);
}
var map = CreateInstance<Map>();
map.name = name;
foreach (Tilemap tilemap in targ.GetComponentsInChildren<Tilemap>())
{
map.Write(tilemap);
}
AssetDatabase.CreateAsset(map, Path + name + extension);
targ.Level = map;
AssetDatabase.ImportAsset(Path + name + extension);
}
if (GUILayout.Button("Load"))
{
if (!targ.Level) return;
foreach (Tilemap tilemap in targ.GetComponentsInChildren<Tilemap>())
{
tilemap.ClearAllTiles();
targ.Level.Read(tilemap);
}
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6eee7cfedfe2c8d4abdb8a5ef71d8158
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,334 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 3
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 12
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 0
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 512
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 256
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 1
m_PVRDenoiserTypeDirect: 1
m_PVRDenoiserTypeIndirect: 1
m_PVRDenoiserTypeAO: 1
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_LightingSettings: {fileID: 0}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &189138874
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 189138875}
- component: {fileID: 189138877}
- component: {fileID: 189138876}
m_Layer: 0
m_Name: Tilemap
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &189138875
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 189138874}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1827197199}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!483693784 &189138876
TilemapRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 189138874}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 0
m_ReflectionProbeUsage: 0
m_RayTracingMode: 0
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 0
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_ChunkSize: {x: 32, y: 32, z: 32}
m_ChunkCullingBounds: {x: 0, y: 0, z: 0}
m_MaxChunkCount: 16
m_MaxFrameAge: 16
m_SortOrder: 0
m_Mode: 0
m_DetectChunkCullingBounds: 0
m_MaskInteraction: 0
--- !u!1839735485 &189138877
Tilemap:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 189138874}
m_Enabled: 1
m_Tiles: {}
m_AnimatedTiles: {}
m_TileAssetArray:
- m_RefCount: 0
m_Data: {fileID: 0}
m_TileSpriteArray:
- m_RefCount: 0
m_Data: {fileID: 0}
- m_RefCount: 0
m_Data: {fileID: 0}
m_TileMatrixArray:
- m_RefCount: 0
m_Data:
e00: 0
e01: 0
e02: -1.1020282e-38
e03: -1.1020282e-38
e10: 0
e11: 0
e12: 7.79e-43
e13: 7.79e-43
e20: -7.180341e-21
e21: 1e-45
e22: 7.1748835e-29
e23: -1.5782e-40
e30: 4.5905e-41
e31: 0
e32: 7.8e-43
e33: 7.83e-43
m_TileColorArray:
- m_RefCount: 0
m_Data: {r: 4.0116e-41, g: 4.0116e-41, b: 4.0116e-41, a: 4.0116e-41}
- m_RefCount: 0
m_Data: {r: NaN, g: NaN, b: NaN, a: NaN}
m_TileObjectToInstantiateArray:
- m_RefCount: 0
m_Data: {fileID: 0}
m_AnimationFrameRate: 1
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Origin: {x: -5, y: -2, z: 0}
m_Size: {x: 5, y: 4, z: 1}
m_TileAnchor: {x: 0.5, y: 0.5, z: 0}
m_TileOrientation: 0
m_TileOrientationMatrix:
e00: 1
e01: 0
e02: 0
e03: 0
e10: 0
e11: 1
e12: 0
e13: 0
e20: 0
e21: 0
e22: 1
e23: 0
e30: 0
e31: 0
e32: 0
e33: 1
--- !u!1 &1827197197
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1827197199}
- component: {fileID: 1827197198}
- component: {fileID: 1827197200}
m_Layer: 0
m_Name: Grid
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!156049354 &1827197198
Grid:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1827197197}
m_Enabled: 1
m_CellSize: {x: 1, y: 1, z: 0}
m_CellGap: {x: 0, y: 0, z: 0}
m_CellLayout: 0
m_CellSwizzle: 0
--- !u!4 &1827197199
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1827197197}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 189138875}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1827197200
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1827197197}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f2aa8eca66833af4ba45af1319c90803, type: 3}
m_Name:
m_EditorClassIdentifier:
_level: {fileID: 11400000, guid: bac1b4f94448a7e4f92d7d855f05d882, type: 2}

View File

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

25
Assets/LevelEditor/Map.cs Normal file
View File

@ -0,0 +1,25 @@
using System.Collections.Generic;
using UnityEngine.Tilemaps;
using UnityEngine;
namespace GatherAndDefend.LevelEditor
{
public class Map : ScriptableObject
{
[SerializeField]
private List<TilemapData> _data = new List<TilemapData>();
public void Write(Tilemap tilemap)
{
var data = new TilemapData();
data.Write(tilemap);
_data.Add(data);
}
public void Read(Tilemap tilemap)
{
var data = _data.Find(x => x.Key == tilemap.name);
if (data == null) return;
data.Read(tilemap);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2b7bfc7dd6af8f648b6abb36eb3be022
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,24 @@
using UnityEngine.Tilemaps;
using UnityEngine;
using System;
namespace GatherAndDefend.LevelEditor
{
[Serializable]
public class TileData
{
[SerializeField]
private TileBase _tile;
[SerializeField]
private Vector3Int _position;
public TileBase Tile => _tile;
public Vector3Int Position => _position;
public TileData(Vector3Int position, TileBase tile)
{
this._position = position;
this._tile = tile;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 60a5887e9e712d145b7baa6d1f0a779f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,47 @@
using System.Collections.Generic;
using UnityEngine.Tilemaps;
using UnityEngine;
using System;
namespace GatherAndDefend.LevelEditor
{
[Serializable]
public class TilemapData
{
[SerializeField]
private string _key;
[SerializeField]
private List<TileData> tiles;
public string Key => _key;
public void Read(Tilemap reference)
{
foreach (TileData data in tiles)
{
reference.SetTile(data.Position, data.Tile);
}
}
public void Write(Tilemap reference)
{
_key = reference.name;
tiles = new List<TileData>();
BoundsInt bounds = reference.cellBounds;
for (int i = bounds.xMin; i <= bounds.xMax; i++)
{
for (int j = bounds.yMin; j <= bounds.yMax; j++)
{
Vector3Int position = new Vector3Int(i, j);
TileBase tile = reference.GetTile(position);
if (!tile) continue;
var tileData = new TileData(position, tile);
tiles.Add(tileData);
}
}
}
public TilemapData()
{
tiles = new List<TileData>();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9acf8a297e0a8a14cbc0cf1e9011bbbe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: