├── 3D Tilemap System
├── Textures
│ ├── Layer0.png
│ ├── Layer1.png
│ ├── Layer0.png.meta
│ └── Layer1.png.meta
├── Editor
│ ├── UI
│ │ ├── BlobLayout.png
│ │ ├── _EmptyIcon.png
│ │ ├── _DefaultColor.png
│ │ ├── BlobLayout.asset.meta
│ │ ├── BlobLayout.png.meta
│ │ ├── _DefaultColor.png.meta
│ │ └── _EmptyIcon.png.meta
│ ├── UI.meta
│ ├── TilePaletteInspector.cs.meta
│ ├── TilemapSystemInspector.cs.meta
│ ├── TilePaletteInspector.cs
│ └── TilemapSystemInspector.cs
├── Scenes
│ ├── New Terrain.asset
│ ├── CustomMesh.unity.meta
│ ├── UnityTerrain.unity.meta
│ ├── New Terrain.asset.meta
│ ├── CustomMesh.unity
│ └── UnityTerrain.unity
├── Data.meta
├── Editor.meta
├── Scenes.meta
├── Imports.meta
├── Palettes.meta
├── Scripts.meta
├── Shaders.meta
├── Textures.meta
├── Scripts
│ ├── Utilities.meta
│ ├── TilePalette.cs.meta
│ ├── TilemapData.cs.meta
│ ├── Utilities
│ │ ├── TilemapSystemLayer.cs.meta
│ │ ├── TilemapSystemUtilities.cs.meta
│ │ ├── TilemapSystem3DEditorStuffs.cs.meta
│ │ ├── TilemapSystemLayer.cs
│ │ ├── TilemapSystemUtilities.cs
│ │ └── TilemapSystem3DEditorStuffs.cs
│ ├── TilemapData.cs
│ ├── TilemapSystem3D.cs.meta
│ ├── TilePalette.cs
│ └── TilemapSystem3D.cs
├── Palettes
│ ├── Layer0.asset.meta
│ └── Layer1.asset.meta
├── Data
│ ├── TerrainTilemapData.asset.meta
│ └── CustomMeshTilemapData.asset.meta
├── Shaders
│ ├── Legacy Diffuse.shader.meta
│ ├── Legacy Unlit.shader.meta
│ ├── Legacy Diffuse.shader
│ └── Legacy Unlit.shader
└── Imports
│ ├── CustomMapMesh.obj.meta
│ └── CustomMapMesh.obj
└── README.md
/3D Tilemap System/Textures/Layer0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7StarsGames/3D-Tilemap-System/HEAD/3D Tilemap System/Textures/Layer0.png
--------------------------------------------------------------------------------
/3D Tilemap System/Textures/Layer1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7StarsGames/3D-Tilemap-System/HEAD/3D Tilemap System/Textures/Layer1.png
--------------------------------------------------------------------------------
/3D Tilemap System/Editor/UI/BlobLayout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7StarsGames/3D-Tilemap-System/HEAD/3D Tilemap System/Editor/UI/BlobLayout.png
--------------------------------------------------------------------------------
/3D Tilemap System/Editor/UI/_EmptyIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7StarsGames/3D-Tilemap-System/HEAD/3D Tilemap System/Editor/UI/_EmptyIcon.png
--------------------------------------------------------------------------------
/3D Tilemap System/Scenes/New Terrain.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7StarsGames/3D-Tilemap-System/HEAD/3D Tilemap System/Scenes/New Terrain.asset
--------------------------------------------------------------------------------
/3D Tilemap System/Editor/UI/_DefaultColor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7StarsGames/3D-Tilemap-System/HEAD/3D Tilemap System/Editor/UI/_DefaultColor.png
--------------------------------------------------------------------------------
/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/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/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.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7272d95a0e572fd408c8642c0789d4ee
3 | DefaultImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/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/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/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/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/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/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/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/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/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/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/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/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/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/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.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0400508317e303b4683b2d7fa99ba81e
3 | ShaderImporter:
4 | externalObjects: {}
5 | defaultTextures: []
6 | nonModifiableTextures: []
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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.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/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.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/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/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.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/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/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/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/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/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/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/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/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.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/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.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 |
--------------------------------------------------------------------------------
/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/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/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/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/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/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/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/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/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 | }
--------------------------------------------------------------------------------