├── 3D Tilemap System ├── Data.meta ├── Data │ ├── CustomMeshTilemapData.asset │ ├── CustomMeshTilemapData.asset.meta │ ├── TerrainTilemapData.asset │ └── TerrainTilemapData.asset.meta ├── Editor.meta ├── Editor │ ├── TilePaletteInspector.cs │ ├── TilePaletteInspector.cs.meta │ ├── TilemapSystemInspector.cs │ ├── TilemapSystemInspector.cs.meta │ ├── UI.meta │ └── UI │ │ ├── BlobLayout.asset │ │ ├── BlobLayout.asset.meta │ │ ├── BlobLayout.png │ │ ├── BlobLayout.png.meta │ │ ├── _DefaultColor.png │ │ ├── _DefaultColor.png.meta │ │ ├── _EmptyIcon.png │ │ └── _EmptyIcon.png.meta ├── Imports.meta ├── Imports │ ├── CustomMapMesh.obj │ └── CustomMapMesh.obj.meta ├── Palettes.meta ├── Palettes │ ├── Layer0.asset │ ├── Layer0.asset.meta │ ├── Layer1.asset │ └── Layer1.asset.meta ├── Scenes.meta ├── Scenes │ ├── CustomMesh.unity │ ├── CustomMesh.unity.meta │ ├── New Terrain.asset │ ├── New Terrain.asset.meta │ ├── UnityTerrain.unity │ └── UnityTerrain.unity.meta ├── Scripts.meta ├── Scripts │ ├── TilePalette.cs │ ├── TilePalette.cs.meta │ ├── TilemapData.cs │ ├── TilemapData.cs.meta │ ├── TilemapSystem3D.cs │ ├── TilemapSystem3D.cs.meta │ ├── Utilities.meta │ └── Utilities │ │ ├── TilemapSystem3DEditorStuffs.cs │ │ ├── TilemapSystem3DEditorStuffs.cs.meta │ │ ├── TilemapSystemLayer.cs │ │ ├── TilemapSystemLayer.cs.meta │ │ ├── TilemapSystemUtilities.cs │ │ └── TilemapSystemUtilities.cs.meta ├── Shaders.meta ├── Shaders │ ├── Legacy Diffuse.shader │ ├── Legacy Diffuse.shader.meta │ ├── Legacy Unlit.shader │ └── Legacy Unlit.shader.meta ├── Textures.meta └── Textures │ ├── Layer0.png │ ├── Layer0.png.meta │ ├── Layer1.png │ └── Layer1.png.meta └── README.md /3D Tilemap System/Data.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3525db21b5e87a64cabc0a2d32e2bff6 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /3D Tilemap System/Data/CustomMeshTilemapData.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2f70dcf06658099458dc5d1d4d47124e 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /3D Tilemap System/Data/TerrainTilemapData.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d4247b418b0fcb64f96a64171c4d4bc9 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /3D Tilemap System/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c710253091bac0c409ff22f3a7103aa9 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /3D Tilemap System/Editor/TilePaletteInspector.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using UnityEngine.TilemapSystem3D; 4 | 5 | [CustomEditor(typeof(TilePalette))] 6 | public class TilePaletteInspector : Editor 7 | { 8 | // The target script 9 | private TilePalette m_target; 10 | 11 | // Editor only 12 | public Texture2D emptyIconTexture; 13 | private readonly Color m_noColor = new Color(0.0f, 0.0f, 0.0f, 0.0f); 14 | private readonly Color m_greenColor = new Color(0.85f, 1.0f, 0.85f); 15 | private readonly Color m_redColor = new Color(1.0f, 0.75f, 0.75f); 16 | private readonly int[] m_tileSizeArray = new[] {16, 24, 32, 48, 64, 96, 128}; 17 | private readonly GUIContent[] m_tileSizeContentArray = new GUIContent[] 18 | { 19 | new GUIContent("16x16", "Select the proper resolution for your tiles."), 20 | new GUIContent("24x24", "Select the proper resolution for your tiles."), 21 | new GUIContent("32x32", "Select the proper resolution for your tiles."), 22 | new GUIContent("48x48", "Select the proper resolution for your tiles."), 23 | new GUIContent("64x64", "Select the proper resolution for your tiles."), 24 | new GUIContent("96x96", "Select the proper resolution for your tiles."), 25 | new GUIContent("128x128", "Select the proper resolution for your tiles.") 26 | //new GUIContent("192x192", "The resolution of each tile."), 27 | //new GUIContent("256x256", "The resolution of each tile.") 28 | }; 29 | 30 | // Scroll view 31 | private Vector2 m_scrollPos; 32 | private Rect m_controlRect; 33 | private Texture2D m_tileTexture; 34 | 35 | // GUIContents 36 | private readonly GUIContent[] m_guiContent = new[] 37 | { 38 | new GUIContent("Tile Size", "The tiles resolution."), 39 | new GUIContent("Atlas Texture:", "The source tileset texture with all the tiles that should be converted and added to this palette."), 40 | new GUIContent("Grid Offset", "The offset between each tile in the atlas texture."), 41 | new GUIContent("Convert Atlas to Tiles Temporary", "Convert the atlas texture to single tiles temporary. By pressing this, each tile texture will be stored in memory temporarily, so build the 3D Tileset Data to save it permanently as a Texture3D."), 42 | new GUIContent("Convert Atlas to Tiles", "Convert the atlas texture to single tile assets. By pressing this, each tile texture will be saved separately as .asset into this Palette"), 43 | new GUIContent("Remove Tiles", "Remove all the tiles from this Palette"), 44 | new GUIContent("Reset", "Reset this Palette to the default settings."), 45 | new GUIContent("Extract Number", "The max number of tiles in the atlas texture that you want to extract and convert to tiles."), 46 | new GUIContent("", "Make sure the import settings option (Non-Power of Two) of the atlas texture is set to 'None'. Otherwise this may cause some issues when extracting the tiles.") 47 | }; 48 | 49 | // Temporary 50 | private int m_tileSize = 32; 51 | 52 | // Serialized properties 53 | private SerializedProperty m_gridOffset; 54 | private SerializedProperty m_atlasTexture; 55 | private SerializedProperty m_extractNumber; 56 | 57 | private void OnEnable() 58 | { 59 | // Get Target 60 | m_target = (TilePalette) target; 61 | 62 | // Find the serialized properties 63 | m_gridOffset = serializedObject.FindProperty("gridOffset"); 64 | m_atlasTexture = serializedObject.FindProperty("atlasTexture"); 65 | m_extractNumber = serializedObject.FindProperty("extractNumber"); 66 | } 67 | 68 | public override void OnInspectorGUI() 69 | { 70 | // Start custom Inspector 71 | serializedObject.Update(); 72 | EditorGUI.BeginChangeCheck(); 73 | 74 | // Reset button 75 | m_controlRect = EditorGUILayout.GetControlRect(); 76 | if (GUI.Button(new Rect(m_controlRect.width - 73, -26, 45, 18), m_guiContent[6])) 77 | m_target.ResetAsset(); 78 | GUILayout.Space(-20); 79 | 80 | // Settings section 81 | EditorGUILayout.LabelField("Settings", (GUIStyle)"DD Background"); // (GUIStyle)"SelectionRect", (GUIStyle)"dockareaStandalone" 82 | GUILayout.Space(-4); 83 | 84 | // Tile size popup 85 | EditorGUILayout.BeginHorizontal("Box"); 86 | m_tileSize = EditorGUILayout.IntPopup(m_guiContent[0], m_target.tileSize, m_tileSizeContentArray, m_tileSizeArray); 87 | EditorGUILayout.EndHorizontal(); 88 | 89 | // Conversion section 90 | EditorGUILayout.LabelField("Conversion", (GUIStyle)"DD Background"); // (GUIStyle)"ObjectPickerResultsEven", (GUIStyle)"LODSliderRangeSelected" 91 | GUILayout.Space(-4); 92 | 93 | // Texture field for the diffuse tileset atlas 94 | EditorGUILayout.BeginVertical("Box"); 95 | EditorGUILayout.HelpBox(m_guiContent[8].tooltip, MessageType.Info); 96 | GUI.color = m_greenColor; 97 | if (!m_atlasTexture.objectReferenceValue) GUI.color = m_redColor; 98 | EditorGUILayout.PropertyField(m_atlasTexture, m_guiContent[1]); 99 | GUI.color = Color.white; 100 | 101 | // Grid offset 102 | EditorGUILayout.PropertyField(m_gridOffset, m_guiContent[2]); 103 | 104 | // Extract number 105 | EditorGUILayout.PropertyField(m_extractNumber, m_guiContent[7]); 106 | 107 | // Button to convert the atlas texture to separate tiles and save it as .asset file 108 | if (GUILayout.Button(m_guiContent[4])) 109 | m_target.ConvertAtlasToTiles(); 110 | 111 | // Delete tile assets button 112 | if (GUILayout.Button(m_guiContent[5])) 113 | m_target.DeleteTiles(); 114 | EditorGUILayout.EndVertical(); 115 | 116 | // Tileset data section 117 | EditorGUILayout.LabelField("Tileset Data", (GUIStyle)"DD Background"); 118 | GUILayout.Space(-4); 119 | 120 | // Build 3D tileset data 121 | EditorGUILayout.BeginVertical("Box"); 122 | //if (GUILayout.Button(m_guiContent[6])) 123 | // m_target.BuildDiffuseTilesetData(); 124 | 125 | // Tile grid 126 | m_scrollPos = EditorGUILayout.BeginScrollView(m_scrollPos); 127 | EditorGUILayout.LabelField("", GUILayout.Width(442)); 128 | GUILayout.Space(-20); 129 | 130 | for (int vertical = 0; vertical < 256;) 131 | { 132 | m_controlRect = EditorGUILayout.GetControlRect(GUILayout.Width(24), GUILayout.Height(24)); 133 | 134 | EditorGUILayout.BeginHorizontal(); 135 | for (int horizontal = 0; horizontal < 16; horizontal++) 136 | { 137 | m_tileTexture = m_target.temporaryTileTextureArray[vertical] ? m_target.temporaryTileTextureArray[vertical] : emptyIconTexture; 138 | GUI.DrawTexture(m_controlRect, m_tileTexture, ScaleMode.StretchToFill, true, 0); 139 | m_controlRect.x += 28; 140 | vertical++; 141 | } 142 | EditorGUILayout.EndHorizontal(); 143 | } 144 | EditorGUILayout.EndScrollView(); 145 | EditorGUILayout.EndVertical(); 146 | 147 | EditorGUILayout.BeginHorizontal(); 148 | GUILayout.Label("Used Slots: " + m_target.tilesCount.ToString()); 149 | GUILayout.FlexibleSpace(); 150 | GUILayout.Label("Free Slots: " + (256 - m_target.tilesCount).ToString()); 151 | EditorGUILayout.EndHorizontal(); 152 | 153 | // End custom Inspector 154 | if (EditorGUI.EndChangeCheck()) 155 | { 156 | Undo.RecordObject(m_target, "3D Tilemap System"); 157 | serializedObject.ApplyModifiedProperties(); 158 | m_target.tileSize = m_tileSize; 159 | } 160 | } 161 | } -------------------------------------------------------------------------------- /3D Tilemap System/Editor/TilePaletteInspector.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 44e4a828a180a61498a5cceab31ea61c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: 7 | - emptyIconTexture: {fileID: 2800000, guid: 0358aeafcbe8c9e429e2b389a3241997, type: 3} 8 | - textureMaterial: {fileID: 2100000, guid: 5830696a4369cb74bb93cdd2721b0c24, type: 2} 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /3D Tilemap System/Editor/TilemapSystemInspector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEditor; 5 | using UnityEditorInternal; 6 | using UnityEngine.TilemapSystem3D; 7 | 8 | [CustomEditor(typeof(TilemapSystem3D))] 9 | public class TilemapSystemInspector : Editor 10 | { 11 | // The target script 12 | private TilemapSystem3D m_target; 13 | 14 | // Editor only 15 | public Texture2D emptyIconTexture; 16 | public TilePalette blobAutoTileLayout; 17 | private Texture2D m_layerIconTexture; 18 | private readonly Color m_greenColor = new Color(0.85f, 1.0f, 0.85f); 19 | private readonly Color m_redColor = new Color(1.0f, 0.75f, 0.75f); 20 | private readonly Color m_selectedTileColor = new Color(0.25f, 0.25f, 0.25f, 0.5f); 21 | private Texture[] m_paintingToolIcons; 22 | private bool m_isPicking, m_isPainting, m_isFilling, m_isErasing; 23 | private bool m_isPaintingEvent; 24 | private readonly int[] m_tilesetSizeArray = new[] {16, 24, 32, 48, 64, 96, 128}; 25 | private string[] m_autoTileElements; 26 | private readonly GUIContent[] m_tilesetSizeContentArray = new GUIContent[] 27 | { 28 | new GUIContent("16x16", "The resolution of the 3D Tileset texture."), 29 | new GUIContent("24x24", "The resolution of the 3D Tileset texture."), 30 | new GUIContent("32x32", "The resolution of the 3D Tileset texture."), 31 | new GUIContent("48x48", "The resolution of the 3D Tileset texture."), 32 | new GUIContent("64x64", "The resolution of the 3D Tileset texture."), 33 | new GUIContent("96x96", "The resolution of the 3D Tileset texture."), 34 | new GUIContent("128x128", "The resolution of the 3D Tileset texture.") 35 | //new GUIContent("192x192", "The resolution of each tile."), 36 | //new GUIContent("256x256", "The resolution of each tile.") 37 | }; 38 | 39 | // Tile grid 40 | private int m_buttonIndex; 41 | private bool m_isSelected; 42 | private Vector2 m_scrollPos, m_autoTileScrollPos; 43 | private Rect m_controlRect; 44 | private Texture2D m_tileTexture; 45 | 46 | // GUIContents 47 | private readonly GUIContent[] m_guiContent = new[] 48 | { 49 | new GUIContent("Grid Map Size:", "The size of the 3D Tilemap texture. It should be proportional to the terrain size or mesh uv."), 50 | new GUIContent("Width", "The width of tilemap texture."), 51 | new GUIContent("Height", "The height of tilemap texture."), 52 | new GUIContent("Tilemap Layers", "List of layers that will be used in this tilemap."), 53 | new GUIContent("Paint Layer", "Select the layer for painting."), 54 | new GUIContent("Tile Palette", "The profile containing the tiles palette."), 55 | new GUIContent("Tilemap Data", "Reference to the tilemap data, it is usually created automatically by pressing the button below. It stores the tilemap texture and the render material."), 56 | new GUIContent("Legacy Shader", "Diffuse shader used by the Legacy Render Pipeline."), 57 | new GUIContent("Universal Shader", "Diffuse shader used by the Universal Render Pipeline."), 58 | new GUIContent("Render Pipeline", "Select the render pipeline you are using in this project."), 59 | new GUIContent("Painting Mode", "Select the feature used to paint the tiles."), 60 | new GUIContent("Auto Tile List", "List of auto tile layouts that will be used by this layer."), 61 | new GUIContent("Auto", "Automatically setup the layout using the current tile selected in the palette as starting point."), 62 | new GUIContent("Tilemap Texture", "The 3D texture that stores the tilemap data of each layer used by this component. This data is used by the render material as mask to render on the mesh the proper tile slice of the 3D Tileset texture."), 63 | new GUIContent("Render Material", "The material used to render the tiles on the mesh."), 64 | new GUIContent("Tileset Texture", "The 3D texture that stores all the tiles used by this component."), 65 | new GUIContent("Tileset Size", "The resolution of the 3D Tileset texture."), 66 | new GUIContent("Layout", "Select the layout index that you want to paint."), 67 | new GUIContent("Donate", "Make a donation to support the asset developer."), 68 | new GUIContent("Azure[Sky] Dynamic Skybox", "Complete sky system with day-night cycle and weather solution."), 69 | new GUIContent("Azure[Sky] Lite", "A lite version of Azure[Sky] Dynamic Skybox with less features and best performance.") 70 | }; 71 | 72 | // Temporary 73 | private Vector4 m_gridMapSize = new Vector4(32, 32, 1, 1); 74 | 75 | // Serialized properties 76 | private SerializedProperty m_showReferencesGroup; 77 | private SerializedProperty m_showSettingsGroup; 78 | private SerializedProperty m_showDataGroup; 79 | private SerializedProperty m_showPantingGroup; 80 | private SerializedProperty m_showAutoTileGroup; 81 | private SerializedProperty m_showRandomTilePaintingGroup; 82 | private SerializedProperty m_showRandomizeTileGroup; 83 | private SerializedProperty m_showTileBrushesGroup; 84 | private SerializedProperty m_showAboutGroup; 85 | private SerializedProperty m_legacyShader; 86 | private SerializedProperty m_universalShader; 87 | private SerializedProperty m_tilemapData; 88 | private SerializedProperty m_tilePalette; 89 | private SerializedProperty m_renderPipeline; 90 | private SerializedProperty m_tilesetSize; 91 | private SerializedProperty m_paintingMode; 92 | private SerializedProperty m_autoTileLayoutIndex; 93 | 94 | // Reorderable lists 95 | private SerializedProperty m_tilemapLayerList; 96 | private ReorderableList m_reorderableTilemapLayerList; 97 | private readonly Dictionary m_autoTileDictionary = new Dictionary(); 98 | 99 | private void OnDisable() 100 | { 101 | // Shows the editor tools again 102 | Tools.hidden = false; 103 | m_target.toolIndex = 0; 104 | } 105 | 106 | private void OnEnable() 107 | { 108 | // Get Target 109 | m_target = (TilemapSystem3D) target; 110 | 111 | // Refresh the render material 112 | if (m_target.tilemapData) 113 | m_target.UpdateRenderMaterial(); 114 | 115 | // Update layer intensity 116 | m_target.UpdateLayerSettings(); 117 | 118 | // Find the serialized properties 119 | m_showReferencesGroup = serializedObject.FindProperty("showReferencesGroup"); 120 | m_showSettingsGroup = serializedObject.FindProperty("showSettingsGroup"); 121 | m_showDataGroup = serializedObject.FindProperty("showDataGroup"); 122 | m_showPantingGroup = serializedObject.FindProperty("showPantingGroup"); 123 | m_showAutoTileGroup = serializedObject.FindProperty("showAutoTileGroup"); 124 | m_showRandomTilePaintingGroup = serializedObject.FindProperty("showRandomTilePaintingGroup"); 125 | m_showRandomizeTileGroup = serializedObject.FindProperty("showRandomizeTileGroup"); 126 | m_showTileBrushesGroup = serializedObject.FindProperty("showTileBrushesGroup"); 127 | m_showAboutGroup = serializedObject.FindProperty("showAboutGroup"); 128 | m_legacyShader = serializedObject.FindProperty("legacyShader"); 129 | m_universalShader = serializedObject.FindProperty("universalShader"); 130 | m_tilemapData = serializedObject.FindProperty("tilemapData"); 131 | m_renderPipeline = serializedObject.FindProperty("renderPipeline"); 132 | m_tilesetSize = serializedObject.FindProperty("tilesetSize"); 133 | m_paintingMode = serializedObject.FindProperty("paintingMode"); 134 | 135 | m_paintingToolIcons = new[] 136 | { 137 | EditorGUIUtility.FindTexture("Grid.PickingTool"), 138 | EditorGUIUtility.FindTexture("Grid.PaintTool"), 139 | EditorGUIUtility.FindTexture("Grid.FillTool"), 140 | EditorGUIUtility.FindTexture("Grid.EraserTool") 141 | }; 142 | 143 | // Layer list 144 | m_tilemapLayerList = serializedObject.FindProperty("tilemapLayerList"); 145 | m_reorderableTilemapLayerList = new ReorderableList(serializedObject, m_tilemapLayerList, false, true, true, true) 146 | { 147 | drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => 148 | { 149 | // Initialize 150 | var element = m_reorderableTilemapLayerList.serializedProperty.GetArrayElementAtIndex(index); 151 | 152 | // Draw the image icon 153 | if(m_target.tilemapLayerList[index].tilePalette) 154 | m_layerIconTexture = m_target.tilemapLayerList[index].tilePalette.temporaryTileTextureArray[1]; 155 | if (m_layerIconTexture == null) m_layerIconTexture = emptyIconTexture; 156 | GUI.DrawTexture(new Rect(rect.x, rect.y + 2, 38, 38), m_layerIconTexture, ScaleMode.StretchToFill, true, 0); 157 | m_layerIconTexture = null; 158 | 159 | // Draw the name field 160 | EditorGUI.PropertyField(new Rect(rect.x + 42, rect.y + 1, rect.width - 85, 18), element.FindPropertyRelative("layerName"), GUIContent.none); 161 | 162 | // Draw the alpha intensity slider 163 | EditorGUI.Slider(new Rect(rect.x + 42, rect.y + 22, rect.width - 85, 18), element.FindPropertyRelative("intensity"), 0.0f, 1.0f, GUIContent.none); 164 | 165 | // Copy button 166 | if (GUI.Button(new Rect(rect.width - 18, rect.y + 1, 22, 41), "C")) 167 | { 168 | m_target.CopyTilemapLayer(index); 169 | } 170 | 171 | // Paste button 172 | if (GUI.Button(new Rect(rect.width + 4, rect.y + 1, 22, 41), "P")) 173 | { 174 | m_target.PasteTilemapLayer(index); 175 | } 176 | 177 | // Create the reorderable auto tile list for this layer and save it to the dictionary 178 | if (!m_autoTileDictionary.ContainsKey(index)) 179 | { 180 | m_autoTileDictionary[index] = CreateAutoTileList(element.FindPropertyRelative("autoTileList")); 181 | } 182 | }, 183 | 184 | onAddCallback = (ReorderableList l) => 185 | { 186 | var index = l.serializedProperty.arraySize; 187 | ReorderableList.defaultBehaviours.DoAddButton(l); 188 | var element = l.serializedProperty.GetArrayElementAtIndex(index); 189 | element.FindPropertyRelative("layerName").stringValue = "Layer " + index; 190 | element.FindPropertyRelative("intensity").floatValue = 1.0f; 191 | element.FindPropertyRelative("tilePalette").objectReferenceValue = null; 192 | element.FindPropertyRelative("autoTileList").ClearArray(); 193 | ResetAutoTileArrayMap(element.FindPropertyRelative("autoTileMapArray")); 194 | }, 195 | 196 | onRemoveCallback = (ReorderableList l) => 197 | { 198 | m_target.layerIndex--; 199 | ReorderableList.defaultBehaviours.DoRemoveButton(l); 200 | }, 201 | 202 | drawHeaderCallback = (Rect rect) => 203 | { 204 | EditorGUI.LabelField(rect, m_guiContent[3], EditorStyles.boldLabel); 205 | }, 206 | 207 | elementHeightCallback = (int index) => 44, 208 | 209 | drawElementBackgroundCallback = (rect, index, active, focused) => 210 | { 211 | if (active) 212 | GUI.Box(new Rect(rect.x +2, rect.y -1, rect.width -4, rect.height +1), "","selectionRect"); 213 | } 214 | }; 215 | 216 | if (m_reorderableTilemapLayerList.count > 0) 217 | m_reorderableTilemapLayerList.index = 0; 218 | } 219 | 220 | /// 221 | /// Custom Inspector 222 | /// 223 | public override void OnInspectorGUI() 224 | { 225 | // Start custom Inspector 226 | serializedObject.Update(); 227 | EditorGUI.BeginChangeCheck(); 228 | m_target.layerIndex = m_reorderableTilemapLayerList.index; 229 | 230 | if (m_target.toolIndex > 0 && m_target.toolIndex < 5) 231 | Tools.hidden = true; 232 | else 233 | Tools.hidden = false; 234 | // 235 | // References 236 | // 237 | m_showReferencesGroup.isExpanded = EditorGUILayout.BeginFoldoutHeaderGroup(m_showReferencesGroup.isExpanded , "References"); 238 | if (m_showReferencesGroup.isExpanded) 239 | { 240 | GUILayout.Space(1); 241 | // Standard diffuse shader 242 | GUI.color = m_greenColor; 243 | if (!m_legacyShader.objectReferenceValue) GUI.color = m_redColor; 244 | EditorGUILayout.PropertyField(m_legacyShader, m_guiContent[7]); 245 | 246 | // Universal diffuse shader 247 | GUI.color = m_greenColor; 248 | if (!m_universalShader.objectReferenceValue) GUI.color = m_redColor; 249 | EditorGUILayout.PropertyField(m_universalShader, m_guiContent[8]); 250 | GUI.color = Color.white; 251 | } 252 | EditorGUILayout.EndFoldoutHeaderGroup(); 253 | // 254 | // Settings 255 | // 256 | m_showSettingsGroup.isExpanded = EditorGUILayout.BeginFoldoutHeaderGroup(m_showSettingsGroup.isExpanded , "Settings"); 257 | if (m_showSettingsGroup.isExpanded) 258 | { 259 | GUILayout.Space(1); 260 | // Render pipeline 261 | EditorGUILayout.PropertyField(m_renderPipeline, m_guiContent[9]); 262 | if(m_target.renderPipeline == TilemapSystemPipeline.Universal) 263 | EditorGUILayout.HelpBox("Universal Render Pipeline is still a work in progress and is not fully functional.", MessageType.Info); 264 | 265 | // Tilemap size 266 | EditorGUILayout.IntPopup(m_tilesetSize, m_tilesetSizeContentArray, m_tilesetSizeArray, m_guiContent[16]); 267 | 268 | // Grid size 269 | EditorGUILayout.BeginVertical("Box"); 270 | EditorGUILayout.LabelField(m_guiContent[0]); 271 | m_gridMapSize.x = EditorGUILayout.IntField(m_guiContent[1], (int)m_target.gridMapSize.x); 272 | m_gridMapSize.y = EditorGUILayout.IntField(m_guiContent[2], (int)m_target.gridMapSize.y); 273 | EditorGUILayout.EndVertical(); 274 | 275 | // Layer list 276 | m_reorderableTilemapLayerList.DoLayoutList(); 277 | } 278 | EditorGUILayout.EndFoldoutHeaderGroup(); 279 | // 280 | // Data 281 | // 282 | m_showDataGroup.isExpanded = EditorGUILayout.BeginFoldoutHeaderGroup(m_showDataGroup.isExpanded , "Data"); 283 | if (m_showDataGroup.isExpanded) 284 | { 285 | GUILayout.Space(1); 286 | if (m_reorderableTilemapLayerList.count > 0) 287 | { 288 | EditorGUI.BeginDisabledGroup(true); 289 | // Tilemap data 290 | if (!m_tilemapData.objectReferenceValue) GUI.color = m_redColor; 291 | EditorGUI.ObjectField(EditorGUILayout.GetControlRect(), m_tilemapData, m_guiContent[6]); 292 | GUI.color = Color.white; 293 | // Tilemap texture field 294 | if (!m_target.tilemapTexture) GUI.color = m_redColor; 295 | EditorGUI.ObjectField(EditorGUILayout.GetControlRect(), m_guiContent[13], m_target.tilemapTexture, typeof(Texture3D), false); 296 | GUI.color = Color.white; 297 | // Tileset texture field 298 | if (!m_target.tilesetTexture) GUI.color = m_redColor; 299 | EditorGUI.ObjectField(EditorGUILayout.GetControlRect(), m_guiContent[15], m_target.tilesetTexture, typeof(Texture3D), false); 300 | GUI.color = Color.white; 301 | // Array texture field 302 | if (!m_target.layerArrayTexture) GUI.color = m_redColor; 303 | EditorGUI.ObjectField(EditorGUILayout.GetControlRect(), m_guiContent[17], m_target.layerArrayTexture, typeof(Texture2D), false); 304 | GUI.color = Color.white; 305 | // Render material field 306 | if (!m_target.renderMaterial) GUI.color = m_redColor; 307 | EditorGUI.ObjectField(EditorGUILayout.GetControlRect(), m_guiContent[14], m_target.renderMaterial, typeof(Material), false); 308 | GUI.color = Color.white; 309 | EditorGUI.EndDisabledGroup(); 310 | 311 | // Button 312 | if (GUILayout.Button("Generate Tilemap Data")) 313 | { 314 | m_target.GenerateTilemapData(); 315 | if (m_target.tilemapData) 316 | { 317 | TilePalette[] palettes = new TilePalette[m_target.tilemapLayerList.Count]; 318 | int[] tilesCount = new int[m_target.tilemapLayerList.Count]; 319 | for (int i = 0; i < palettes.Length; i++) 320 | { 321 | palettes[i] = m_target.tilemapLayerList[i].tilePalette; 322 | if (palettes[i]) 323 | tilesCount[i] = m_target.tilemapLayerList[i].tilePalette.tilesCount; 324 | else 325 | tilesCount[i] = 0; 326 | } 327 | 328 | m_target.tilemapData.settingsState = new TilemapSettings(m_target.tilemapLayerList.Count, tilesCount, palettes, (int) m_gridMapSize.x, (int) m_gridMapSize.y, m_tilesetSize.intValue); 329 | m_target.tilemapData.layerIntensity = new float[m_target.tilemapLayerList.Count]; 330 | } 331 | } 332 | } 333 | else 334 | EditorGUILayout.HelpBox("There is no layer created yet! Create a tilemap layer.", MessageType.Error); 335 | } 336 | EditorGUILayout.EndFoldoutHeaderGroup(); 337 | // 338 | // Painting 339 | // 340 | m_showPantingGroup.isExpanded = EditorGUILayout.BeginFoldoutHeaderGroup(m_showPantingGroup.isExpanded , "Painting"); 341 | if (m_showPantingGroup.isExpanded) 342 | { 343 | if (m_reorderableTilemapLayerList.count > 0 && m_target.layerIndex >= 0 && m_target.tilemapLayerList.Count > 0) 344 | { 345 | if (m_tilemapData.objectReferenceValue) 346 | { 347 | // Tile palette field 348 | EditorGUILayout.BeginVertical("Box"); 349 | m_tilePalette = m_reorderableTilemapLayerList.serializedProperty.GetArrayElementAtIndex(m_target.layerIndex).FindPropertyRelative("tilePalette"); 350 | GUI.color = m_greenColor; 351 | if (!m_tilePalette.objectReferenceValue) GUI.color = m_redColor; 352 | EditorGUILayout.PropertyField(m_tilePalette, m_guiContent[5]); 353 | GUI.color = Color.white; 354 | EditorGUILayout.EndVertical(); 355 | 356 | if (m_target.tilemapLayerList[m_target.layerIndex].tilePalette) 357 | { 358 | // Painting mode 359 | EditorGUILayout.BeginVertical("Box"); 360 | EditorGUILayout.PropertyField(m_paintingMode, m_guiContent[10]); 361 | 362 | // Auto tile layout popup 363 | if (m_target.paintingMode == TilemapSystemPaintingMode.AutoTiles) 364 | { 365 | m_autoTileElements = GetAutoTileElements(); 366 | 367 | if (m_autoTileElements.Length > 0) 368 | { 369 | m_autoTileLayoutIndex = m_reorderableTilemapLayerList.serializedProperty.GetArrayElementAtIndex(m_target.layerIndex).FindPropertyRelative("layoutIndex"); 370 | m_autoTileLayoutIndex.intValue = EditorGUILayout.Popup(m_guiContent[17], m_autoTileLayoutIndex.intValue, m_autoTileElements); 371 | } 372 | else 373 | { 374 | EditorGUILayout.HelpBox("The Auto Tile list is empty. Please, set some auto tile layout first.", MessageType.Error); 375 | } 376 | } 377 | EditorGUILayout.EndVertical(); 378 | GUILayout.Space(-3); 379 | 380 | if (m_target.tilemapLayerList[m_target.layerIndex].tilePalette.tilesCount > 0) 381 | { 382 | EditorGUILayout.BeginVertical("Box"); 383 | if (m_target.tilesetTexture) 384 | { 385 | if (CanPaint()) 386 | { 387 | // Reset layer button 388 | if (GUILayout.Button("Reset This Layer Using the Selected Tile")) 389 | { 390 | // Register the texture in the undo stack 391 | Undo.RegisterCompleteObjectUndo(m_target.tilemapTexture, "Tilemap Change"); 392 | m_target.ResetLayer(m_target.layerIndex); 393 | } 394 | 395 | // Toolbar 396 | EditorGUILayout.BeginHorizontal(); 397 | m_isPicking = m_target.toolIndex == 1 ? true : false; 398 | if (GUILayout.Toggle(m_isPicking, m_paintingToolIcons[0], EditorStyles.miniButtonLeft)) 399 | m_target.toolIndex = 1; 400 | else if (m_target.toolIndex == 1) 401 | m_target.toolIndex = 0; 402 | 403 | m_isPainting = m_target.toolIndex == 2 ? true : false; 404 | if (GUILayout.Toggle(m_isPainting, m_paintingToolIcons[1], EditorStyles.miniButtonMid)) 405 | m_target.toolIndex = 2; 406 | else if (m_target.toolIndex == 2) 407 | m_target.toolIndex = 0; 408 | 409 | m_isFilling = m_target.toolIndex == 3 ? true : false; 410 | if (GUILayout.Toggle(m_isFilling, m_paintingToolIcons[2], EditorStyles.miniButtonMid)) 411 | m_target.toolIndex = 3; 412 | else if (m_target.toolIndex == 3) 413 | m_target.toolIndex = 0; 414 | 415 | m_isErasing = m_target.toolIndex == 4 ? true : false; 416 | if (GUILayout.Toggle(m_isErasing, m_paintingToolIcons[3], EditorStyles.miniButtonRight)) 417 | m_target.toolIndex = 4; 418 | else if (m_target.toolIndex == 4) 419 | m_target.toolIndex = 0; 420 | EditorGUILayout.EndHorizontal(); 421 | } 422 | else 423 | EditorGUILayout.HelpBox("It looks like you have changed some settings. Please, regenerate the Tilemap Data to update the 3D Textures.", MessageType.Error); 424 | } 425 | else 426 | EditorGUILayout.HelpBox("There is no Tileset Texture yet. Please, regenerate the Tilemap Data again to create the 3D Tileset texture so you can start painting.", MessageType.Error); 427 | 428 | // Tile grid 429 | m_scrollPos = EditorGUILayout.BeginScrollView(m_scrollPos); 430 | EditorGUILayout.LabelField("", GUILayout.Width(442)); 431 | GUILayout.Space(-20); 432 | m_buttonIndex = 0; 433 | 434 | // Start the selectable loop 435 | for (int vertical = 0; vertical < 256;) 436 | { 437 | m_controlRect = EditorGUILayout.GetControlRect(GUILayout.Width(24), GUILayout.Height(24)); 438 | 439 | EditorGUILayout.BeginHorizontal(); 440 | for (int horizontal = 0; horizontal < 16; horizontal++) 441 | { 442 | // Get the tile texture 443 | m_tileTexture = m_target.tilemapLayerList[m_target.layerIndex].tilePalette.temporaryTileTextureArray[vertical] ? m_target.tilemapLayerList[m_target.layerIndex].tilePalette.temporaryTileTextureArray[vertical] : emptyIconTexture; 444 | 445 | // Draw the selectable button 446 | m_isSelected = m_target.tileIndex == m_buttonIndex ? true : false; 447 | if (GUI.Toggle(m_controlRect, m_isSelected, GUIContent.none, GUI.skin.button)) 448 | { 449 | m_target.tileIndex = m_buttonIndex; 450 | } 451 | 452 | // Draw the tile texture 453 | if (m_isSelected) GUI.color = m_selectedTileColor; 454 | GUI.DrawTexture(m_controlRect, m_tileTexture, ScaleMode.StretchToFill, true, 0); 455 | GUI.color = Color.white; 456 | 457 | m_controlRect.x += 28; 458 | vertical++; 459 | m_buttonIndex++; 460 | } 461 | 462 | EditorGUILayout.EndHorizontal(); 463 | } 464 | 465 | EditorGUILayout.EndScrollView(); 466 | EditorGUILayout.EndVertical(); 467 | } 468 | else 469 | EditorGUILayout.HelpBox("The Tile Palette used in this layer is empty. Please, add the tiles to the Tile Palette first.", MessageType.Error); 470 | } 471 | else 472 | EditorGUILayout.HelpBox("The tile palette of this layer is missing! Add a Tile Palette to start painting.", MessageType.Error); 473 | } 474 | else 475 | EditorGUILayout.HelpBox("There is no tilemap data created yet! Generate the Tilemap Data.", MessageType.Error); 476 | } 477 | else 478 | EditorGUILayout.HelpBox("There is no layer created yet! Create a tilemap layer.", MessageType.Error); 479 | 480 | 481 | } 482 | EditorGUILayout.EndFoldoutHeaderGroup(); 483 | // 484 | // Auto tiles 485 | // 486 | m_showAutoTileGroup.isExpanded = EditorGUILayout.BeginFoldoutHeaderGroup(m_showAutoTileGroup.isExpanded , "Auto Tiles"); 487 | if (m_showAutoTileGroup.isExpanded) 488 | { 489 | if (m_reorderableTilemapLayerList.count > 0 && m_target.layerIndex >= 0 && m_target.tilemapLayerList.Count > 0) 490 | { 491 | if (m_tilemapData.objectReferenceValue) 492 | { 493 | if (m_target.tilemapLayerList[m_target.layerIndex].tilePalette) 494 | { 495 | if (m_target.tilemapLayerList[m_target.layerIndex].tilePalette.tilesCount > 0) 496 | { 497 | // Editor stuff here 498 | GUILayout.Space(3); 499 | m_autoTileDictionary[m_target.layerIndex].DoLayoutList(); 500 | } 501 | else 502 | EditorGUILayout.HelpBox("The Tile Palette used in this layer is empty. Please, add the tiles to the Tile Palette first.", MessageType.Error); 503 | } 504 | else 505 | EditorGUILayout.HelpBox("The tile palette of this layer is missing! Add a Tile Palette to start painting.", MessageType.Error); 506 | } 507 | else 508 | EditorGUILayout.HelpBox("There is no tilemap data created yet! Generate the Tilemap Data.", MessageType.Error); 509 | } 510 | else 511 | EditorGUILayout.HelpBox("There is no layer created yet! Create a tilemap layer.", MessageType.Error); 512 | } 513 | EditorGUILayout.EndFoldoutHeaderGroup(); 514 | // 515 | // Random tile painting 516 | // 517 | EditorGUI.BeginDisabledGroup(true); 518 | m_showRandomTilePaintingGroup.isExpanded = EditorGUILayout.BeginFoldoutHeaderGroup(m_showRandomTilePaintingGroup.isExpanded , "Random Tile Painting"); 519 | if (m_showRandomTilePaintingGroup.isExpanded) 520 | { 521 | if (m_reorderableTilemapLayerList.count > 0 && m_target.layerIndex >= 0 && m_target.tilemapLayerList.Count > 0) 522 | { 523 | if (m_tilemapData.objectReferenceValue) 524 | { 525 | if (m_target.tilemapLayerList[m_target.layerIndex].tilePalette) 526 | { 527 | if (m_target.tilemapLayerList[m_target.layerIndex].tilePalette.tilesCount > 0) 528 | { 529 | // Editor stuff here 530 | } 531 | else 532 | EditorGUILayout.HelpBox("The Tile Palette used in this layer is empty. Please, add the tiles to the Tile Palette first.", MessageType.Error); 533 | } 534 | else 535 | EditorGUILayout.HelpBox("The tile palette of this layer is missing! Add a Tile Palette to start painting.", MessageType.Error); 536 | } 537 | else 538 | EditorGUILayout.HelpBox("There is no tilemap data created yet! Generate the Tilemap Data.", MessageType.Error); 539 | } 540 | else 541 | EditorGUILayout.HelpBox("There is no layer created yet! Create a tilemap layer.", MessageType.Error); 542 | } 543 | EditorGUILayout.EndFoldoutHeaderGroup(); 544 | 545 | // Random tiles 546 | m_showRandomizeTileGroup.isExpanded = EditorGUILayout.BeginFoldoutHeaderGroup(m_showRandomizeTileGroup.isExpanded , "Randomize Tiles"); 547 | if (m_showRandomizeTileGroup.isExpanded) 548 | { 549 | if (m_reorderableTilemapLayerList.count > 0 && m_target.layerIndex >= 0 && m_target.tilemapLayerList.Count > 0) 550 | { 551 | if (m_tilemapData.objectReferenceValue) 552 | { 553 | if (m_target.tilemapLayerList[m_target.layerIndex].tilePalette) 554 | { 555 | if (m_target.tilemapLayerList[m_target.layerIndex].tilePalette.tilesCount > 0) 556 | { 557 | // Editor stuff here 558 | } 559 | else 560 | EditorGUILayout.HelpBox("The Tile Palette used in this layer is empty. Please, add the tiles to the Tile Palette first.", MessageType.Error); 561 | } 562 | else 563 | EditorGUILayout.HelpBox("The tile palette of this layer is missing! Add a Tile Palette to start painting.", MessageType.Error); 564 | } 565 | else 566 | EditorGUILayout.HelpBox("There is no tilemap data created yet! Generate the Tilemap Data.", MessageType.Error); 567 | } 568 | else 569 | EditorGUILayout.HelpBox("There is no layer created yet! Create a tilemap layer.", MessageType.Error); 570 | } 571 | EditorGUILayout.EndFoldoutHeaderGroup(); 572 | 573 | // Tile brushes 574 | m_showTileBrushesGroup.isExpanded = EditorGUILayout.BeginFoldoutHeaderGroup(m_showTileBrushesGroup.isExpanded , "Tile Brushes"); 575 | if (m_showTileBrushesGroup.isExpanded) 576 | { 577 | if (m_reorderableTilemapLayerList.count > 0 && m_target.layerIndex>= 0 && m_target.tilemapLayerList.Count > 0) 578 | { 579 | if (m_tilemapData.objectReferenceValue) 580 | { 581 | if (m_target.tilemapLayerList[m_target.layerIndex].tilePalette) 582 | { 583 | if (m_target.tilemapLayerList[m_target.layerIndex].tilePalette.tilesCount > 0) 584 | { 585 | // Editor stuff here 586 | } 587 | else 588 | EditorGUILayout.HelpBox("The Tile Palette used in this layer is empty. Please, add the tiles to the Tile Palette first.", MessageType.Error); 589 | } 590 | else 591 | EditorGUILayout.HelpBox("The tile palette of this layer is missing! Add a Tile Palette to start painting.", MessageType.Error); 592 | } 593 | else 594 | EditorGUILayout.HelpBox("There is no tilemap data created yet! Generate the Tilemap Data.", MessageType.Error); 595 | } 596 | else 597 | EditorGUILayout.HelpBox("There is no layer created yet! Create a tilemap layer.", MessageType.Error); 598 | } 599 | EditorGUILayout.EndFoldoutHeaderGroup(); 600 | EditorGUI.EndDisabledGroup(); 601 | 602 | // About group 603 | m_showAboutGroup.isExpanded = EditorGUILayout.BeginFoldoutHeaderGroup(m_showAboutGroup.isExpanded, "About"); 604 | if (m_showAboutGroup.isExpanded) 605 | { 606 | EditorGUILayout.HelpBox("3D Tilemap System v1.0.1 by Seven Stars Games", MessageType.None); 607 | if (GUILayout.Button(m_guiContent[18])) 608 | { 609 | Application.OpenURL("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=S8AB7CVH5VMZS&source=url"); 610 | } 611 | EditorGUILayout.Space(); 612 | EditorGUILayout.LabelField("My other assets you may like:"); 613 | if (GUILayout.Button(m_guiContent[19])) 614 | { 615 | Application.OpenURL("https://assetstore.unity.com/packages/tools/particles-effects/azure-sky-dynamic-skybox-36050"); 616 | } 617 | if (GUILayout.Button(m_guiContent[20])) 618 | { 619 | Application.OpenURL("https://assetstore.unity.com/packages/vfx/shaders/azure-sky-lite-89858"); 620 | } 621 | } 622 | 623 | // Update layer intensity when there is a change in the Inspector 624 | if (m_target.tilemapData) 625 | { 626 | if (NeedUpdateLayerIntensity()) 627 | { 628 | m_target.UpdateLayerSettings(); 629 | m_target.tilemapData.layerIntensity = new float[m_target.tilemapLayerList.Count]; 630 | for (int i = 0; i < m_target.tilemapLayerList.Count; i++) 631 | { 632 | m_target.tilemapData.layerIntensity[i] = m_target.tilemapLayerList[i].intensity; 633 | } 634 | } 635 | } 636 | 637 | // End custom Inspector 638 | if (EditorGUI.EndChangeCheck()) 639 | { 640 | Undo.RecordObject(m_target, "3D Tilemap System"); 641 | serializedObject.ApplyModifiedProperties(); 642 | m_target.gridMapSize = m_gridMapSize; 643 | m_target.UpdateMaterialSettings(); 644 | } 645 | } 646 | 647 | /// 648 | /// Editor painting in scene view 649 | /// 650 | private void OnSceneGUI() 651 | { 652 | if ((m_target.toolIndex > 0 || m_target.toolIndex <= 4)) 653 | { 654 | var e = Event.current; 655 | var controlID = GUIUtility.GetControlID(FocusType.Passive); 656 | 657 | if (e.button == 0 && !e.alt && e.type != EventType.MouseMove) 658 | { 659 | switch (e.type) 660 | { 661 | case EventType.MouseDown: 662 | m_isPaintingEvent = true; 663 | if (!m_target.tilemapData) 664 | { 665 | Debug.LogWarning("3D Tilemap System: The tilemap data is missing! Please, first generate the tilemap data to be able to paint the tiles."); 666 | m_isPaintingEvent = false; 667 | e.Use(); 668 | return; 669 | } 670 | break; 671 | 672 | case EventType.Layout: 673 | HandleUtility.AddDefaultControl(controlID); 674 | break; 675 | 676 | case EventType.MouseUp: 677 | m_isPaintingEvent = false; 678 | e.Use(); 679 | break; 680 | } 681 | } 682 | 683 | if (e.alt && m_isPaintingEvent == true) 684 | { 685 | m_isPaintingEvent = false; 686 | } 687 | 688 | if (!m_isPaintingEvent) return; 689 | 690 | var mousePos = e.mousePosition; 691 | var pixelsPerPoint = EditorGUIUtility.pixelsPerPoint; 692 | mousePos.y = SceneView.currentDrawingSceneView.camera.pixelHeight - mousePos.y * pixelsPerPoint; 693 | mousePos.x *= pixelsPerPoint; 694 | 695 | var ray = SceneView.currentDrawingSceneView.camera.ScreenPointToRay(mousePos); 696 | RaycastHit hit; 697 | if (!Physics.Raycast(ray, out hit)) return; 698 | 699 | // Get the uv texture coordinate at the collision location 700 | var hitCoord = hit.textureCoord; 701 | hitCoord.x *= m_target.tilemapTexture.width; 702 | hitCoord.y *= m_target.tilemapTexture.height; 703 | 704 | // Register the texture in the undo stack 705 | Undo.RegisterCompleteObjectUndo(m_target.tilemapTexture, "Tilemap Change"); 706 | 707 | // Pickup the tile 708 | if (m_target.toolIndex == 1) 709 | { 710 | m_target.tileIndex = m_target.PickupTile((int) hitCoord.x, (int) hitCoord.y, m_target.layerIndex); 711 | m_isPaintingEvent = false; 712 | Repaint(); 713 | } 714 | 715 | // Paint the tile 716 | if (m_target.toolIndex == 2 && m_target.paintingMode == TilemapSystemPaintingMode.Default) 717 | m_target.PaintTile((int)hitCoord.x, (int)hitCoord.y, m_target.tileIndex, m_target.layerIndex); 718 | 719 | // Fill the area with the same tile 720 | if (m_target.toolIndex == 3 && m_target.paintingMode == TilemapSystemPaintingMode.Default) 721 | { 722 | m_target.FillTile((int) hitCoord.x, (int) hitCoord.y, m_target.tileIndex, m_target.layerIndex); 723 | m_isPaintingEvent = false; 724 | } 725 | 726 | // Auto tile painting 727 | if (m_target.toolIndex == 2 && m_target.paintingMode == TilemapSystemPaintingMode.AutoTiles) 728 | { 729 | Undo.RecordObject(m_target, "Autotile Change"); 730 | m_target.PaintAutoTile((int) hitCoord.x, (int) hitCoord.y, m_target.tilemapLayerList[m_target.layerIndex].layoutIndex, m_target.layerIndex); 731 | } 732 | 733 | // Erasing the auto tile and regular tile 734 | if (m_target.toolIndex == 4) 735 | { 736 | Undo.RecordObject(m_target, "Autotile Change"); 737 | m_target.EraseAutoTile((int) hitCoord.x, (int) hitCoord.y, m_target.tilemapLayerList[m_target.layerIndex].layoutIndex, m_target.layerIndex); 738 | } 739 | } 740 | } 741 | 742 | /// 743 | /// Create the auto tiles reorderable list. 744 | /// 745 | private ReorderableList CreateAutoTileList (SerializedProperty list) 746 | { 747 | return new ReorderableList(serializedObject, list, false, true, true, true) 748 | { 749 | drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => 750 | { 751 | // Initialize 752 | var element = m_autoTileDictionary[m_target.layerIndex].serializedProperty.GetArrayElementAtIndex(index); 753 | var id = element.FindPropertyRelative("id"); 754 | var isPicked = element.FindPropertyRelative("isPicked"); 755 | var layoutButtonRect = new Rect(rect.x, rect.y, 32, 32); 756 | var layoutImageRect = new Rect(rect.x, rect.y, 32, 32); 757 | var layoutName = element.FindPropertyRelative("name"); 758 | var layoutIconTexture = blobAutoTileLayout.temporaryTileTextureArray[0]; 759 | 760 | // Get the icon texture 761 | if (m_target.tilemapLayerList[m_target.layerIndex].autoTileList.Count > 0) 762 | { 763 | if (m_target.tilemapLayerList[m_target.layerIndex].autoTileList[index].isPicked[0]) 764 | layoutIconTexture = m_target.tilemapLayerList[m_target.layerIndex].tilePalette.temporaryTileTextureArray[id.GetArrayElementAtIndex(0).intValue]; 765 | } 766 | 767 | // Draw the automatic layout button 768 | if (GUI.Button(new Rect(rect.x, rect.y + 2, 48, 16), m_guiContent[12])) 769 | { 770 | for (var i = 0; i < id.arraySize; i++) 771 | { 772 | if (i + m_target.tileIndex < m_target.tilemapLayerList[m_target.layerIndex].tilePalette.tilesCount) 773 | { 774 | id.GetArrayElementAtIndex(i).intValue = i + m_target.tileIndex; 775 | isPicked.GetArrayElementAtIndex(i).boolValue = true; 776 | } 777 | } 778 | } 779 | 780 | // Draw the layout name 781 | layoutName.stringValue = EditorGUI.TextField(new Rect(rect.x + 53, rect.y + 2, rect.width - 53, 16), layoutName.stringValue); 782 | 783 | // Draw the main icon texture 784 | GUI.DrawTexture(new Rect(rect.x, rect.y + 20, 48, 48), layoutIconTexture, ScaleMode.StretchToFill, true, 0); 785 | 786 | // Draw the auto tile layout selector 787 | m_autoTileScrollPos = GUI.BeginScrollView(new Rect(rect.x + 53, rect.y + 20, rect.width - 53, 48), m_autoTileScrollPos, new Rect(rect.x, rect.y, 1598, 34)); 788 | for (var i = 0; i < id.arraySize; i++) 789 | { 790 | // If the pickup button was pressed 791 | if (GUI.Button(layoutButtonRect, GUIContent.none)) 792 | { 793 | if (m_target.tileIndex < m_target.tilemapLayerList[m_target.layerIndex].tilePalette.tilesCount) 794 | { 795 | // Pickup the current tile selected in the grid 796 | id.GetArrayElementAtIndex(i).intValue = m_target.tileIndex; 797 | isPicked.GetArrayElementAtIndex(i).boolValue = !isPicked.GetArrayElementAtIndex(i).boolValue; 798 | } 799 | else 800 | { 801 | id.GetArrayElementAtIndex(i).intValue = 0; 802 | isPicked.GetArrayElementAtIndex(i).boolValue = false; 803 | } 804 | } 805 | 806 | // Set the rect to the next slot 807 | layoutImageRect.x += 2; 808 | layoutImageRect.y += 2; 809 | layoutImageRect.width -= 4; 810 | layoutImageRect.height -= 4; 811 | 812 | // Draw the layout preview texture 813 | if (isPicked.GetArrayElementAtIndex(i).boolValue) 814 | layoutIconTexture = m_target.tilemapLayerList[m_target.layerIndex].tilePalette.temporaryTileTextureArray[id.GetArrayElementAtIndex(i).intValue]; 815 | else 816 | layoutIconTexture = blobAutoTileLayout.temporaryTileTextureArray[i]; 817 | 818 | GUI.DrawTexture(layoutImageRect, layoutIconTexture, ScaleMode.StretchToFill, true, 0); 819 | layoutButtonRect.x += 34; 820 | layoutImageRect = layoutButtonRect; 821 | } 822 | GUI.EndScrollView(); 823 | }, 824 | 825 | onAddCallback = (ReorderableList l) => 826 | { 827 | var index = l.serializedProperty.arraySize; 828 | l.serializedProperty.arraySize++; 829 | 830 | var element = l.serializedProperty.GetArrayElementAtIndex(index); 831 | element.FindPropertyRelative("isPicked").arraySize = 47; 832 | element.FindPropertyRelative("id").arraySize = 47; 833 | element.FindPropertyRelative("name").stringValue = "Auto Tile Layout " + index; 834 | }, 835 | 836 | drawHeaderCallback = (Rect rect) => 837 | { 838 | EditorGUI.LabelField(rect, m_guiContent[11], EditorStyles.boldLabel); 839 | }, 840 | 841 | elementHeightCallback = (int index) => 72, 842 | 843 | drawElementBackgroundCallback = (rect, index, active, focused) => 844 | { 845 | if (active) 846 | GUI.Box(new Rect(rect.x + 2, rect.y - 1, rect.width - 4, rect.height + 1), "", "selectionRect"); 847 | } 848 | }; 849 | } 850 | 851 | /// 852 | /// Check if there is a change in the settings. 853 | /// Use to enable and disable the paint tools. 854 | /// 855 | private bool CanPaint() 856 | { 857 | if (m_target.tilemapData.settingsState.layersCount != m_target.tilemapLayerList.Count) return false; 858 | if (m_target.tilemapData.settingsState.tilemapWidth != (int) m_gridMapSize.x) return false; 859 | if (m_target.tilemapData.settingsState.tilemapHeight != (int) m_gridMapSize.y) return false; 860 | if (m_target.tilemapData.settingsState.tilesetSize != m_tilesetSize.intValue) return false; 861 | 862 | if (m_target.tilemapData.settingsState.layersCount == m_target.tilemapLayerList.Count) 863 | { 864 | for (int i = 0; i < m_target.tilemapLayerList.Count; i++) 865 | { 866 | if (m_target.tilemapData.settingsState.tilePalette[i] != m_target.tilemapLayerList[i].tilePalette) 867 | return false; 868 | if (m_target.tilemapData.settingsState.tilesCount[i] != m_target.tilemapLayerList[i].tilePalette.tilesCount) 869 | return false; 870 | } 871 | } 872 | 873 | return true; 874 | } 875 | 876 | /// 877 | /// Checks if the user changed the alpha intensity of some layer. 878 | /// 879 | private bool NeedUpdateLayerIntensity() 880 | { 881 | if (m_target.tilemapData.layerIntensity.Length == m_target.tilemapLayerList.Count) 882 | { 883 | for (int i = 0; i < m_target.tilemapLayerList.Count; i++) 884 | { 885 | if (Math.Abs(m_target.tilemapData.layerIntensity[i] - m_target.tilemapLayerList[i].intensity) > 0) 886 | return true; 887 | } 888 | } 889 | 890 | return false; 891 | } 892 | 893 | /// 894 | /// Reset the auto tiles array map. 895 | /// 896 | private void ResetAutoTileArrayMap(SerializedProperty array) 897 | { 898 | array.arraySize = (int) (m_target.gridMapSize.x * m_target.gridMapSize.y); 899 | for (int i = 0; i < array.arraySize; i++) 900 | { 901 | //array.GetArrayElementAtIndex(i).intValue = -1; 902 | array.GetArrayElementAtIndex(i).boolValue = false; 903 | } 904 | } 905 | 906 | /// 907 | /// Gets all elements of the auto tile list and returns the string names. 908 | /// 909 | /// 910 | private string[] GetAutoTileElements() 911 | { 912 | string[] temp = new string[m_target.tilemapLayerList[m_target.layerIndex].autoTileList.Count]; 913 | 914 | for (int i = 0; i < temp.Length; i++) 915 | { 916 | temp[i] = m_target.tilemapLayerList[m_target.layerIndex].autoTileList[i].name; 917 | } 918 | 919 | return temp; 920 | } 921 | } -------------------------------------------------------------------------------- /3D Tilemap System/Editor/TilemapSystemInspector.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: db2ce25bf4586784eaaea66b26c9be4b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: 7 | - emptyIconTexture: {fileID: 2800000, guid: 0358aeafcbe8c9e429e2b389a3241997, type: 3} 8 | - blobAutoTileLayout: {fileID: 11400000, guid: 0f025f66865c69240add34b4c61044f6, 9 | type: 2} 10 | executionOrder: 0 11 | icon: {instanceID: 0} 12 | userData: 13 | assetBundleName: 14 | assetBundleVariant: 15 | -------------------------------------------------------------------------------- /3D Tilemap System/Editor/UI.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d5c481d82b2916542bf7a929a3c8fe38 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /3D Tilemap System/Editor/UI/BlobLayout.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0f025f66865c69240add34b4c61044f6 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /3D Tilemap System/Editor/UI/BlobLayout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7StarsGames/3D-Tilemap-System/2abeb86464655ba4046bdf23edde553fd18d1172/3D Tilemap System/Editor/UI/BlobLayout.png -------------------------------------------------------------------------------- /3D Tilemap System/Editor/UI/BlobLayout.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7ab142fb8d99c8543821e75f037133b3 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 10 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 1 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 0 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 3 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | forceMaximumCompressionQuality_BC6H_BC7: 0 73 | - serializedVersion: 3 74 | buildTarget: Standalone 75 | maxTextureSize: 2048 76 | resizeAlgorithm: 0 77 | textureFormat: -1 78 | textureCompression: 1 79 | compressionQuality: 50 80 | crunchedCompression: 0 81 | allowsAlphaSplitting: 0 82 | overridden: 0 83 | androidETC2FallbackOverride: 0 84 | forceMaximumCompressionQuality_BC6H_BC7: 0 85 | spriteSheet: 86 | serializedVersion: 2 87 | sprites: [] 88 | outline: [] 89 | physicsShape: [] 90 | bones: [] 91 | spriteID: 92 | internalID: 0 93 | vertices: [] 94 | indices: 95 | edges: [] 96 | weights: [] 97 | secondaryTextures: [] 98 | spritePackingTag: 99 | pSDRemoveMatte: 0 100 | pSDShowRemoveMatteOption: 0 101 | userData: 102 | assetBundleName: 103 | assetBundleVariant: 104 | -------------------------------------------------------------------------------- /3D Tilemap System/Editor/UI/_DefaultColor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7StarsGames/3D-Tilemap-System/2abeb86464655ba4046bdf23edde553fd18d1172/3D Tilemap System/Editor/UI/_DefaultColor.png -------------------------------------------------------------------------------- /3D Tilemap System/Editor/UI/_DefaultColor.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fc2536f26d8023b49872f89b877b5a4d 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 1 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 0 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: 1 38 | wrapV: 1 39 | wrapW: 1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | applyGammaDecoding: 0 61 | platformSettings: 62 | - serializedVersion: 3 63 | buildTarget: DefaultTexturePlatform 64 | maxTextureSize: 64 65 | resizeAlgorithm: 0 66 | textureFormat: -1 67 | textureCompression: 0 68 | compressionQuality: 50 69 | crunchedCompression: 0 70 | allowsAlphaSplitting: 0 71 | overridden: 0 72 | androidETC2FallbackOverride: 0 73 | forceMaximumCompressionQuality_BC6H_BC7: 0 74 | - serializedVersion: 3 75 | buildTarget: Standalone 76 | maxTextureSize: 64 77 | resizeAlgorithm: 0 78 | textureFormat: -1 79 | textureCompression: 0 80 | compressionQuality: 50 81 | crunchedCompression: 0 82 | allowsAlphaSplitting: 0 83 | overridden: 0 84 | androidETC2FallbackOverride: 0 85 | forceMaximumCompressionQuality_BC6H_BC7: 0 86 | spriteSheet: 87 | serializedVersion: 2 88 | sprites: [] 89 | outline: [] 90 | physicsShape: [] 91 | bones: [] 92 | spriteID: 93 | internalID: 0 94 | vertices: [] 95 | indices: 96 | edges: [] 97 | weights: [] 98 | secondaryTextures: [] 99 | spritePackingTag: 100 | pSDRemoveMatte: 0 101 | pSDShowRemoveMatteOption: 0 102 | userData: 103 | assetBundleName: 104 | assetBundleVariant: 105 | -------------------------------------------------------------------------------- /3D Tilemap System/Editor/UI/_EmptyIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7StarsGames/3D-Tilemap-System/2abeb86464655ba4046bdf23edde553fd18d1172/3D Tilemap System/Editor/UI/_EmptyIcon.png -------------------------------------------------------------------------------- /3D Tilemap System/Editor/UI/_EmptyIcon.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0358aeafcbe8c9e429e2b389a3241997 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 1 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 0 35 | aniso: 1 36 | mipBias: -100 37 | wrapU: 1 38 | wrapV: 1 39 | wrapW: -1 40 | nPOTScale: 0 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 1 53 | spriteTessellationDetail: -1 54 | textureType: 2 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | applyGammaDecoding: 1 61 | platformSettings: 62 | - serializedVersion: 3 63 | buildTarget: DefaultTexturePlatform 64 | maxTextureSize: 64 65 | resizeAlgorithm: 0 66 | textureFormat: -1 67 | textureCompression: 0 68 | compressionQuality: 50 69 | crunchedCompression: 0 70 | allowsAlphaSplitting: 0 71 | overridden: 0 72 | androidETC2FallbackOverride: 0 73 | forceMaximumCompressionQuality_BC6H_BC7: 0 74 | - serializedVersion: 3 75 | buildTarget: Standalone 76 | maxTextureSize: 64 77 | resizeAlgorithm: 0 78 | textureFormat: -1 79 | textureCompression: 0 80 | compressionQuality: 50 81 | crunchedCompression: 0 82 | allowsAlphaSplitting: 0 83 | overridden: 0 84 | androidETC2FallbackOverride: 0 85 | forceMaximumCompressionQuality_BC6H_BC7: 0 86 | spriteSheet: 87 | serializedVersion: 2 88 | sprites: [] 89 | outline: [] 90 | physicsShape: [] 91 | bones: [] 92 | spriteID: 93 | internalID: 0 94 | vertices: [] 95 | indices: 96 | edges: [] 97 | weights: [] 98 | secondaryTextures: [] 99 | spritePackingTag: 100 | pSDRemoveMatte: 0 101 | pSDShowRemoveMatteOption: 0 102 | userData: 103 | assetBundleName: 104 | assetBundleVariant: 105 | -------------------------------------------------------------------------------- /3D Tilemap System/Imports.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 10410e6d3ec8c904eaf7932fa630e218 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /3D Tilemap System/Imports/CustomMapMesh.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.81 (sub 16) OBJ File: 'TilemapSystem3DMap.blend' 2 | # www.blender.org 3 | mtllib CustomMapMesh.mtl 4 | o Plane 5 | v 0.000000 0.000000 1.000000 6 | v 2.000000 0.000000 1.000000 7 | v 0.000000 0.000000 -1.000000 8 | v 2.000000 0.000000 -1.000000 9 | v 0.000000 2.000000 1.000000 10 | v 2.000000 2.000000 1.000000 11 | v 0.000000 2.000000 -1.000000 12 | v 2.000000 2.000000 -1.000000 13 | v -6.000000 0.000000 -1.000000 14 | v 6.000000 0.000000 5.000000 15 | v -6.000000 0.000000 1.000000 16 | v 6.000000 0.000000 -5.000000 17 | v -6.000000 0.000000 5.000000 18 | v -6.000000 0.000000 -5.000000 19 | v -4.000000 0.000000 1.000000 20 | v -4.000000 0.000000 -1.000000 21 | v -6.000000 -1.000000 -1.000000 22 | v -6.000000 -1.000000 1.000000 23 | v 6.000000 -1.000000 5.000000 24 | v 6.000000 -1.000000 -5.000000 25 | v -6.000000 -1.000000 5.000000 26 | v -6.000000 -1.000000 -5.000000 27 | v -8.000000 -1.000000 0.000000 28 | v 8.000000 -1.000000 8.000000 29 | v 8.000000 -1.000000 -8.000000 30 | v -8.000000 -1.000000 8.000000 31 | v -8.000000 -1.000000 -8.000000 32 | vt 0.312500 0.781250 33 | vt 0.312500 0.718750 34 | vt 0.437500 0.593750 35 | vt 0.437500 0.906250 36 | vt 0.250000 0.718750 37 | vt 0.312500 0.718750 38 | vt 0.312500 0.781250 39 | vt 0.250000 0.781250 40 | vt 0.625000 0.937500 41 | vt 0.687500 0.937500 42 | vt 0.687500 1.000000 43 | vt 0.625000 1.000000 44 | vt 0.750000 0.937500 45 | vt 0.812500 0.937500 46 | vt 0.812500 1.000000 47 | vt 0.750000 1.000000 48 | vt 0.562500 0.937500 49 | vt 0.562500 1.000000 50 | vt 0.125000 0.718750 51 | vt 0.062500 0.593750 52 | vt 0.250000 0.718750 53 | vt 0.250000 0.781250 54 | vt 0.062500 0.906250 55 | vt 0.125000 0.781250 56 | vt 0.593750 0.906250 57 | vt 0.656250 0.875000 58 | vt 0.656250 0.906250 59 | vt 0.562500 0.875000 60 | vt 0.562500 0.843750 61 | vt 0.625000 0.875000 62 | vt 0.062500 0.718750 63 | vt 0.062500 0.718750 64 | vt 0.062500 0.781250 65 | vt 0.062500 0.781250 66 | vt 0.375000 0.031250 67 | vt 0.000000 0.031250 68 | vt 0.000000 0.000000 69 | vt 0.375000 0.000000 70 | vt 0.406250 0.062500 71 | vt 0.031250 0.062500 72 | vt 0.031250 0.031250 73 | vt 0.406250 0.031250 74 | vt 0.343750 0.093750 75 | vt 0.031250 0.093750 76 | vt 0.031250 0.062500 77 | vt 0.343750 0.062500 78 | vt 0.375000 0.000000 79 | vt 0.500000 0.000000 80 | vt 0.500000 0.031250 81 | vt 0.375000 0.031250 82 | vt 0.656250 0.031250 83 | vt 0.531250 0.031250 84 | vt 0.531250 -0.000000 85 | vt 0.656250 -0.000000 86 | vt 0.062500 0.906250 87 | vt 0.437500 0.906250 88 | vt 0.500000 1.000000 89 | vt 0.000000 1.000000 90 | vt 0.000000 0.750000 91 | vt 0.437500 0.593750 92 | vt 0.062500 0.593750 93 | vt 0.000000 0.500000 94 | vt 0.500000 0.500000 95 | vn 0.0000 1.0000 0.0000 96 | vn 1.0000 0.0000 0.0000 97 | vn -1.0000 0.0000 0.0000 98 | vn 0.0000 0.0000 -1.0000 99 | vn 0.0000 0.0000 1.0000 100 | vn -0.4472 0.8944 0.0000 101 | usemtl Material.001 102 | s off 103 | f 4/1/1 2/2/1 10/3/1 12/4/1 104 | f 5/5/1 6/6/1 8/7/1 7/8/1 105 | f 2/9/2 4/10/2 8/11/2 6/12/2 106 | f 3/13/3 1/14/3 5/15/3 7/16/3 107 | f 4/10/4 3/13/4 7/16/4 8/11/4 108 | f 1/17/5 2/9/5 6/12/5 5/18/5 109 | f 15/19/1 13/20/1 1/21/1 110 | f 3/22/1 4/1/1 12/4/1 14/23/1 111 | f 2/2/1 1/21/1 13/20/1 10/3/1 112 | f 1/21/1 3/22/1 16/24/1 15/19/1 113 | f 14/23/1 16/24/1 3/22/1 114 | f 15/25/4 18/26/4 11/27/4 115 | f 9/28/5 17/29/5 16/30/5 116 | f 15/19/1 11/31/1 13/20/1 117 | f 18/32/6 15/19/6 16/24/6 17/33/6 118 | f 16/24/1 14/23/1 9/34/1 119 | f 10/35/5 13/36/5 21/37/5 19/38/5 120 | f 14/39/4 12/40/4 20/41/4 22/42/4 121 | f 12/43/2 10/44/2 19/45/2 20/46/2 122 | f 18/47/3 21/48/3 13/49/3 11/50/3 123 | f 9/51/3 14/52/3 22/53/3 17/54/3 124 | f 22/55/1 20/56/1 25/57/1 27/58/1 125 | f 17/33/1 22/55/1 27/58/1 23/59/1 126 | f 18/32/1 17/33/1 23/59/1 127 | f 19/60/1 21/61/1 26/62/1 24/63/1 128 | f 20/56/1 19/60/1 24/63/1 25/57/1 129 | f 21/61/1 18/32/1 23/59/1 26/62/1 130 | -------------------------------------------------------------------------------- /3D Tilemap System/Imports/CustomMapMesh.obj.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8e0ab8acdae10b8459db59394f7bece8 3 | ModelImporter: 4 | serializedVersion: 19300 5 | internalIDToNameTable: [] 6 | externalObjects: {} 7 | materials: 8 | materialImportMode: 0 9 | materialName: 0 10 | materialSearch: 1 11 | materialLocation: 1 12 | animations: 13 | legacyGenerateAnimations: 4 14 | bakeSimulation: 0 15 | resampleCurves: 1 16 | optimizeGameObjects: 0 17 | motionNodeName: 18 | rigImportErrors: 19 | rigImportWarnings: 20 | animationImportErrors: 21 | animationImportWarnings: 22 | animationRetargetingWarnings: 23 | animationDoRetargetingWarnings: 0 24 | importAnimatedCustomProperties: 0 25 | importConstraints: 0 26 | animationCompression: 1 27 | animationRotationError: 0.5 28 | animationPositionError: 0.5 29 | animationScaleError: 0.5 30 | animationWrapMode: 0 31 | extraExposedTransformPaths: [] 32 | extraUserProperties: [] 33 | clipAnimations: [] 34 | isReadable: 0 35 | meshes: 36 | lODScreenPercentages: [] 37 | globalScale: 1 38 | meshCompression: 0 39 | addColliders: 0 40 | useSRGBMaterialColor: 1 41 | sortHierarchyByName: 1 42 | importVisibility: 1 43 | importBlendShapes: 1 44 | importCameras: 1 45 | importLights: 1 46 | swapUVChannels: 0 47 | generateSecondaryUV: 0 48 | useFileUnits: 1 49 | keepQuads: 0 50 | weldVertices: 1 51 | preserveHierarchy: 0 52 | skinWeightsMode: 0 53 | maxBonesPerVertex: 4 54 | minBoneWeight: 0.001 55 | meshOptimizationFlags: -1 56 | indexFormat: 0 57 | secondaryUVAngleDistortion: 8 58 | secondaryUVAreaDistortion: 15.000001 59 | secondaryUVHardAngle: 88 60 | secondaryUVPackMargin: 4 61 | useFileScale: 1 62 | tangentSpace: 63 | normalSmoothAngle: 60 64 | normalImportMode: 0 65 | tangentImportMode: 3 66 | normalCalculationMode: 4 67 | legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 68 | blendShapeNormalImportMode: 1 69 | normalSmoothingSource: 0 70 | referencedClips: [] 71 | importAnimation: 0 72 | humanDescription: 73 | serializedVersion: 3 74 | human: [] 75 | skeleton: [] 76 | armTwist: 0.5 77 | foreArmTwist: 0.5 78 | upperLegTwist: 0.5 79 | legTwist: 0.5 80 | armStretch: 0.05 81 | legStretch: 0.05 82 | feetSpacing: 0 83 | globalScale: 1 84 | rootMotionBoneName: 85 | hasTranslationDoF: 0 86 | hasExtraRoot: 0 87 | skeletonHasParents: 1 88 | lastHumanDescriptionAvatarSource: {instanceID: 0} 89 | autoGenerateAvatarMappingIfUnspecified: 1 90 | animationType: 0 91 | humanoidOversampling: 1 92 | avatarSetup: 0 93 | additionalBone: 0 94 | userData: 95 | assetBundleName: 96 | assetBundleVariant: 97 | -------------------------------------------------------------------------------- /3D Tilemap System/Palettes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5ca1be0c6a5726443a04efd34f258aee 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /3D Tilemap System/Palettes/Layer0.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c7e2f22a6fd29d444ae2e4b05b62aa5f 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /3D Tilemap System/Palettes/Layer1.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b76cc6d0bdff4854190ea3231731c8de 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /3D Tilemap System/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2993319468a168d419fa833d02bd91d9 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /3D Tilemap System/Scenes/CustomMesh.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 1 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &508256828 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 508256831} 133 | - component: {fileID: 508256830} 134 | - component: {fileID: 508256829} 135 | m_Layer: 0 136 | m_Name: Main Camera 137 | m_TagString: MainCamera 138 | m_Icon: {fileID: 0} 139 | m_NavMeshLayer: 0 140 | m_StaticEditorFlags: 0 141 | m_IsActive: 1 142 | --- !u!81 &508256829 143 | AudioListener: 144 | m_ObjectHideFlags: 0 145 | m_CorrespondingSourceObject: {fileID: 0} 146 | m_PrefabInstance: {fileID: 0} 147 | m_PrefabAsset: {fileID: 0} 148 | m_GameObject: {fileID: 508256828} 149 | m_Enabled: 1 150 | --- !u!20 &508256830 151 | Camera: 152 | m_ObjectHideFlags: 0 153 | m_CorrespondingSourceObject: {fileID: 0} 154 | m_PrefabInstance: {fileID: 0} 155 | m_PrefabAsset: {fileID: 0} 156 | m_GameObject: {fileID: 508256828} 157 | m_Enabled: 1 158 | serializedVersion: 2 159 | m_ClearFlags: 1 160 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 161 | m_projectionMatrixMode: 1 162 | m_GateFitMode: 2 163 | m_FOVAxisMode: 0 164 | m_SensorSize: {x: 36, y: 24} 165 | m_LensShift: {x: 0, y: 0} 166 | m_FocalLength: 50 167 | m_NormalizedViewPortRect: 168 | serializedVersion: 2 169 | x: 0 170 | y: 0 171 | width: 1 172 | height: 1 173 | near clip plane: 0.3 174 | far clip plane: 1000 175 | field of view: 60 176 | orthographic: 0 177 | orthographic size: 5 178 | m_Depth: -1 179 | m_CullingMask: 180 | serializedVersion: 2 181 | m_Bits: 4294967295 182 | m_RenderingPath: -1 183 | m_TargetTexture: {fileID: 0} 184 | m_TargetDisplay: 0 185 | m_TargetEye: 3 186 | m_HDR: 1 187 | m_AllowMSAA: 1 188 | m_AllowDynamicResolution: 0 189 | m_ForceIntoRT: 0 190 | m_OcclusionCulling: 1 191 | m_StereoConvergence: 10 192 | m_StereoSeparation: 0.022 193 | --- !u!4 &508256831 194 | Transform: 195 | m_ObjectHideFlags: 0 196 | m_CorrespondingSourceObject: {fileID: 0} 197 | m_PrefabInstance: {fileID: 0} 198 | m_PrefabAsset: {fileID: 0} 199 | m_GameObject: {fileID: 508256828} 200 | m_LocalRotation: {x: -0.04995017, y: 0.91597575, z: -0.120590456, w: -0.37940934} 201 | m_LocalPosition: {x: 10, y: 4, z: 10} 202 | m_LocalScale: {x: 1, y: 1, z: 1} 203 | m_Children: [] 204 | m_Father: {fileID: 0} 205 | m_RootOrder: 0 206 | m_LocalEulerAnglesHint: {x: 15, y: 225, z: 0} 207 | --- !u!1 &673493858 208 | GameObject: 209 | m_ObjectHideFlags: 0 210 | m_CorrespondingSourceObject: {fileID: 0} 211 | m_PrefabInstance: {fileID: 0} 212 | m_PrefabAsset: {fileID: 0} 213 | serializedVersion: 6 214 | m_Component: 215 | - component: {fileID: 673493860} 216 | - component: {fileID: 673493859} 217 | m_Layer: 0 218 | m_Name: Directional Light 219 | m_TagString: Untagged 220 | m_Icon: {fileID: 0} 221 | m_NavMeshLayer: 0 222 | m_StaticEditorFlags: 0 223 | m_IsActive: 1 224 | --- !u!108 &673493859 225 | Light: 226 | m_ObjectHideFlags: 0 227 | m_CorrespondingSourceObject: {fileID: 0} 228 | m_PrefabInstance: {fileID: 0} 229 | m_PrefabAsset: {fileID: 0} 230 | m_GameObject: {fileID: 673493858} 231 | m_Enabled: 1 232 | serializedVersion: 10 233 | m_Type: 1 234 | m_Shape: 0 235 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 236 | m_Intensity: 1 237 | m_Range: 10 238 | m_SpotAngle: 30 239 | m_InnerSpotAngle: 21.80208 240 | m_CookieSize: 10 241 | m_Shadows: 242 | m_Type: 2 243 | m_Resolution: -1 244 | m_CustomResolution: -1 245 | m_Strength: 1 246 | m_Bias: 0.05 247 | m_NormalBias: 0.4 248 | m_NearPlane: 0.2 249 | m_CullingMatrixOverride: 250 | e00: 1 251 | e01: 0 252 | e02: 0 253 | e03: 0 254 | e10: 0 255 | e11: 1 256 | e12: 0 257 | e13: 0 258 | e20: 0 259 | e21: 0 260 | e22: 1 261 | e23: 0 262 | e30: 0 263 | e31: 0 264 | e32: 0 265 | e33: 1 266 | m_UseCullingMatrixOverride: 0 267 | m_Cookie: {fileID: 0} 268 | m_DrawHalo: 0 269 | m_Flare: {fileID: 0} 270 | m_RenderMode: 0 271 | m_CullingMask: 272 | serializedVersion: 2 273 | m_Bits: 4294967295 274 | m_RenderingLayerMask: 1 275 | m_Lightmapping: 4 276 | m_LightShadowCasterMode: 0 277 | m_AreaSize: {x: 1, y: 1} 278 | m_BounceIntensity: 1 279 | m_ColorTemperature: 6570 280 | m_UseColorTemperature: 0 281 | m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} 282 | m_UseBoundingSphereOverride: 0 283 | m_ShadowRadius: 0 284 | m_ShadowAngle: 0 285 | --- !u!4 &673493860 286 | Transform: 287 | m_ObjectHideFlags: 0 288 | m_CorrespondingSourceObject: {fileID: 0} 289 | m_PrefabInstance: {fileID: 0} 290 | m_PrefabAsset: {fileID: 0} 291 | m_GameObject: {fileID: 673493858} 292 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 293 | m_LocalPosition: {x: 0, y: 3, z: 0} 294 | m_LocalScale: {x: 1, y: 1, z: 1} 295 | m_Children: [] 296 | m_Father: {fileID: 0} 297 | m_RootOrder: 1 298 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 299 | --- !u!23 &616906688896003795 300 | MeshRenderer: 301 | m_ObjectHideFlags: 0 302 | m_CorrespondingSourceObject: {fileID: 0} 303 | m_PrefabInstance: {fileID: 0} 304 | m_PrefabAsset: {fileID: 0} 305 | m_GameObject: {fileID: 8490445995354657350} 306 | m_Enabled: 1 307 | m_CastShadows: 1 308 | m_ReceiveShadows: 1 309 | m_DynamicOccludee: 1 310 | m_MotionVectors: 1 311 | m_LightProbeUsage: 1 312 | m_ReflectionProbeUsage: 1 313 | m_RayTracingMode: 2 314 | m_RenderingLayerMask: 1 315 | m_RendererPriority: 0 316 | m_Materials: 317 | - {fileID: 8100435524718681739, guid: 2f70dcf06658099458dc5d1d4d47124e, type: 2} 318 | m_StaticBatchInfo: 319 | firstSubMesh: 0 320 | subMeshCount: 0 321 | m_StaticBatchRoot: {fileID: 0} 322 | m_ProbeAnchor: {fileID: 0} 323 | m_LightProbeVolumeOverride: {fileID: 0} 324 | m_ScaleInLightmap: 1 325 | m_ReceiveGI: 1 326 | m_PreserveUVs: 0 327 | m_IgnoreNormalsForChartDetection: 0 328 | m_ImportantGI: 0 329 | m_StitchLightmapSeams: 1 330 | m_SelectedEditorRenderState: 3 331 | m_MinimumChartSize: 4 332 | m_AutoUVMaxDistance: 0.5 333 | m_AutoUVMaxAngle: 89 334 | m_LightmapParameters: {fileID: 0} 335 | m_SortingLayerID: 0 336 | m_SortingLayer: 0 337 | m_SortingOrder: 0 338 | --- !u!33 &8191224824226906659 339 | MeshFilter: 340 | m_ObjectHideFlags: 0 341 | m_CorrespondingSourceObject: {fileID: 0} 342 | m_PrefabInstance: {fileID: 0} 343 | m_PrefabAsset: {fileID: 0} 344 | m_GameObject: {fileID: 8490445995354657350} 345 | m_Mesh: {fileID: -2432090755550338912, guid: 8e0ab8acdae10b8459db59394f7bece8, type: 3} 346 | --- !u!1 &8490445995354657350 347 | GameObject: 348 | m_ObjectHideFlags: 0 349 | m_CorrespondingSourceObject: {fileID: 0} 350 | m_PrefabInstance: {fileID: 0} 351 | m_PrefabAsset: {fileID: 0} 352 | serializedVersion: 6 353 | m_Component: 354 | - component: {fileID: 8930025769546864368} 355 | - component: {fileID: 8191224824226906659} 356 | - component: {fileID: 616906688896003795} 357 | - component: {fileID: 8490445995354657351} 358 | - component: {fileID: 8490445995354657352} 359 | m_Layer: 0 360 | m_Name: CustomMesh 361 | m_TagString: Untagged 362 | m_Icon: {fileID: 0} 363 | m_NavMeshLayer: 0 364 | m_StaticEditorFlags: 0 365 | m_IsActive: 1 366 | --- !u!64 &8490445995354657351 367 | MeshCollider: 368 | m_ObjectHideFlags: 0 369 | m_CorrespondingSourceObject: {fileID: 0} 370 | m_PrefabInstance: {fileID: 0} 371 | m_PrefabAsset: {fileID: 0} 372 | m_GameObject: {fileID: 8490445995354657350} 373 | m_Material: {fileID: 0} 374 | m_IsTrigger: 0 375 | m_Enabled: 1 376 | serializedVersion: 4 377 | m_Convex: 0 378 | m_CookingOptions: 30 379 | m_Mesh: {fileID: -2432090755550338912, guid: 8e0ab8acdae10b8459db59394f7bece8, type: 3} 380 | --- !u!114 &8490445995354657352 381 | MonoBehaviour: 382 | m_ObjectHideFlags: 0 383 | m_CorrespondingSourceObject: {fileID: 0} 384 | m_PrefabInstance: {fileID: 0} 385 | m_PrefabAsset: {fileID: 0} 386 | m_GameObject: {fileID: 8490445995354657350} 387 | m_Enabled: 1 388 | m_EditorHideFlags: 0 389 | m_Script: {fileID: 11500000, guid: 7040d198a41a5574bbbcfda0058a088d, type: 3} 390 | m_Name: 391 | m_EditorClassIdentifier: 392 | legacyShader: {fileID: 4800000, guid: 5594d6040eb13d54db5449d867e57ea0, type: 3} 393 | universalShader: {fileID: 4800000, guid: 0400508317e303b4683b2d7fa99ba81e, type: 3} 394 | renderPipeline: 1 395 | tilesetSize: 32 396 | gridMapSize: {x: 32, y: 32, z: 1, w: 1} 397 | tilemapData: {fileID: 11400000, guid: 2f70dcf06658099458dc5d1d4d47124e, type: 2} 398 | tilemapLayerList: 399 | - tilePalette: {fileID: 11400000, guid: c7e2f22a6fd29d444ae2e4b05b62aa5f, type: 2} 400 | autoTileList: [] 401 | intensity: 1 402 | autoTileMapArray: 01010101010101010101010101010101010101010101000000000000000000000001010101010101010101010100000000000000000000000000000000000000000101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000010101010101000100000001010100000000000000000000000000000000000101010101010101010101010101010000000000000000000000000000000000000100010000000000000000000001000000000000000000000000000000000000010000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000010000000000010000000000000000000000000000000000000000000000010101000000000100000001000000000000000000000000000000000000000101000000000000000000000000000100000000000000000000000000000000010000000000000000000001000000000000000000000000000000000000000000000000010000000100000000000000000001010000000000000000000000000001000000000000000000000000000000000001010000000000000000000000010000000000000000000000000000010000000000000000000000000000000000000000000001000000000100010000000001010101010101010000000000000000000100000000000000000000000100000101010101010101000000000000 403 | layerName: Layer 0 404 | iconTexture: {fileID: 0} 405 | layoutIndex: 0 406 | tilemapTexture: {fileID: 7255575906354808228, guid: 2f70dcf06658099458dc5d1d4d47124e, 407 | type: 2} 408 | tilesetTexture: {fileID: -3226186117573426890, guid: 2f70dcf06658099458dc5d1d4d47124e, 409 | type: 2} 410 | layerArrayTexture: {fileID: 8860209851284015757, guid: 2f70dcf06658099458dc5d1d4d47124e, 411 | type: 2} 412 | renderMaterial: {fileID: 8100435524718681739, guid: 2f70dcf06658099458dc5d1d4d47124e, 413 | type: 2} 414 | defaultColorTexture: {fileID: 2800000, guid: fc2536f26d8023b49872f89b877b5a4d, type: 3} 415 | paintingMode: 0 416 | showReferencesGroup: 1 417 | showSettingsGroup: 1 418 | showDataGroup: 1 419 | showPantingGroup: 1 420 | showAutoTileGroup: 1 421 | showRandomTilePaintingGroup: 0 422 | showRandomizeTileGroup: 0 423 | showTileBrushesGroup: 0 424 | showAboutGroup: 1 425 | --- !u!4 &8930025769546864368 426 | Transform: 427 | m_ObjectHideFlags: 0 428 | m_CorrespondingSourceObject: {fileID: 0} 429 | m_PrefabInstance: {fileID: 0} 430 | m_PrefabAsset: {fileID: 0} 431 | m_GameObject: {fileID: 8490445995354657350} 432 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 433 | m_LocalPosition: {x: 0, y: 0, z: 0} 434 | m_LocalScale: {x: 1, y: 1, z: 1} 435 | m_Children: [] 436 | m_Father: {fileID: 0} 437 | m_RootOrder: 2 438 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 439 | -------------------------------------------------------------------------------- /3D Tilemap System/Scenes/CustomMesh.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7272d95a0e572fd408c8642c0789d4ee 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /3D Tilemap System/Scenes/New Terrain.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7StarsGames/3D-Tilemap-System/2abeb86464655ba4046bdf23edde553fd18d1172/3D Tilemap System/Scenes/New Terrain.asset -------------------------------------------------------------------------------- /3D Tilemap System/Scenes/New Terrain.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 53e2d12b7618ef541b2b5d37a80758b9 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /3D Tilemap System/Scenes/UnityTerrain.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 1 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &41485485 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 41485488} 133 | - component: {fileID: 41485487} 134 | - component: {fileID: 41485486} 135 | - component: {fileID: 41485489} 136 | m_Layer: 0 137 | m_Name: Terrain 138 | m_TagString: Untagged 139 | m_Icon: {fileID: 0} 140 | m_NavMeshLayer: 0 141 | m_StaticEditorFlags: 4294967295 142 | m_IsActive: 1 143 | --- !u!154 &41485486 144 | TerrainCollider: 145 | m_ObjectHideFlags: 0 146 | m_CorrespondingSourceObject: {fileID: 0} 147 | m_PrefabInstance: {fileID: 0} 148 | m_PrefabAsset: {fileID: 0} 149 | m_GameObject: {fileID: 41485485} 150 | m_Material: {fileID: 0} 151 | m_Enabled: 1 152 | m_TerrainData: {fileID: 15600000, guid: 53e2d12b7618ef541b2b5d37a80758b9, type: 2} 153 | m_EnableTreeColliders: 1 154 | --- !u!218 &41485487 155 | Terrain: 156 | m_ObjectHideFlags: 0 157 | m_CorrespondingSourceObject: {fileID: 0} 158 | m_PrefabInstance: {fileID: 0} 159 | m_PrefabAsset: {fileID: 0} 160 | m_GameObject: {fileID: 41485485} 161 | m_Enabled: 1 162 | serializedVersion: 6 163 | m_TerrainData: {fileID: 15600000, guid: 53e2d12b7618ef541b2b5d37a80758b9, type: 2} 164 | m_TreeDistance: 5000 165 | m_TreeBillboardDistance: 50 166 | m_TreeCrossFadeLength: 5 167 | m_TreeMaximumFullLODCount: 50 168 | m_DetailObjectDistance: 80 169 | m_DetailObjectDensity: 1 170 | m_HeightmapPixelError: 5 171 | m_SplatMapDistance: 1000 172 | m_HeightmapMaximumLOD: 0 173 | m_ShadowCastingMode: 2 174 | m_DrawHeightmap: 1 175 | m_DrawInstanced: 0 176 | m_DrawTreesAndFoliage: 1 177 | m_ReflectionProbeUsage: 1 178 | m_MaterialTemplate: {fileID: -4413301779959847400, guid: d4247b418b0fcb64f96a64171c4d4bc9, 179 | type: 2} 180 | m_BakeLightProbesForTrees: 1 181 | m_PreserveTreePrototypeLayers: 0 182 | m_DeringLightProbesForTrees: 1 183 | m_ScaleInLightmap: 0.0256 184 | m_LightmapParameters: {fileID: 15203, guid: 0000000000000000f000000000000000, type: 0} 185 | m_GroupingID: 0 186 | m_RenderingLayerMask: 1 187 | m_AllowAutoConnect: 1 188 | --- !u!4 &41485488 189 | Transform: 190 | m_ObjectHideFlags: 0 191 | m_CorrespondingSourceObject: {fileID: 0} 192 | m_PrefabInstance: {fileID: 0} 193 | m_PrefabAsset: {fileID: 0} 194 | m_GameObject: {fileID: 41485485} 195 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 196 | m_LocalPosition: {x: -16, y: 0, z: -16} 197 | m_LocalScale: {x: 1, y: 1, z: 1} 198 | m_Children: [] 199 | m_Father: {fileID: 0} 200 | m_RootOrder: 2 201 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 202 | --- !u!114 &41485489 203 | MonoBehaviour: 204 | m_ObjectHideFlags: 0 205 | m_CorrespondingSourceObject: {fileID: 0} 206 | m_PrefabInstance: {fileID: 0} 207 | m_PrefabAsset: {fileID: 0} 208 | m_GameObject: {fileID: 41485485} 209 | m_Enabled: 1 210 | m_EditorHideFlags: 0 211 | m_Script: {fileID: 11500000, guid: 7040d198a41a5574bbbcfda0058a088d, type: 3} 212 | m_Name: 213 | m_EditorClassIdentifier: 214 | legacyShader: {fileID: 4800000, guid: 5594d6040eb13d54db5449d867e57ea0, type: 3} 215 | universalShader: {fileID: 4800000, guid: 0400508317e303b4683b2d7fa99ba81e, type: 3} 216 | renderPipeline: 0 217 | tilesetSize: 32 218 | gridMapSize: {x: 32, y: 32, z: 1, w: 1} 219 | tilemapData: {fileID: 11400000, guid: d4247b418b0fcb64f96a64171c4d4bc9, type: 2} 220 | tilemapLayerList: 221 | - tilePalette: {fileID: 11400000, guid: c7e2f22a6fd29d444ae2e4b05b62aa5f, type: 2} 222 | autoTileList: 223 | - id: 0100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e0000001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b0000002c0000002d0000002e0000002f000000 224 | isPicked: 0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101 225 | name: Auto Tile Layout 0 226 | intensity: 1 227 | autoTileMapArray: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101000000010000000101010101000000000100000000010000000101010101010100000000000000010101010100000000000000000000000000010101010101010000000000000001010101010000000000000000000000000001010101010101000000000000000000010000000000000000000000000000000101010101010100000000000001010101000000000000000000000000000000010101010101010001000000000100000000000000000100000000000000000001010101010101000000000000010000000000000000000000000000000100000000000001000000000000000001000000000000000000000000000000000000000000000100000000000000000101010000000000000000000000000000000000000000010000000000000000000001010000000000000000000000000000000000000001000000000100000000000001000000000100000000000000000000000000000100000000000000000100000100000000000000000000000000000100000000010000000000000000000000010000000000000000000000000000000000000001000000000000000000000001000000000000000000000000000000000000000101010101010101010101010100000000000000000000000000000000000000000000000000000000000000010000000101010101000000000000000000000000000000000000000000000001000000010101010100000000000000000000000000000000000000000000000100000001010001010000000100000000000000000000000000000001000000010000000101000101000000000000000000000000000000000000000000000001000000010100010100000000000000000000000000000000000000000000000100000001010001010000000000000000000000000000000000000000000000010000000101010101000000000000010000000000010000000000000000000001010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 228 | layerName: Layer 0 229 | iconTexture: {fileID: 0} 230 | layoutIndex: 0 231 | - tilePalette: {fileID: 11400000, guid: b76cc6d0bdff4854190ea3231731c8de, type: 2} 232 | autoTileList: 233 | - id: 0100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e0000001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b0000002c0000002d0000002e0000002f000000 234 | isPicked: 0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101 235 | name: Auto Tile Layout 0 236 | intensity: 1 237 | autoTileMapArray: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000100010000000000000000000000000000000000000000000000000000000100010001000000000000000000000000000000000000000000000000000000010001000100000000000000000000000000000000000000000000000000000001000100010000000000000000000000000000000000000000000000000000000100010001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 238 | layerName: Layer 1 239 | iconTexture: {fileID: 0} 240 | layoutIndex: 0 241 | tilemapTexture: {fileID: -4812047712901483052, guid: d4247b418b0fcb64f96a64171c4d4bc9, 242 | type: 2} 243 | tilesetTexture: {fileID: -6207913971041024804, guid: d4247b418b0fcb64f96a64171c4d4bc9, 244 | type: 2} 245 | layerArrayTexture: {fileID: 5142989601297917491, guid: d4247b418b0fcb64f96a64171c4d4bc9, 246 | type: 2} 247 | renderMaterial: {fileID: -4413301779959847400, guid: d4247b418b0fcb64f96a64171c4d4bc9, 248 | type: 2} 249 | defaultColorTexture: {fileID: 2800000, guid: fc2536f26d8023b49872f89b877b5a4d, type: 3} 250 | paintingMode: 0 251 | showReferencesGroup: 1 252 | showSettingsGroup: 1 253 | showDataGroup: 1 254 | showPantingGroup: 1 255 | showAutoTileGroup: 1 256 | showRandomTilePaintingGroup: 0 257 | showRandomizeTileGroup: 0 258 | showTileBrushesGroup: 0 259 | showAboutGroup: 1 260 | --- !u!1 &618268794 261 | GameObject: 262 | m_ObjectHideFlags: 0 263 | m_CorrespondingSourceObject: {fileID: 0} 264 | m_PrefabInstance: {fileID: 0} 265 | m_PrefabAsset: {fileID: 0} 266 | serializedVersion: 6 267 | m_Component: 268 | - component: {fileID: 618268797} 269 | - component: {fileID: 618268796} 270 | - component: {fileID: 618268795} 271 | m_Layer: 0 272 | m_Name: Main Camera 273 | m_TagString: MainCamera 274 | m_Icon: {fileID: 0} 275 | m_NavMeshLayer: 0 276 | m_StaticEditorFlags: 0 277 | m_IsActive: 1 278 | --- !u!81 &618268795 279 | AudioListener: 280 | m_ObjectHideFlags: 0 281 | m_CorrespondingSourceObject: {fileID: 0} 282 | m_PrefabInstance: {fileID: 0} 283 | m_PrefabAsset: {fileID: 0} 284 | m_GameObject: {fileID: 618268794} 285 | m_Enabled: 1 286 | --- !u!20 &618268796 287 | Camera: 288 | m_ObjectHideFlags: 0 289 | m_CorrespondingSourceObject: {fileID: 0} 290 | m_PrefabInstance: {fileID: 0} 291 | m_PrefabAsset: {fileID: 0} 292 | m_GameObject: {fileID: 618268794} 293 | m_Enabled: 1 294 | serializedVersion: 2 295 | m_ClearFlags: 1 296 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 297 | m_projectionMatrixMode: 1 298 | m_GateFitMode: 2 299 | m_FOVAxisMode: 0 300 | m_SensorSize: {x: 36, y: 24} 301 | m_LensShift: {x: 0, y: 0} 302 | m_FocalLength: 50 303 | m_NormalizedViewPortRect: 304 | serializedVersion: 2 305 | x: 0 306 | y: 0 307 | width: 1 308 | height: 1 309 | near clip plane: 0.3 310 | far clip plane: 1000 311 | field of view: 60 312 | orthographic: 0 313 | orthographic size: 5 314 | m_Depth: -1 315 | m_CullingMask: 316 | serializedVersion: 2 317 | m_Bits: 4294967295 318 | m_RenderingPath: -1 319 | m_TargetTexture: {fileID: 0} 320 | m_TargetDisplay: 0 321 | m_TargetEye: 3 322 | m_HDR: 1 323 | m_AllowMSAA: 1 324 | m_AllowDynamicResolution: 0 325 | m_ForceIntoRT: 0 326 | m_OcclusionCulling: 1 327 | m_StereoConvergence: 10 328 | m_StereoSeparation: 0.022 329 | --- !u!4 &618268797 330 | Transform: 331 | m_ObjectHideFlags: 0 332 | m_CorrespondingSourceObject: {fileID: 0} 333 | m_PrefabInstance: {fileID: 0} 334 | m_PrefabAsset: {fileID: 0} 335 | m_GameObject: {fileID: 618268794} 336 | m_LocalRotation: {x: 0.17216258, y: 0.12854317, z: -0.022665627, w: 0.9763827} 337 | m_LocalPosition: {x: -8, y: 6, z: -20} 338 | m_LocalScale: {x: 1, y: 1, z: 1} 339 | m_Children: [] 340 | m_Father: {fileID: 0} 341 | m_RootOrder: 0 342 | m_LocalEulerAnglesHint: {x: 20, y: 15, z: 0} 343 | --- !u!1 &2006084671 344 | GameObject: 345 | m_ObjectHideFlags: 0 346 | m_CorrespondingSourceObject: {fileID: 0} 347 | m_PrefabInstance: {fileID: 0} 348 | m_PrefabAsset: {fileID: 0} 349 | serializedVersion: 6 350 | m_Component: 351 | - component: {fileID: 2006084673} 352 | - component: {fileID: 2006084672} 353 | m_Layer: 0 354 | m_Name: Directional Light 355 | m_TagString: Untagged 356 | m_Icon: {fileID: 0} 357 | m_NavMeshLayer: 0 358 | m_StaticEditorFlags: 0 359 | m_IsActive: 1 360 | --- !u!108 &2006084672 361 | Light: 362 | m_ObjectHideFlags: 0 363 | m_CorrespondingSourceObject: {fileID: 0} 364 | m_PrefabInstance: {fileID: 0} 365 | m_PrefabAsset: {fileID: 0} 366 | m_GameObject: {fileID: 2006084671} 367 | m_Enabled: 1 368 | serializedVersion: 10 369 | m_Type: 1 370 | m_Shape: 0 371 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 372 | m_Intensity: 1 373 | m_Range: 10 374 | m_SpotAngle: 30 375 | m_InnerSpotAngle: 21.80208 376 | m_CookieSize: 10 377 | m_Shadows: 378 | m_Type: 2 379 | m_Resolution: -1 380 | m_CustomResolution: -1 381 | m_Strength: 1 382 | m_Bias: 0.05 383 | m_NormalBias: 0.4 384 | m_NearPlane: 0.2 385 | m_CullingMatrixOverride: 386 | e00: 1 387 | e01: 0 388 | e02: 0 389 | e03: 0 390 | e10: 0 391 | e11: 1 392 | e12: 0 393 | e13: 0 394 | e20: 0 395 | e21: 0 396 | e22: 1 397 | e23: 0 398 | e30: 0 399 | e31: 0 400 | e32: 0 401 | e33: 1 402 | m_UseCullingMatrixOverride: 0 403 | m_Cookie: {fileID: 0} 404 | m_DrawHalo: 0 405 | m_Flare: {fileID: 0} 406 | m_RenderMode: 0 407 | m_CullingMask: 408 | serializedVersion: 2 409 | m_Bits: 4294967295 410 | m_RenderingLayerMask: 1 411 | m_Lightmapping: 4 412 | m_LightShadowCasterMode: 0 413 | m_AreaSize: {x: 1, y: 1} 414 | m_BounceIntensity: 1 415 | m_ColorTemperature: 6570 416 | m_UseColorTemperature: 0 417 | m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} 418 | m_UseBoundingSphereOverride: 0 419 | m_ShadowRadius: 0 420 | m_ShadowAngle: 0 421 | --- !u!4 &2006084673 422 | Transform: 423 | m_ObjectHideFlags: 0 424 | m_CorrespondingSourceObject: {fileID: 0} 425 | m_PrefabInstance: {fileID: 0} 426 | m_PrefabAsset: {fileID: 0} 427 | m_GameObject: {fileID: 2006084671} 428 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 429 | m_LocalPosition: {x: 0, y: 3, z: 0} 430 | m_LocalScale: {x: 1, y: 1, z: 1} 431 | m_Children: [] 432 | m_Father: {fileID: 0} 433 | m_RootOrder: 1 434 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 435 | -------------------------------------------------------------------------------- /3D Tilemap System/Scenes/UnityTerrain.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6fd97251306a026419d5f0d371a367e7 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /3D Tilemap System/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b3dbf268be2af1f4c948c5d0ad763a24 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /3D Tilemap System/Scripts/TilePalette.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEditor; 3 | #endif 4 | 5 | namespace UnityEngine.TilemapSystem3D 6 | { 7 | [CreateAssetMenu(fileName = "New Tile Palette", menuName = "3D Tilemap System/ Tile Palette")] 8 | public class TilePalette : ScriptableObject 9 | { 10 | /// 11 | /// The tiles resolution. 12 | /// 13 | public int tileSize = 32; 14 | 15 | /// 16 | /// The atlas texture to convert to tiles. 17 | /// 18 | public Texture2D atlasTexture; 19 | 20 | /// 21 | /// The offset between each tile in the atlas texture. 22 | /// 23 | public int gridOffset = 0; 24 | 25 | /// 26 | /// The number of tiles in the atlas texture that you want to extract and convert to tiles. 27 | /// 28 | public int extractNumber = 255; 29 | 30 | /// 31 | /// The number of tiles inside this palette. 32 | /// 33 | public int tilesCount = 0; 34 | 35 | 36 | // Editor only 37 | #if UNITY_EDITOR 38 | /// 39 | /// Array that stores all the temporary tiles inside this palette. 40 | /// 41 | public Texture2D[] temporaryTileTextureArray = new Texture2D[256]; 42 | 43 | /// 44 | /// Editor warning messages. 45 | /// 46 | private readonly string[] m_warning = new[] 47 | { 48 | "3D Tilemap System: There is no texture attached to the Atlas Texture field. Please add a texture and try again!", 49 | "3D Tilemap System: The atlas texture is not readable. Please, check the Read/Write Enabled option in the texture import settings to be able to perform the conversion.", 50 | "3D Tilemap System: Action aborted! The tile Pack is already full." 51 | }; 52 | 53 | /// 54 | /// Called by the custom reset button. 55 | /// 56 | public void ResetAsset() 57 | { 58 | DeleteTiles(); 59 | tileSize = 32; 60 | gridOffset = 0; 61 | tilesCount = 0; 62 | atlasTexture = null; 63 | } 64 | 65 | /// 66 | /// Delete all the temporary tile inside this palette. 67 | /// 68 | public void DeleteTiles() 69 | { 70 | for (int i = 0; i < 256; i++) 71 | { 72 | if (!temporaryTileTextureArray[i]) continue; 73 | 74 | DestroyImmediate(temporaryTileTextureArray[i], true); 75 | } 76 | 77 | tilesCount = 0; 78 | 79 | if (AssetDatabase.Contains(this)) 80 | { 81 | AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(this)); 82 | EditorGUIUtility.PingObject(this); 83 | } 84 | } 85 | 86 | /// 87 | /// Extracts all the tiles of the atlas texture and save inside this pallete as .asset file. 88 | /// 89 | public void ConvertAtlasToTiles() 90 | { 91 | if (!atlasTexture) 92 | { 93 | Debug.LogWarning(m_warning[0]); 94 | return; 95 | } 96 | 97 | var texturePath = AssetDatabase.GetAssetPath(atlasTexture); 98 | var textureImporter = (TextureImporter)AssetImporter.GetAtPath(texturePath); 99 | if(!textureImporter.isReadable) 100 | { 101 | Debug.LogWarning(m_warning[1]); 102 | return; 103 | } 104 | 105 | bool isFree = false; 106 | for (int i = 0; i < 256; i++) 107 | { 108 | if (temporaryTileTextureArray[i]) continue; 109 | isFree = true; 110 | } 111 | 112 | if (!isFree) 113 | { 114 | Debug.LogWarning(m_warning[2]); 115 | return; 116 | } 117 | 118 | // Calculates the amount of tiles in the atlas texture 119 | var horizontalColumns = atlasTexture.width / (tileSize + gridOffset); 120 | var verticalColumns = atlasTexture.height / (tileSize + gridOffset); 121 | 122 | // The tile index currently being scanned 123 | var tileIndex = 0; 124 | 125 | // Scans each tile of the atlas texture 126 | for (var y = verticalColumns -1; y >= 0; y--) 127 | { 128 | for (var x = 0; x < horizontalColumns; x++) 129 | { 130 | if (tileIndex > 255 || tileIndex >= extractNumber) break; 131 | while (temporaryTileTextureArray[tileIndex] && tileIndex < 255) 132 | { 133 | tileIndex++; 134 | } 135 | 136 | if (temporaryTileTextureArray[tileIndex]) continue; 137 | 138 | // Get the color of the current tile from the atlas texture 139 | var tileColor = atlasTexture.GetPixels(x * (tileSize + gridOffset) + gridOffset, y * (tileSize + gridOffset) + gridOffset, tileSize, tileSize); 140 | 141 | // Create the tile texture 142 | temporaryTileTextureArray[tileIndex] = new Texture2D(tileSize, tileSize, TextureFormat.ARGB32, false, true) 143 | { 144 | name = "Tile" + tileIndex, 145 | filterMode = FilterMode.Point, 146 | alphaIsTransparency = true, 147 | wrapMode = TextureWrapMode.Repeat, 148 | hideFlags = HideFlags.DontSaveInBuild 149 | }; 150 | 151 | // Paste the tile color to new tile texture 152 | temporaryTileTextureArray[tileIndex].SetPixels(tileColor); 153 | temporaryTileTextureArray[tileIndex].Apply(); 154 | 155 | // Save the new tile texture into this palette as .asset file 156 | AssetDatabase.AddObjectToAsset(temporaryTileTextureArray[tileIndex], this); 157 | 158 | // Go to the next tile 159 | tileIndex++; 160 | tilesCount++; 161 | } 162 | } 163 | 164 | // Refresh the project window 165 | AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(this)); 166 | EditorGUIUtility.PingObject(this); 167 | } 168 | #endif 169 | } 170 | } -------------------------------------------------------------------------------- /3D Tilemap System/Scripts/TilePalette.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 53238153853032b49a5f0ef130f9b7ed 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /3D Tilemap System/Scripts/TilemapData.cs: -------------------------------------------------------------------------------- 1 | namespace UnityEngine.TilemapSystem3D 2 | { 3 | public class TilemapData : ScriptableObject 4 | { 5 | [HideInInspector] public Texture3D tilemapTexture; 6 | [HideInInspector] public Texture3D tilesetTexture; 7 | [HideInInspector] public Texture2D layerArrayTexture; 8 | [HideInInspector] public int[] autoTileArrayMap; 9 | 10 | // Editor only 11 | #if UNITY_EDITOR 12 | [HideInInspector] public TilemapSettings settingsState; 13 | [HideInInspector] public LayerClipboard layerClipboard; 14 | public float[] layerIntensity; 15 | #endif 16 | } 17 | } -------------------------------------------------------------------------------- /3D Tilemap System/Scripts/TilemapData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 516326f854c8ce74cbd3ac6ed151a1e0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /3D Tilemap System/Scripts/TilemapSystem3D.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | /// 4 | /// This script file contains only the runtime stuffs of the 'TilemapSystem3D' class. 5 | /// 6 | namespace UnityEngine.TilemapSystem3D 7 | { 8 | [AddComponentMenu("Tilemap/3D Tilemap System")] 9 | [ExecuteInEditMode] 10 | public partial class TilemapSystem3D : MonoBehaviour 11 | { 12 | /// 13 | /// The shader used by the Standard Render Pipeline. 14 | /// 15 | public Shader legacyShader; 16 | 17 | /// 18 | /// The shader used by the Universal Render Pipeline. 19 | /// 20 | public Shader universalShader; 21 | 22 | /// 23 | /// The render pipeline used in this project. 24 | /// 25 | public TilemapSystemPipeline renderPipeline = TilemapSystemPipeline.Legacy; 26 | 27 | /// 28 | /// The resolution of the 3D Tileset texture. 29 | /// 30 | public int tilesetSize = 32; 31 | 32 | /// 33 | /// The size of the 3D Tilemap texture. It should be proportional to the terrain size or mesh uv. 34 | /// 35 | public Vector4 gridMapSize = new Vector4(32, 32, 1, 1); 36 | 37 | /// 38 | /// Stores the data of the current tilemap. 39 | /// 40 | public TilemapData tilemapData; 41 | 42 | /// 43 | /// The list of all layers in this tilemap. 44 | /// 45 | public List tilemapLayerList; 46 | 47 | /// 48 | /// Texture containing the tilemap data, it is used by the render material to determine which tile should be 49 | /// rendered in each grid position. 50 | /// 51 | public Texture3D tilemapTexture; 52 | 53 | /// 54 | /// Pack texture containing all the tiles used by the painting system. 55 | /// 56 | public Texture3D tilesetTexture; 57 | 58 | /// 59 | /// Texture used to store the tiles count and alpha intensity of each layer. 60 | /// In this situation is better to use a texture than a regular array because we can resize the texture every 61 | /// time we want, what is not possible with a shader array. 62 | /// Each pixel of this texture will store the data of the corespondent layer from the layer list. 63 | /// Channel R: Stores the tiles count on that layer. 64 | /// Channel G: Stores the alpha intensity of that layer. 65 | /// 66 | public Texture2D layerArrayTexture; 67 | 68 | /// 69 | /// The material used to render the tilemap system on the mesh. 70 | /// 71 | public Material renderMaterial; 72 | 73 | /// 74 | /// A block of material values to apply to the renderer component. 75 | /// 76 | public MaterialPropertyBlock materialPropertyBlock; 77 | 78 | /// 79 | /// Cached material property index. 80 | /// 81 | private static readonly int TilemapTexture = Shader.PropertyToID("_TilemapTexture"); 82 | private static readonly int TilesetTexture = Shader.PropertyToID("_TilesetTexture"); 83 | private static readonly int LayerArrayTexture = Shader.PropertyToID("_LayerArrayTexture"); 84 | private static readonly int LayersCount = Shader.PropertyToID("_LayersCount"); 85 | private static readonly int TilesCount = Shader.PropertyToID("_TilesCount"); 86 | private static readonly int GridMapSize = Shader.PropertyToID("_GridMapSize"); 87 | 88 | /// 89 | /// Translate the result from the auto tile bitmasking computation to correct layout index. 90 | /// 91 | private readonly Dictionary m_8BitMasking = new Dictionary() 92 | { 93 | {0, 0}, {1, 1}, {4, 2}, {5, 3}, {7, 4}, {16, 5}, {17, 6}, {20, 7}, {21, 8}, {23, 9}, {28, 10}, {29, 11}, {31, 12}, {64, 13}, {65, 14}, {68, 15}, 94 | {69, 16}, {71, 17}, {80, 18}, {81, 19}, {84, 20}, {85, 21}, {87, 22}, {92, 23}, {93, 24}, {95, 25}, {112, 26}, {113, 27}, {116, 28}, {117, 29}, {119, 30}, {124, 31}, 95 | {125, 32}, {127, 33}, {193, 34}, {197, 35}, {199, 36}, {209, 37}, {213, 38}, {215, 39}, {221, 40}, {223, 41}, {241, 42}, {245, 43}, {247, 44}, {253, 45}, {255, 46} 96 | }; 97 | 98 | /// 99 | /// Called at start. 100 | /// 101 | private void Start() 102 | { 103 | if(tilemapData) 104 | { 105 | // Get the texture references stored in the TilemapData 106 | tilemapTexture = tilemapData.tilemapTexture; 107 | tilesetTexture = tilemapData.tilesetTexture; 108 | layerArrayTexture = tilemapData.layerArrayTexture; 109 | 110 | // Refresh the render material 111 | UpdateRenderMaterial(); 112 | 113 | // Editor only 114 | #if UNITY_EDITOR 115 | UpdateLayerSettings(); 116 | #endif 117 | } 118 | } 119 | 120 | /// 121 | /// Called every frame. 122 | /// 123 | private void Update() 124 | { 125 | // For an unknown reason, the render material is reseted every time the scene is saved. 126 | // So it is necessary to update the render material every frame only in the editor. 127 | // This is not necessary in the build and is not recommended for performance reasons. 128 | #if UNITY_EDITOR 129 | if (tilemapData) 130 | UpdateRenderMaterial(); 131 | #endif 132 | } 133 | 134 | /// 135 | /// Update the render material. 136 | /// 137 | public void UpdateRenderMaterial() 138 | { 139 | // Update the material property block 140 | if (materialPropertyBlock == null) 141 | materialPropertyBlock = new MaterialPropertyBlock(); 142 | 143 | materialPropertyBlock.SetTexture(TilemapTexture, tilemapTexture); 144 | materialPropertyBlock.SetTexture(TilesetTexture, tilesetTexture); 145 | materialPropertyBlock.SetTexture(LayerArrayTexture, layerArrayTexture); 146 | materialPropertyBlock.SetInt(LayersCount, tilemapTexture.depth); 147 | materialPropertyBlock.SetInt(TilesCount, tilesetTexture.depth); 148 | materialPropertyBlock.SetVector(GridMapSize, gridMapSize); 149 | 150 | // Update the render material properties 151 | renderMaterial.SetTexture(TilemapTexture, tilemapTexture); 152 | renderMaterial.SetTexture(TilesetTexture, tilesetTexture); 153 | renderMaterial.SetTexture(LayerArrayTexture, layerArrayTexture); 154 | renderMaterial.SetInt(LayersCount, tilemapTexture.depth); 155 | materialPropertyBlock.SetInt(TilesCount, tilesetTexture.depth); 156 | materialPropertyBlock.SetVector(GridMapSize, gridMapSize); 157 | 158 | // Set the material to the terrain or custom mesh 159 | //#if UNITY_EDITOR 160 | Terrain terrainComponent = gameObject.GetComponent(); 161 | if (terrainComponent) 162 | { 163 | terrainComponent.materialTemplate = renderMaterial; 164 | terrainComponent.SetSplatMaterialPropertyBlock(materialPropertyBlock); 165 | } 166 | 167 | Renderer rendererComponent = gameObject.GetComponent(); 168 | if (rendererComponent) 169 | { 170 | rendererComponent.material = renderMaterial; 171 | rendererComponent.SetPropertyBlock(materialPropertyBlock); 172 | } 173 | //#endif 174 | } 175 | 176 | /// 177 | /// Sets the alpha intensity of a given layer. 178 | /// 179 | public void SetLayerIntensity(int layer, float intensity) 180 | { 181 | if (layerArrayTexture) 182 | { 183 | intensity = Mathf.Clamp01(intensity); 184 | tilemapLayerList[layer].intensity = intensity; 185 | Color32 color = layerArrayTexture.GetPixel(layer, 0); 186 | color.g = (byte)(intensity * 255); 187 | layerArrayTexture.SetPixel(layer, 0, color); 188 | layerArrayTexture.Apply(); 189 | } 190 | } 191 | 192 | /// 193 | /// Gets the alpha intensity of a given layer. 194 | /// 195 | public float GetLayerIntensity(int layer) 196 | { 197 | return tilemapLayerList[layer].intensity; 198 | } 199 | 200 | /// 201 | /// Pickup the index of the clicked tile on the mesh. 202 | /// 203 | public int PickupTile(int x, int y, int layer) 204 | { 205 | return (int) (tilemapTexture.GetPixel(x, y, layer).r * 255); 206 | } 207 | 208 | /// 209 | /// Paint a tile on the mesh. 210 | /// 211 | public void PaintTile(int x, int y, int index, int layer) 212 | { 213 | index = Mathf.Clamp(index, 0, tilemapLayerList[layer].tilePalette.tilesCount - 1); 214 | 215 | if (index > 0) 216 | tilemapLayerList[layer].autoTileMapArray[(y * tilemapTexture.width) + x] = true; 217 | else 218 | tilemapLayerList[layer].autoTileMapArray[(y * tilemapTexture.width) + x] = false; 219 | 220 | tilemapTexture.SetPixel(x, y, layer, new Color32((byte) index, 0, 0, 0)); 221 | tilemapTexture.Apply(); 222 | } 223 | 224 | // Based on "TextureFloodFill" from: 225 | // https://wiki.unity3d.com/index.php/TextureFloodFill 226 | /// 227 | /// Fill a layer region with a tile. 228 | /// 229 | public void FillTile(int x, int y, int index, int layer) 230 | { 231 | index = Mathf.Clamp(index, 0, tilemapLayerList[layer].tilePalette.tilesCount - 1); 232 | Texture2D tempTexture2D = GetTexture3DSlice(tilemapTexture, layer); 233 | var width = tilemapTexture.width; 234 | var height = tilemapTexture.height; 235 | var colors = tempTexture2D.GetPixels32(); 236 | var refCol = colors[x + y * width]; 237 | var nodes = new Queue(); 238 | nodes.Enqueue(new Vector2Int(x, y)); 239 | 240 | while (nodes.Count > 0) 241 | { 242 | var currentPoint = nodes.Dequeue(); 243 | 244 | for (var i = currentPoint.x; i < width; i++) 245 | { 246 | int C = colors[i + currentPoint.y * width].r; 247 | if (C != refCol.r || C == index) 248 | break; 249 | colors[i + currentPoint.y * width] = new Color32((byte)index, 0, 0, 0); 250 | if (currentPoint.y + 1 < height) 251 | { 252 | C = colors[i + currentPoint.y * width + width].r; 253 | if (C == refCol.r && C != index) 254 | nodes.Enqueue(new Vector2Int(i, currentPoint.y + 1)); 255 | } 256 | 257 | if (currentPoint.y - 1 < 0) continue; 258 | 259 | C = colors[i + currentPoint.y * width - width].r; 260 | if (C == refCol.r && C != index) 261 | nodes.Enqueue(new Vector2Int(i, currentPoint.y - 1)); 262 | } 263 | 264 | for (var i = currentPoint.x - 1; i >= 0; i--) 265 | { 266 | int C = colors[i + currentPoint.y * width].r; 267 | if (C != refCol.r || C == index) 268 | break; 269 | colors[i + currentPoint.y * width] = new Color32((byte)index, 0, 0, 0); 270 | if (currentPoint.y + 1 < height) 271 | { 272 | C = colors[i + currentPoint.y * width + width].r; 273 | if (C == refCol.r && C != index) 274 | nodes.Enqueue(new Vector2Int(i, currentPoint.y + 1)); 275 | } 276 | 277 | if (currentPoint.y - 1 < 0) continue; 278 | 279 | C = colors[i + currentPoint.y * width - width].r; 280 | if (C == refCol.r && C != index) 281 | nodes.Enqueue(new Vector2Int(i, currentPoint.y - 1)); 282 | } 283 | } 284 | 285 | tempTexture2D.SetPixels32(colors); 286 | tempTexture2D.Apply(); 287 | SetTexture3DSlice(tempTexture2D, tilemapTexture, layer); 288 | } 289 | 290 | /// 291 | /// Perform the auto tile painting. 292 | /// 293 | public void PaintAutoTile(int x, int y, int layoutIndex, int layer) 294 | { 295 | int autoTileMapX = x; 296 | int autoTileMapY = y; 297 | int north; 298 | int northEast; 299 | int east; 300 | int southEast; 301 | int south; 302 | int southWest; 303 | int west; 304 | int northWest; 305 | int autoTileIndex; 306 | 307 | tilemapLayerList[layer].autoTileMapArray[y * tilemapTexture.width + x] = true; 308 | 309 | // Compute the center tile 310 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 311 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 312 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 313 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 314 | // if top = 0: topLeft = 0, topRight = 0 315 | // if left = 0: topLeft = 0, bottomLeft = 0 316 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 317 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 318 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 319 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 320 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 321 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 322 | 323 | // Compute the north tile 324 | autoTileMapX = x; 325 | autoTileMapY = y + 1; 326 | if (GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY)) 327 | { 328 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 329 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 330 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 331 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 332 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 333 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 334 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 335 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 336 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 337 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 338 | } 339 | 340 | // Compute the north-east tile 341 | autoTileMapX = x + 1; 342 | autoTileMapY = y + 1; 343 | if (GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY)) 344 | { 345 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 346 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 347 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 348 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 349 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 350 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 351 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 352 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 353 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 354 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 355 | } 356 | 357 | // Compute the east tile 358 | autoTileMapX = x + 1; 359 | autoTileMapY = y; 360 | if (GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY)) 361 | { 362 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 363 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 364 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 365 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 366 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 367 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 368 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 369 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 370 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 371 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 372 | } 373 | 374 | // Compute the east-south tile 375 | autoTileMapX = x + 1; 376 | autoTileMapY = y - 1; 377 | if (GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY)) 378 | { 379 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 380 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 381 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 382 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 383 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 384 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 385 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 386 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 387 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 388 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 389 | } 390 | 391 | // Compute the south tile 392 | autoTileMapX = x; 393 | autoTileMapY = y - 1; 394 | if (GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY)) 395 | { 396 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 397 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 398 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 399 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 400 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 401 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 402 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 403 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 404 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 405 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 406 | } 407 | 408 | // Compute the south-west tile 409 | autoTileMapX = x - 1; 410 | autoTileMapY = y - 1; 411 | if (GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY)) 412 | { 413 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 414 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 415 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 416 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 417 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 418 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 419 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 420 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 421 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 422 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 423 | } 424 | 425 | // Compute the west tile 426 | autoTileMapX = x - 1; 427 | autoTileMapY = y ; 428 | if (GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY)) 429 | { 430 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 431 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 432 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 433 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 434 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 435 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 436 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 437 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 438 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 439 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 440 | } 441 | 442 | // Compute the west-north tile 443 | autoTileMapX = x - 1; 444 | autoTileMapY = y + 1; 445 | if (GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY)) 446 | { 447 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 448 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 449 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 450 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 451 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 452 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 453 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 454 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 455 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 456 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 457 | } 458 | 459 | tilemapTexture.Apply(); 460 | } 461 | 462 | /// 463 | /// Erase the tile from the auto tile array map. 464 | /// 465 | public void EraseAutoTile(int x, int y, int layoutIndex, int layer) 466 | { 467 | int autoTileMapX = x; 468 | int autoTileMapY = y; 469 | int north; 470 | int northEast; 471 | int east; 472 | int southEast; 473 | int south; 474 | int southWest; 475 | int west; 476 | int northWest; 477 | int autoTileIndex; 478 | 479 | // Erase the clicked tile 480 | tilemapLayerList[layer].autoTileMapArray[y * tilemapTexture.width + x] = false; 481 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) 0, 0, 0, 0)); 482 | 483 | // Compute the north tile 484 | autoTileMapX = x; 485 | autoTileMapY = y + 1; 486 | if (GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY)) 487 | { 488 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 489 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 490 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 491 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 492 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 493 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 494 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 495 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 496 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 497 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 498 | } 499 | 500 | // Compute the north-east tile 501 | autoTileMapX = x + 1; 502 | autoTileMapY = y + 1; 503 | if (GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY)) 504 | { 505 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 506 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 507 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 508 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 509 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 510 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 511 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 512 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 513 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 514 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 515 | } 516 | 517 | // Compute the east tile 518 | autoTileMapX = x + 1; 519 | autoTileMapY = y; 520 | if (GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY)) 521 | { 522 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 523 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 524 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 525 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 526 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 527 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 528 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 529 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 530 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 531 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 532 | } 533 | 534 | // Compute the east-south tile 535 | autoTileMapX = x + 1; 536 | autoTileMapY = y - 1; 537 | if (GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY)) 538 | { 539 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 540 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 541 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 542 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 543 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 544 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 545 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 546 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 547 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 548 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 549 | } 550 | 551 | // Compute the south tile 552 | autoTileMapX = x; 553 | autoTileMapY = y - 1; 554 | if (GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY)) 555 | { 556 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 557 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 558 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 559 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 560 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 561 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 562 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 563 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 564 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 565 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 566 | } 567 | 568 | // Compute the south-west tile 569 | autoTileMapX = x - 1; 570 | autoTileMapY = y - 1; 571 | if (GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY)) 572 | { 573 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 574 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 575 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 576 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 577 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 578 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 579 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 580 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 581 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 582 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 583 | } 584 | 585 | // Compute the west tile 586 | autoTileMapX = x - 1; 587 | autoTileMapY = y ; 588 | if (GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY)) 589 | { 590 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 591 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 592 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 593 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 594 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 595 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 596 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 597 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 598 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 599 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 600 | } 601 | 602 | // Compute the west-north tile 603 | autoTileMapX = x - 1; 604 | autoTileMapY = y + 1; 605 | if (GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY)) 606 | { 607 | north = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY + 1) ? 1 : 0; 608 | east = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray,autoTileMapX + 1, autoTileMapY) ? 4 : 0; 609 | south = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX, autoTileMapY - 1) ? 16 : 0; 610 | west = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY) ? 64 : 0; 611 | northEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY + 1) && north != 0 && east != 0 ? 2 : 0; 612 | southEast = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX + 1, autoTileMapY - 1) && south != 0 && east != 0 ? 8 : 0; 613 | southWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY - 1) && south != 0 && west != 0 ? 32 : 0; 614 | northWest = GetArrayMapIndex(tilemapLayerList[layer].autoTileMapArray, autoTileMapX - 1, autoTileMapY + 1) && north != 0 && west != 0 ? 128 : 0; 615 | autoTileIndex = north + northEast + east + southEast + south + southWest + west + northWest; 616 | tilemapTexture.SetPixel(autoTileMapX, autoTileMapY, layer, new Color32((byte) tilemapLayerList[layer].autoTileList[layoutIndex].id[m_8BitMasking[autoTileIndex]], 0, 0, 0)); 617 | } 618 | 619 | tilemapTexture.Apply(); 620 | } 621 | 622 | /// 623 | /// Copy a tilemap slice and save into a Texture2D. 624 | /// 625 | private Texture2D GetTexture3DSlice(Texture3D texture, int depth) 626 | { 627 | // Creates the temporary Texture2D 628 | Texture2D tempTexture = new Texture2D(texture.width, texture.height, texture.format, false) 629 | { 630 | name = "Slice Texture", 631 | filterMode = FilterMode.Point, 632 | wrapMode = TextureWrapMode.Clamp, 633 | anisoLevel = 0 634 | }; 635 | 636 | // Copy the 3D texture slice color to the temporary Texture2D 637 | for (int i = 0; i < texture.width; i++) 638 | { 639 | for (int j = 0; j < texture.height; j++) 640 | { 641 | Color32 tempColor = texture.GetPixel(i, j, depth); 642 | tempTexture.SetPixel(i, j, tempColor); 643 | } 644 | } 645 | 646 | // Apply the changes to the temporary Texture2D and return 647 | tempTexture.Apply(); 648 | return tempTexture; 649 | } 650 | 651 | /// 652 | /// Paste a Texture2D to a tilemap slice. 653 | /// 654 | private void SetTexture3DSlice(Texture2D sourceTex2D, Texture3D targetTex3D, int depth) 655 | { 656 | // Get the color of the source Texture2D 657 | Color32[] newColor = sourceTex2D.GetPixels32(); 658 | 659 | // Used to access each index of the color array 660 | int index = 0; 661 | 662 | // Paste the Texture2D color into the tilemap slice pixel by pixel 663 | for (int i = 0; i < targetTex3D.width; i++) 664 | { 665 | for (int j = 0; j < targetTex3D.height; j++) 666 | { 667 | targetTex3D.SetPixel(j, i, depth, newColor[index]); 668 | index++; 669 | } 670 | } 671 | 672 | // Apply the changes to the tilemap texture 673 | targetTex3D.Apply(); 674 | } 675 | 676 | /// 677 | /// Get the value of an array using a 2D coordinate as a parameter. 678 | /// 679 | private bool GetArrayMapIndex(bool[] array, int x, int y) 680 | { 681 | if (x >= 0 && y >= 0 && x < tilemapTexture.width && y < tilemapTexture.height) 682 | return array[y * tilemapTexture.width + x]; 683 | else 684 | return false; 685 | } 686 | } 687 | } -------------------------------------------------------------------------------- /3D Tilemap System/Scripts/TilemapSystem3D.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7040d198a41a5574bbbcfda0058a088d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: 7 | - legacyShader: {fileID: 4800000, guid: 5594d6040eb13d54db5449d867e57ea0, type: 3} 8 | - universalShader: {fileID: 4800000, guid: 0400508317e303b4683b2d7fa99ba81e, type: 3} 9 | - tilemapData: {instanceID: 0} 10 | - tilemapTexture: {instanceID: 0} 11 | - tilesetTexture: {instanceID: 0} 12 | - layerArrayTexture: {instanceID: 0} 13 | - renderMaterial: {instanceID: 0} 14 | - defaultColorTexture: {fileID: 2800000, guid: fc2536f26d8023b49872f89b877b5a4d, 15 | type: 3} 16 | executionOrder: 0 17 | icon: {instanceID: 0} 18 | userData: 19 | assetBundleName: 20 | assetBundleVariant: 21 | -------------------------------------------------------------------------------- /3D Tilemap System/Scripts/Utilities.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1e4cb54a43925494f986ad1e4342f864 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /3D Tilemap System/Scripts/Utilities/TilemapSystem3DEditorStuffs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | #if UNITY_EDITOR 3 | using UnityEditor; 4 | #endif 5 | 6 | /// 7 | /// This script file contains only the editor stuffs of the 'TilemapSystem3D' class. 8 | /// 9 | namespace UnityEngine.TilemapSystem3D 10 | { 11 | public partial class TilemapSystem3D : MonoBehaviour 12 | { 13 | // Editor only 14 | #if UNITY_EDITOR 15 | /// 16 | /// The texture used to apply the default color to the mesh while a tileset does not yet exist. 17 | /// 18 | public Texture2D defaultColorTexture; 19 | 20 | /// 21 | /// The current tilemap layer selected for painting. 22 | /// 23 | [NonSerialized] public int layerIndex = 0; 24 | 25 | /// 26 | /// The current tile selected for painting. 27 | /// 28 | [NonSerialized] public int tileIndex = 0; 29 | 30 | /// 31 | /// The current tool selected for painting. 32 | /// 33 | [NonSerialized] public int toolIndex = 0; 34 | 35 | /// 36 | /// Select the feature used to paint the tiles. 37 | /// 38 | public TilemapSystemPaintingMode paintingMode = TilemapSystemPaintingMode.Default; 39 | 40 | // Controls the foldout header groups 41 | public bool showReferencesGroup = true; 42 | public bool showSettingsGroup = true; 43 | public bool showDataGroup = true; 44 | public bool showPantingGroup = true; 45 | public bool showAutoTileGroup = true; 46 | public bool showRandomTilePaintingGroup = false; 47 | public bool showRandomizeTileGroup = false; 48 | public bool showTileBrushesGroup = false; 49 | public bool showAboutGroup = true; 50 | 51 | /// 52 | /// Creates the textures and material used by the Tilemap System. 53 | /// 54 | public void GenerateTilemapData() 55 | { 56 | // If the tilemap data does not yet exist 57 | if (!tilemapData) 58 | { 59 | // Displays the "save file" dialog and returns the selected path name 60 | var savePath = EditorUtility.SaveFilePanel 61 | ( 62 | "Select the folder directory were the tilemap data should be saved", 63 | Application.dataPath, 64 | "Tilemap Data", 65 | "asset" 66 | ); 67 | 68 | // Checks if the path name is valid, otherwise returns 69 | if (savePath.Length <= 0) return; 70 | 71 | // Edit the path to be relative to the project folder 72 | savePath = savePath.Replace(Application.dataPath, "Assets"); 73 | 74 | // Delete the previous file 75 | if (System.IO.File.Exists(savePath)) AssetDatabase.DeleteAsset(savePath); 76 | 77 | // Create the tilemap data 78 | tilemapData = ScriptableObject.CreateInstance(); 79 | 80 | // Save the tilemap data as .asset file 81 | AssetDatabase.CreateAsset(tilemapData, savePath); 82 | 83 | // Create the 3D Tilemap texture 84 | CreateTilemapTexture(); 85 | 86 | // Create the 3D Tileset texture 87 | CreateTilesetTexture(); 88 | 89 | // Create the layer data array texture 90 | CreateLayerDataArray(); 91 | 92 | // Create the render material 93 | switch (renderPipeline) 94 | { 95 | case TilemapSystemPipeline.Legacy: 96 | CreateRenderMaterial(legacyShader); 97 | break; 98 | 99 | case TilemapSystemPipeline.Universal: 100 | CreateRenderMaterial(universalShader); 101 | break; 102 | } 103 | 104 | // Update material 105 | UpdateRenderMaterial(); 106 | 107 | // Ping the tilemap data to refresh the editor. 108 | EditorGUIUtility.PingObject(tilemapData); 109 | return; 110 | } 111 | 112 | // Update the tilemap texture 113 | UpdateTilemapTexture(); 114 | 115 | // Update the tileset texture 116 | UpdateTilesetTexture(); 117 | 118 | // Update the layer data array texture 119 | UpdateLayerDataArray(); 120 | 121 | // Update material 122 | UpdateRenderMaterial(); 123 | 124 | // Whenever a new texture is created, its old version is deleted and the new texture is referenced to the variable. 125 | // But if you don't save the scene, the new texture reference will be lost and when you open the scene again, the 126 | // variable will try to access the old texture that no longer exists. So the solution is to use the TilemapData to 127 | // store the new references and load it again at Start(). 128 | tilemapData.tilemapTexture = tilemapTexture; 129 | tilemapData.tilesetTexture = tilesetTexture; 130 | tilemapData.layerArrayTexture = layerArrayTexture; 131 | 132 | // Ping the tilemap data to refresh the editor 133 | EditorGUIUtility.PingObject(tilemapData); 134 | } 135 | 136 | /// 137 | /// Creates a black 3D Tilemap texture. 138 | /// 139 | private void CreateTilemapTexture() 140 | { 141 | int width = (int)gridMapSize.x; 142 | int height = (int)gridMapSize.y; 143 | int depth = tilemapLayerList.Count; 144 | 145 | // Starts the temporary colors full black. 146 | Color32[] tempColor = new Color32[width * height * depth]; 147 | 148 | // Create the 3D tilemap texture 149 | tilemapTexture = new Texture3D(width, height, depth, TextureFormat.R8, false) 150 | { 151 | name = "Tilemap Texture", 152 | filterMode = FilterMode.Point, 153 | wrapMode = TextureWrapMode.Clamp, 154 | anisoLevel = 0 155 | }; 156 | 157 | // Apply the colors to the tilemap texture 158 | tilemapTexture.SetPixels32(tempColor); 159 | tilemapTexture.Apply(); 160 | 161 | // Save the tilemap texture as .asset file 162 | AssetDatabase.AddObjectToAsset(tilemapTexture, tilemapData); 163 | AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(tilemapTexture)); 164 | } 165 | 166 | /// 167 | /// Updates the 3D Tilemap texture when any important settings are changed. 168 | /// 169 | private void UpdateTilemapTexture() 170 | { 171 | int width = (int)gridMapSize.x; 172 | int height = (int)gridMapSize.y; 173 | int depth = tilemapLayerList.Count; 174 | 175 | // If the user changes the grid map size, the 3D Tilemap texture will need to be resized and 176 | // the map data for each layer will be lost. 177 | // So there is no alternative but to just create a new blank tilemap texture and return 178 | if (width != tilemapTexture.width || height != tilemapTexture.height) 179 | { 180 | DestroyImmediate(tilemapTexture, true); 181 | CreateTilemapTexture(); 182 | return; 183 | } 184 | 185 | // Copy the current color of the tilemap texture 186 | Color32[] oldColor = tilemapTexture.GetPixels32(); 187 | 188 | // Destroy the tilemap texture to create it again in the next step 189 | DestroyImmediate(tilemapTexture, true); 190 | 191 | // Recreate the tilemap texture with the new layer settings 192 | tilemapTexture = new Texture3D(width, height, depth, TextureFormat.R8, false) 193 | { 194 | name = "Tilemap Texture", 195 | filterMode = FilterMode.Point, 196 | wrapMode = TextureWrapMode.Clamp, 197 | anisoLevel = 0 198 | }; 199 | 200 | // Creates the new color array 201 | Color32[] newColor = new Color32[width * height * depth]; 202 | 203 | // Paste the old color to the new tilemap texture 204 | if (newColor.Length < oldColor.Length) 205 | { 206 | for (int i = 0; i < newColor.Length; i++) 207 | { 208 | newColor[i] = oldColor[i]; 209 | } 210 | } 211 | 212 | if (newColor.Length >= oldColor.Length) 213 | { 214 | for (int i = 0; i < oldColor.Length; i++) 215 | { 216 | newColor[i] = oldColor[i]; 217 | } 218 | } 219 | 220 | // Apply the changes to the new tilemap texture 221 | tilemapTexture.SetPixels32(newColor); 222 | tilemapTexture.Apply(); 223 | 224 | // Save the new tilemap texture as .asset file 225 | AssetDatabase.AddObjectToAsset(tilemapTexture, tilemapData); 226 | AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(tilemapTexture)); 227 | } 228 | 229 | /// 230 | /// Creates the 3D Tileset texture with a default color. 231 | /// 232 | private void CreateTilesetTexture() 233 | { 234 | int width = defaultColorTexture.width; 235 | int height = defaultColorTexture.height; 236 | int depth = 1; 237 | 238 | // Copy the default color texture to the temporary color array 239 | Color32[] tempColors = defaultColorTexture.GetPixels32(); 240 | 241 | // Create the 3D tileset texture 242 | tilesetTexture = new Texture3D(width, height, depth, TextureFormat.RGBA32, false) 243 | { 244 | name = "Tileset Texture", 245 | filterMode = FilterMode.Point, 246 | wrapMode = TextureWrapMode.Repeat, 247 | anisoLevel = 0 248 | }; 249 | 250 | // Apply the colors to the tileset texture 251 | tilesetTexture.SetPixels32(tempColors); 252 | tilesetTexture.Apply(); 253 | 254 | // Save the tileset texture as .asset file 255 | AssetDatabase.AddObjectToAsset(tilesetTexture, tilemapData); 256 | AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(tilesetTexture)); 257 | } 258 | 259 | /// 260 | /// Updates the 3D Tileset texture when any important settings are changed. 261 | /// 262 | private void UpdateTilesetTexture() 263 | { 264 | // Get the tile palette of each layer 265 | TilePalette[] paletteList = new TilePalette[tilemapLayerList.Count]; 266 | for (int i = 0; i < tilemapLayerList.Count; i++) 267 | { 268 | paletteList[i] = tilemapLayerList[i].tilePalette; 269 | } 270 | 271 | // Get the total number of tiles in all the palettes 272 | var tilesCount = 0; 273 | for (var i = 0; i < paletteList.Length; i++) 274 | { 275 | if (paletteList[i]) 276 | { 277 | tilesCount += paletteList[i].tilesCount; 278 | 279 | // Return if the tile palette is empty 280 | if (paletteList[i].tilesCount == 0) 281 | { 282 | Debug.LogWarning("3D Tilemap System: Can't pack the 3D Tileset texture because the Tile Palette field of the Layer" + i + " is empty. Please, add the tiles to the Tile Palette first and try to regenerate the Tilemap Data again."); 283 | return; 284 | } 285 | 286 | // Return if the tiles size in the palette do not match with the 3D Tileset texture size 287 | if (paletteList[i].tileSize != tilesetSize) 288 | { 289 | Debug.LogWarning("3D Tilemap System: Can't pack the 3D Tileset texture because the tiles size in the Tile Palette of the Layer" + i + " do not match with the 3D Tileset texture size."); 290 | return; 291 | } 292 | } 293 | else 294 | { 295 | // Return if there is no tile palette attached to some layer 296 | Debug.LogWarning("3D Tilemap System: Can't pack the 3D Tileset texture because the Tile Palette field of the Layer" + i + " is null. Please, attach a Tile Palette to it and try to regenerate the Tilemap Data again."); 297 | return; 298 | } 299 | } 300 | 301 | // Delete the existing 3D Tileset texture before creating a new one 302 | DestroyImmediate(tilesetTexture, true); 303 | 304 | // Initialize the tileset texture 305 | tilesetTexture = new Texture3D(tilesetSize, tilesetSize, tilesCount + 1, TextureFormat.RGBA32, false) 306 | { 307 | name = "Tileset Texture", 308 | filterMode = FilterMode.Point, 309 | wrapMode = TextureWrapMode.Repeat, 310 | anisoLevel = 0 311 | }; 312 | 313 | // Pack the tiles from paletteList[] to Texture3D 314 | Color[] tilesetColor = tilesetTexture.GetPixels(); 315 | int layer = 0; 316 | int index = 0; 317 | int tileSize = tilesetTexture.width; 318 | 319 | for (int z = 0; z < tilesCount; z++) 320 | { 321 | var tileColor = paletteList[layer].temporaryTileTextureArray[index].GetPixels32(); 322 | 323 | for (int y = 0; y < tileSize; y++) 324 | { 325 | for (int x = 0; x < tileSize; x++) 326 | { 327 | tilesetColor[x + (y * tileSize) + (z * tileSize * tileSize)] = tileColor[x + (y * tileSize)]; 328 | } 329 | } 330 | 331 | index++; 332 | if (index >= paletteList[layer].tilesCount) 333 | { 334 | index = 0; 335 | layer++; 336 | } 337 | } 338 | 339 | // Apply the changes to the tileset texture 340 | tilesetTexture.SetPixels(tilesetColor); 341 | tilesetTexture.Apply(); 342 | 343 | // Save the tileset texture as .asset file 344 | AssetDatabase.AddObjectToAsset(tilesetTexture, tilemapData); 345 | AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(tilesetTexture)); 346 | } 347 | 348 | /// 349 | /// Create the Texture2D that will be used as an array in the shader. 350 | /// 351 | private void CreateLayerDataArray() 352 | { 353 | if (layerArrayTexture) 354 | DestroyImmediate(layerArrayTexture, true); 355 | 356 | layerArrayTexture = new Texture2D(1, 1, TextureFormat.RGBA32, false) 357 | { 358 | name = "Layer Array Texture", 359 | filterMode = FilterMode.Point, 360 | wrapMode = TextureWrapMode.Clamp, 361 | anisoLevel = 0 362 | }; 363 | 364 | // Apply the changes to the layer data texture 365 | layerArrayTexture.SetPixel(tilemapLayerList.Count, 1, new Color32(0, 255, 0, 0)); 366 | layerArrayTexture.Apply(); 367 | 368 | // Save the layer data texture as .asset file 369 | AssetDatabase.AddObjectToAsset(layerArrayTexture, tilemapData); 370 | AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(layerArrayTexture)); 371 | } 372 | 373 | /// 374 | /// Update the Texture2D used as an array in the shader. 375 | /// 376 | private void UpdateLayerDataArray() 377 | { 378 | int width = tilemapLayerList.Count; 379 | Color32[] layerData = new Color32[width]; 380 | TilePalette[] paletteList = new TilePalette[width]; 381 | 382 | for (int i = 0; i < width; i++) 383 | { 384 | paletteList[i] = tilemapLayerList[i].tilePalette; 385 | if (paletteList[i]) 386 | layerData[i].r = (byte)paletteList[i].tilesCount; 387 | layerData[i].g = (byte)(tilemapLayerList[i].intensity * 255); 388 | } 389 | 390 | DestroyImmediate(layerArrayTexture, true); 391 | 392 | layerArrayTexture = new Texture2D(width, 1, TextureFormat.RGBA32, false) 393 | { 394 | name = "Layer Array Texture", 395 | filterMode = FilterMode.Point, 396 | wrapMode = TextureWrapMode.Clamp, 397 | anisoLevel = 0 398 | }; 399 | 400 | // Apply the changes to the layer data texture 401 | layerArrayTexture.SetPixels32(layerData); 402 | layerArrayTexture.Apply(); 403 | 404 | // Save the layer data texture as .asset file 405 | AssetDatabase.AddObjectToAsset(layerArrayTexture, tilemapData); 406 | AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(layerArrayTexture)); 407 | } 408 | 409 | /// 410 | /// Create the material used to render the Tilemap System on the mesh. 411 | /// 412 | private void CreateRenderMaterial(Shader shader) 413 | { 414 | if (renderMaterial) return; 415 | 416 | renderMaterial = new Material(shader) 417 | { 418 | name = "Render Material" 419 | }; 420 | 421 | // Save the material as .asset file 422 | AssetDatabase.AddObjectToAsset(renderMaterial, tilemapData); 423 | AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(renderMaterial)); 424 | } 425 | 426 | /// 427 | /// Update the render material shader when there is a change in the render pipeline property. 428 | /// 429 | public void UpdateMaterialSettings() 430 | { 431 | if (!renderMaterial) return; 432 | 433 | switch (renderPipeline) 434 | { 435 | case TilemapSystemPipeline.Legacy: 436 | renderMaterial.shader = legacyShader; 437 | break; 438 | 439 | case TilemapSystemPipeline.Universal: 440 | renderMaterial.shader = universalShader; 441 | break; 442 | } 443 | } 444 | 445 | /// 446 | /// Copy the tilemap slice of the selected layer and save it temporarily into the clipboard property of the TilemapData 447 | /// 448 | public void CopyTilemapLayer(int layer) 449 | { 450 | if (!tilemapData) return; 451 | if (!tilemapTexture) return; 452 | if (tilemapTexture.depth < layer) return; 453 | tilemapData.layerClipboard = new LayerClipboard(layer, GetTexture3DSlice(tilemapTexture, layer)); 454 | } 455 | 456 | /// 457 | /// Paste the clipboard texture from the TilemapData to the tilemap slice of the selected layer. 458 | /// 459 | public void PasteTilemapLayer(int layer) 460 | { 461 | if (!tilemapData) return; 462 | if (!tilemapTexture) return; 463 | if (tilemapTexture.depth < layer) return; 464 | if (tilemapData.layerClipboard.layerIndex > tilemapTexture.depth) return; 465 | if (!tilemapData.layerClipboard.tilemapSlice) return; 466 | SetTexture3DSlice(tilemapData.layerClipboard.tilemapSlice, tilemapTexture, layer); 467 | } 468 | 469 | /// 470 | /// Update the alpha intensity and tiles count stored in the layer data array texture. 471 | /// 472 | public void UpdateLayerSettings() 473 | { 474 | if (layerArrayTexture) 475 | { 476 | int width = tilemapLayerList.Count; 477 | Color32[] layerData = new Color32[width]; 478 | 479 | if (layerData.Length == layerArrayTexture.width) 480 | { 481 | for (int i = 0; i < width; i++) 482 | { 483 | if (tilemapLayerList[i].tilePalette) 484 | layerData[i].r = (byte)tilemapLayerList[i].tilePalette.tilesCount; 485 | layerData[i].g = (byte)(tilemapLayerList[i].intensity * 255); 486 | } 487 | 488 | // Apply the changes to the layer data texture 489 | layerArrayTexture.SetPixels32(layerData); 490 | layerArrayTexture.Apply(); 491 | } 492 | } 493 | } 494 | 495 | /// 496 | /// Reset a layer using the selected tile. 497 | /// 498 | public void ResetLayer(int index) 499 | { 500 | Color32 color = new Color32((byte)tileIndex, 0, 0, 0); 501 | for (int i = 0; i < tilemapTexture.width; i++) 502 | { 503 | for (int j = 0; j < tilemapTexture.height; j++) 504 | { 505 | tilemapTexture.SetPixel(i, j, index, color); 506 | } 507 | } 508 | 509 | tilemapLayerList[layerIndex].autoTileMapArray = new bool[(int)(gridMapSize.x * gridMapSize.y)]; 510 | tilemapTexture.Apply(); 511 | } 512 | 513 | /// 514 | /// Resize a Texture2D using Graphics.Blit(). 515 | /// 516 | private void ResizeTexture2D(int width, int height, Texture2D tex2D) 517 | { 518 | RenderTexture rt = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB, 1); 519 | rt.filterMode = FilterMode.Point; 520 | Graphics.Blit(tex2D, rt); 521 | tex2D.Resize(width, height); 522 | 523 | //RenderTexture active = RenderTexture.active; 524 | RenderTexture.active = rt; 525 | tex2D.ReadPixels(new Rect(0, 0, width, height), 0, 0); 526 | tex2D.Apply(); 527 | //RenderTexture.active = active; 528 | RenderTexture.active = null; 529 | RenderTexture.ReleaseTemporary(rt); 530 | } 531 | #endif 532 | } 533 | } -------------------------------------------------------------------------------- /3D Tilemap System/Scripts/Utilities/TilemapSystem3DEditorStuffs.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b86b99d24148e0c49ad59d1ec03abfa8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /3D Tilemap System/Scripts/Utilities/TilemapSystemLayer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace UnityEngine.TilemapSystem3D 5 | { 6 | /// 7 | /// Class that stores all the necessary data for painting each layer. 8 | /// 9 | [Serializable] 10 | public sealed class TilemapSystemLayer 11 | { 12 | /// 13 | /// The tile palette used to paint on this layer. 14 | /// 15 | public TilePalette tilePalette; 16 | 17 | /// 18 | /// The auto tile layout list of this layer. 19 | /// 20 | public List autoTileList = new List(); 21 | 22 | /// 23 | /// The alpha intensity of this layer. 24 | /// 25 | public float intensity = 1.0f; 26 | 27 | // TODO: Add support for multiples auto tile array maps and store it in the TilemapData.asset 28 | // -1 = regular tile 29 | // 0 = tile painted using the first auto tile layout 30 | // 1 = tile painted using the second auto tile layout 31 | // 2 = tile painted using the third auto tile layout 32 | // ... 33 | //public int[] autoTileArrayMap; 34 | 35 | /// 36 | /// Array map used by the auto tile feature. 37 | /// 38 | public bool[] autoTileMapArray; 39 | 40 | // Editor only 41 | #if UNITY_EDITOR 42 | /// 43 | /// Stores the layer name. Only used in the editor. 44 | /// 45 | public string layerName; 46 | 47 | /// 48 | /// The layer icon texture. Only used in the editor. 49 | /// 50 | public Texture2D iconTexture; 51 | 52 | /// 53 | /// The layout index from the auto tile list that should be used for painting the auto tiles. 54 | /// Only used in the editor. 55 | /// 56 | public int layoutIndex = 0; 57 | #endif 58 | } 59 | } -------------------------------------------------------------------------------- /3D Tilemap System/Scripts/Utilities/TilemapSystemLayer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9f9383b88e5ef344686e6694cd1ed1dc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /3D Tilemap System/Scripts/Utilities/TilemapSystemUtilities.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace UnityEngine.TilemapSystem3D 4 | { 5 | /// 6 | /// Used to set the Render Pipeline used by the current project. 7 | /// 8 | public enum TilemapSystemPipeline 9 | { 10 | Legacy, 11 | Universal 12 | } 13 | 14 | /// 15 | /// 16 | /// 17 | public enum TilemapSystemPaintingMode 18 | { 19 | Default, 20 | AutoTiles, 21 | RandomTilePainting, 22 | TileBrushes 23 | } 24 | 25 | /// 26 | /// Used by the auto tile list to store the layout for the 8-Bitmasking computations. 27 | /// 28 | [Serializable] public sealed class AutoTileLayout 29 | { 30 | public int[] id = new int[47]; 31 | 32 | // Not included in build 33 | #if UNITY_EDITOR 34 | public bool[] isPicked = new bool[47]; 35 | public string name; 36 | #endif 37 | } 38 | 39 | /// 40 | /// Stores some important settings of the Tilemap System component. 41 | /// Used in the TilemapData.asset to check if the user changed some settings in the Inspector. 42 | /// 43 | [Serializable] public struct TilemapSettings 44 | { 45 | public int layersCount; 46 | public int[] tilesCount; 47 | public TilePalette[] tilePalette; 48 | public int tilemapWidth; 49 | public int tilemapHeight; 50 | public int tilesetSize; 51 | 52 | public TilemapSettings(int layersCount, int[] tilesCount, TilePalette[] tilePalette, int tilemapWidth, int tilemapHeight, int tilesetSize) 53 | { 54 | this.layersCount = layersCount; 55 | this.tilesCount = tilesCount; 56 | this.tilePalette = tilePalette; 57 | this.tilemapWidth = tilemapWidth; 58 | this.tilemapHeight = tilemapHeight; 59 | this.tilesetSize = tilesetSize; 60 | } 61 | } 62 | 63 | /// 64 | /// Stores the tilemap data of a layer. 65 | /// Used in the TilemapData.asset to perform the copy and paste feature. 66 | /// 67 | [Serializable] public sealed class LayerClipboard 68 | { 69 | public int layerIndex; 70 | public Texture2D tilemapSlice; 71 | 72 | public LayerClipboard(int layerIndex, Texture2D tilemapSlice) 73 | { 74 | this.layerIndex = layerIndex; 75 | this.tilemapSlice = tilemapSlice; 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /3D Tilemap System/Scripts/Utilities/TilemapSystemUtilities.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9bd5322bca6d92a438dc5210a8777ac1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /3D Tilemap System/Shaders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c6d6174a3076aba4fbe13f8457807ea0 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /3D Tilemap System/Shaders/Legacy Diffuse.shader: -------------------------------------------------------------------------------- 1 | Shader "3D Tilemap System/Legacy Diffuse" 2 | { 3 | Properties 4 | { 5 | _TilemapTexture ("Tilemap Texture3D", 3D) = "black" {} 6 | _TilesetTexture ("Tileset Texture3D", 3D) = "black" {} 7 | _LayerArrayTexture ("Layer Array Texture1D", 2D) = "black" {} 8 | } 9 | 10 | SubShader 11 | { 12 | Tags { "RenderType"="Opaque" } 13 | LOD 200 14 | 15 | CGPROGRAM 16 | 17 | #pragma surface surf Lambert vertex:vert 18 | 19 | uniform sampler2D _LayerArrayTexture; 20 | uniform sampler3D _TilemapTexture; 21 | uniform sampler3D _TilesetTexture; 22 | uniform int2 _GridMapSize; 23 | uniform int _LayersCount; 24 | uniform int _TilesCount; 25 | 26 | struct Input 27 | { 28 | float4 vertex : SV_POSITION; 29 | float2 tilemap_uv : TEXCOORD0; 30 | float2 tileset_uv : TEXCOORD1; 31 | }; 32 | 33 | void vert(inout appdata_full v, out Input o) 34 | { 35 | UNITY_INITIALIZE_OUTPUT(Input, o); 36 | o.tilemap_uv = v.texcoord.xy; 37 | o.tileset_uv = v.texcoord.xy * _GridMapSize.xy; 38 | } 39 | 40 | void surf (Input IN, inout SurfaceOutput o) 41 | { 42 | float2 layerData = float2(0, 0); 43 | float tilemap = 0; 44 | fixed4 tileset = fixed4(0, 0, 0, 0); 45 | fixed4 outputColor = tex3D(_TilesetTexture, float3(IN.tileset_uv, 0)); 46 | float index = 0; 47 | float previousLayerCount = 0; 48 | 49 | for (int i = 0; i < _LayersCount; i++) 50 | { 51 | // Get layer data 52 | // layerData.x = The number of tiles in that layer 53 | // layerData.y = The alhpa intensity of that layer 54 | layerData = tex2D(_LayerArrayTexture, float2(1.0 / (_LayersCount - 1.0) * i, 0)).rg; 55 | 56 | // Get the tilemap data 57 | // Each pixel value of the 3d tilemap texture stores the slice number that the 3d tileset texture should render 58 | tilemap = tex3D(_TilemapTexture, float3(IN.tilemap_uv, 1.0 / (_LayersCount - 1) * i)).r * 255; 59 | 60 | // Compute the right slice index for current layer 61 | index = tilemap + previousLayerCount * 255; 62 | previousLayerCount += layerData.x; 63 | 64 | tileset = tex3D(_TilesetTexture, float3(IN.tileset_uv, 1.0 / (_TilesCount - 1) * index)); 65 | outputColor = lerp(outputColor, tileset, layerData.y * tileset.a); 66 | } 67 | 68 | o.Albedo = outputColor.rgb; 69 | o.Alpha = outputColor.a; 70 | } 71 | 72 | ENDCG 73 | } 74 | 75 | Fallback "Legacy Shaders/VertexLit" 76 | } -------------------------------------------------------------------------------- /3D Tilemap System/Shaders/Legacy Diffuse.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5594d6040eb13d54db5449d867e57ea0 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /3D Tilemap System/Shaders/Legacy Unlit.shader: -------------------------------------------------------------------------------- 1 | // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt) 2 | 3 | // Unlit shader. Simplest possible colored shader. 4 | // - no lighting 5 | // - no lightmap support 6 | // - no texture 7 | 8 | Shader "3D Tilemap System/Legacy Unlit" 9 | { 10 | Properties 11 | { 12 | _TilemapTexture ("Tilemap Texture3D", 3D) = "black" {} 13 | _TilesetTexture ("Tileset Texture3D", 3D) = "black" {} 14 | _LayerArrayTexture ("Layer Array Texture1D", 2D) = "black" {} 15 | } 16 | 17 | SubShader 18 | { 19 | Tags { "RenderType"="Opaque" } 20 | LOD 100 21 | 22 | Pass 23 | { 24 | CGPROGRAM 25 | 26 | #pragma vertex vert 27 | #pragma fragment frag 28 | #pragma target 2.0 29 | 30 | uniform sampler2D _LayerArrayTexture; 31 | uniform sampler3D _TilemapTexture; 32 | uniform sampler3D _TilesetTexture; 33 | uniform int2 _GridMapSize; 34 | uniform int _LayersCount; 35 | uniform int _TilesCount; 36 | 37 | struct appdata_t 38 | { 39 | float4 vertex : POSITION; 40 | float2 texcoord : TEXCOORD0; 41 | }; 42 | 43 | struct v2f 44 | { 45 | float4 vertex : SV_POSITION; 46 | float2 tilemap_uv : TEXCOORD0; 47 | float2 tileset_uv : TEXCOORD1; 48 | }; 49 | 50 | v2f vert (appdata_t v) 51 | { 52 | v2f o; 53 | o.vertex = UnityObjectToClipPos(v.vertex); 54 | o.tilemap_uv = v.texcoord.xy; 55 | o.tileset_uv = v.texcoord.xy * _GridMapSize.xy; 56 | return o; 57 | } 58 | 59 | fixed4 frag (v2f IN) : COLOR 60 | { 61 | float2 layerData = float2(0, 0); 62 | float tilemap = 0; 63 | fixed4 tileset = fixed4(0, 0, 0, 0); 64 | fixed4 outputColor = tex3D(_TilesetTexture, float3(IN.tileset_uv, 0)); 65 | float index = 0; 66 | float previousLayerCount = 0; 67 | 68 | for (int i = 0; i < _LayersCount; i++) 69 | { 70 | // Get layer data 71 | // layerData.x = The number of tiles in that layer 72 | // layerData.y = The alhpa intensity of that layer 73 | layerData = tex2D(_LayerArrayTexture, float2(1.0 / (_LayersCount - 1.0) * i, 0)).rg; 74 | 75 | // Get the tilemap data 76 | // Each pixel value of the 3d tilemap texture stores the slice number that the 3d tileset texture should render 77 | tilemap = tex3D(_TilemapTexture, float3(IN.tilemap_uv, 1.0 / (_LayersCount - 1) * i)).r * 255; 78 | 79 | // Compute the right slice index for current layer 80 | index = tilemap + previousLayerCount * 255; 81 | previousLayerCount += layerData.x; 82 | 83 | tileset = tex3D(_TilesetTexture, float3(IN.tileset_uv, 1.0 / (_TilesCount - 1) * index)); 84 | outputColor = lerp(outputColor, tileset, layerData.y * tileset.a); 85 | } 86 | 87 | return outputColor; 88 | } 89 | 90 | ENDCG 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /3D Tilemap System/Shaders/Legacy Unlit.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0400508317e303b4683b2d7fa99ba81e 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /3D Tilemap System/Textures.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a979e0455677fc941aec0a79ba211b54 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /3D Tilemap System/Textures/Layer0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7StarsGames/3D-Tilemap-System/2abeb86464655ba4046bdf23edde553fd18d1172/3D Tilemap System/Textures/Layer0.png -------------------------------------------------------------------------------- /3D Tilemap System/Textures/Layer0.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9809fce74ba3a434bb72ffee4a3a0960 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 1 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 0 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 0 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | applyGammaDecoding: 1 61 | platformSettings: 62 | - serializedVersion: 3 63 | buildTarget: DefaultTexturePlatform 64 | maxTextureSize: 2048 65 | resizeAlgorithm: 0 66 | textureFormat: -1 67 | textureCompression: 0 68 | compressionQuality: 50 69 | crunchedCompression: 0 70 | allowsAlphaSplitting: 0 71 | overridden: 0 72 | androidETC2FallbackOverride: 0 73 | forceMaximumCompressionQuality_BC6H_BC7: 0 74 | - serializedVersion: 3 75 | buildTarget: Standalone 76 | maxTextureSize: 2048 77 | resizeAlgorithm: 0 78 | textureFormat: -1 79 | textureCompression: 0 80 | compressionQuality: 50 81 | crunchedCompression: 0 82 | allowsAlphaSplitting: 0 83 | overridden: 0 84 | androidETC2FallbackOverride: 0 85 | forceMaximumCompressionQuality_BC6H_BC7: 0 86 | spriteSheet: 87 | serializedVersion: 2 88 | sprites: [] 89 | outline: [] 90 | physicsShape: [] 91 | bones: [] 92 | spriteID: 93 | internalID: 0 94 | vertices: [] 95 | indices: 96 | edges: [] 97 | weights: [] 98 | secondaryTextures: [] 99 | spritePackingTag: 100 | pSDRemoveMatte: 0 101 | pSDShowRemoveMatteOption: 0 102 | userData: 103 | assetBundleName: 104 | assetBundleVariant: 105 | -------------------------------------------------------------------------------- /3D Tilemap System/Textures/Layer1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7StarsGames/3D-Tilemap-System/2abeb86464655ba4046bdf23edde553fd18d1172/3D Tilemap System/Textures/Layer1.png -------------------------------------------------------------------------------- /3D Tilemap System/Textures/Layer1.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 97559c0a35915f140bd28c4021a42a02 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 1 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 0 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 0 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 1 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | applyGammaDecoding: 0 61 | platformSettings: 62 | - serializedVersion: 3 63 | buildTarget: DefaultTexturePlatform 64 | maxTextureSize: 2048 65 | resizeAlgorithm: 0 66 | textureFormat: -1 67 | textureCompression: 0 68 | compressionQuality: 50 69 | crunchedCompression: 0 70 | allowsAlphaSplitting: 0 71 | overridden: 0 72 | androidETC2FallbackOverride: 0 73 | forceMaximumCompressionQuality_BC6H_BC7: 0 74 | - serializedVersion: 3 75 | buildTarget: Standalone 76 | maxTextureSize: 2048 77 | resizeAlgorithm: 0 78 | textureFormat: -1 79 | textureCompression: 0 80 | compressionQuality: 50 81 | crunchedCompression: 0 82 | allowsAlphaSplitting: 0 83 | overridden: 0 84 | androidETC2FallbackOverride: 0 85 | forceMaximumCompressionQuality_BC6H_BC7: 0 86 | spriteSheet: 87 | serializedVersion: 2 88 | sprites: [] 89 | outline: [] 90 | physicsShape: [] 91 | bones: [] 92 | spriteID: 93 | internalID: 0 94 | vertices: [] 95 | indices: 96 | edges: [] 97 | weights: [] 98 | secondaryTextures: [] 99 | spritePackingTag: 100 | pSDRemoveMatte: 0 101 | pSDShowRemoveMatteOption: 0 102 | userData: 103 | assetBundleName: 104 | assetBundleVariant: 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 3D-Tilemap-System 2 | 3D Tilemap System is a tool for painting tiles on Unity terrains or even on custom meshs using tilesets in the same way as it is popularly made and seen in 2D game engines. 3 | 4 | See the official forum page: https://forum.unity.com/threads/free-3d-tilemap-system-for-3d-pixel-art-games.710600/ 5 | --------------------------------------------------------------------------------