├── scr.png ├── TilemapMask ├── Editor │ └── TilemapMaskEditor.cs ├── TilemapMask.cs └── FloorMask.prefab ├── README.md ├── LICENSE └── .gitignore /scr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justcoredev/UnityTilemapMask/HEAD/scr.png -------------------------------------------------------------------------------- /TilemapMask/Editor/TilemapMaskEditor.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEditor; 5 | 6 | [CustomEditor(typeof(TilemapMask))] 7 | public class TilemapMaskEditor : Editor 8 | { 9 | public override void OnInspectorGUI() 10 | { 11 | base.OnInspectorGUI(); 12 | TilemapMask tilemapMask = (TilemapMask)target; 13 | 14 | if (GUILayout.Button("Generate Mask")) 15 | { 16 | tilemapMask.GenerateMask(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnityTilemapMask 2 | The mask component. Works the same as SpriteMask, but used for tilemaps. Very easy to use! 3 | 4 | ### How to use 5 | 6 | 1. Download the TilemapMask folder 7 | 2. Add the `TilemapMask.cs` script to an object that the Tilemap is on and set the `Mask Cell` field to the `FloorMask.prefab`. 8 | 3. Click `Generate Mask` to generate mask for your tilemap. 9 | 4. Set `Mask Interaction` to `Visible Inside Mask` inside all `SpriteRenderers` of your `Sprites`, which should only appear inside the mask. 10 | 5. See the result! :) 11 | 12 | ![alt text](https://github.com/JustAnCore/UnityTilemapMask/blob/main/scr.png?raw=true) 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Andrey Lebedev (justcore) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # This .gitignore file should be placed at the root of your Unity project directory 2 | # 3 | # Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore 4 | # 5 | /[Ll]ibrary/ 6 | /[Tt]emp/ 7 | /[Oo]bj/ 8 | /[Bb]uild/ 9 | /[Bb]uilds/ 10 | /[Ll]ogs/ 11 | /[Mm]emoryCaptures/ 12 | 13 | # Asset meta data should only be ignored when the corresponding asset is also ignored 14 | !/[Aa]ssets/**/*.meta 15 | 16 | # Uncomment this line if you wish to ignore the asset store tools plugin 17 | # /[Aa]ssets/AssetStoreTools* 18 | 19 | # Autogenerated Jetbrains Rider plugin 20 | [Aa]ssets/Plugins/Editor/JetBrains* 21 | 22 | # Visual Studio cache directory 23 | .vs/ 24 | 25 | # Gradle cache directory 26 | .gradle/ 27 | 28 | # Autogenerated VS/MD/Consulo solution and project files 29 | ExportedObj/ 30 | .consulo/ 31 | *.csproj 32 | *.unityproj 33 | *.sln 34 | *.suo 35 | *.tmp 36 | *.user 37 | *.userprefs 38 | *.pidb 39 | *.booproj 40 | *.svd 41 | *.pdb 42 | *.mdb 43 | *.opendb 44 | *.VC.db 45 | 46 | # Unity3D generated meta files 47 | *.pidb.meta 48 | *.pdb.meta 49 | *.mdb.meta 50 | 51 | # Unity3D generated file on crash reports 52 | sysinfo.txt 53 | 54 | # Builds 55 | *.apk 56 | *.unitypackage 57 | 58 | # Crashlytics generated file 59 | crashlytics-build.properties 60 | 61 | -------------------------------------------------------------------------------- /TilemapMask/TilemapMask.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Tilemaps; 5 | 6 | public class TilemapMask : MonoBehaviour 7 | { 8 | //-- UnityTilemapMask - Open source repo hosted on github 9 | //-- License: MIT 10 | 11 | public GameObject maskCell; 12 | [HideInInspector] 13 | public GameObject maskParentObj; // Must be public for correct handling of game/editor destroying 14 | 15 | public void GenerateMask() 16 | { 17 | Tilemap tilemap = GetComponent(); 18 | 19 | Vector3Int startCoord = tilemap.origin; 20 | Vector3Int size = tilemap.size; 21 | 22 | // Destroy old mask if needed 23 | if (maskParentObj != null) 24 | { 25 | if (Application.isEditor) 26 | { 27 | DestroyImmediate(maskParentObj); 28 | maskParentObj = null; 29 | } 30 | else Destroy(maskParentObj); 31 | } 32 | 33 | maskParentObj = new GameObject("TilemapMask"); 34 | maskParentObj.transform.parent = transform; 35 | 36 | //Iterate over each cell 37 | for (int x = startCoord.x; x < startCoord.x + size.x; x++) 38 | { 39 | for (int y = startCoord.y; y < startCoord.y + size.y; y++) 40 | { 41 | //Check if cell isn't empty 42 | if (tilemap.GetTile(new Vector3Int(x, y, startCoord.z)) != null) 43 | { 44 | //Create maskCell on the cell coords 45 | Vector3 coord = tilemap.CellToWorld(new Vector3Int(x, y, startCoord.z)) + new Vector3(0.5f, 0.5f, 0); 46 | GameObject cell = Instantiate(maskCell, coord, Quaternion.identity, maskParentObj.transform); 47 | cell.GetComponent().sprite = tilemap.GetSprite(new Vector3Int(x, y, startCoord.z)); 48 | } 49 | } 50 | } 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /TilemapMask/FloorMask.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &6232566873042256313 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 8390527113114443708} 12 | - component: {fileID: 8435516128349044459} 13 | m_Layer: 0 14 | m_Name: FloorMask 15 | m_TagString: Untagged 16 | m_Icon: {fileID: 0} 17 | m_NavMeshLayer: 0 18 | m_StaticEditorFlags: 0 19 | m_IsActive: 1 20 | --- !u!4 &8390527113114443708 21 | Transform: 22 | m_ObjectHideFlags: 0 23 | m_CorrespondingSourceObject: {fileID: 0} 24 | m_PrefabInstance: {fileID: 0} 25 | m_PrefabAsset: {fileID: 0} 26 | m_GameObject: {fileID: 6232566873042256313} 27 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 28 | m_LocalPosition: {x: 0, y: 0, z: 0} 29 | m_LocalScale: {x: 1, y: 1, z: 1} 30 | m_ConstrainProportionsScale: 0 31 | m_Children: [] 32 | m_Father: {fileID: 0} 33 | m_RootOrder: 0 34 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 35 | --- !u!331 &8435516128349044459 36 | SpriteMask: 37 | m_ObjectHideFlags: 0 38 | m_CorrespondingSourceObject: {fileID: 0} 39 | m_PrefabInstance: {fileID: 0} 40 | m_PrefabAsset: {fileID: 0} 41 | m_GameObject: {fileID: 6232566873042256313} 42 | m_Enabled: 1 43 | m_CastShadows: 1 44 | m_ReceiveShadows: 1 45 | m_DynamicOccludee: 1 46 | m_StaticShadowCaster: 0 47 | m_MotionVectors: 1 48 | m_LightProbeUsage: 1 49 | m_ReflectionProbeUsage: 1 50 | m_RayTracingMode: 0 51 | m_RayTraceProcedural: 0 52 | m_RenderingLayerMask: 1 53 | m_RendererPriority: 0 54 | m_Materials: 55 | - {fileID: 10758, guid: 0000000000000000f000000000000000, type: 0} 56 | m_StaticBatchInfo: 57 | firstSubMesh: 0 58 | subMeshCount: 0 59 | m_StaticBatchRoot: {fileID: 0} 60 | m_ProbeAnchor: {fileID: 0} 61 | m_LightProbeVolumeOverride: {fileID: 0} 62 | m_ScaleInLightmap: 1 63 | m_ReceiveGI: 1 64 | m_PreserveUVs: 0 65 | m_IgnoreNormalsForChartDetection: 0 66 | m_ImportantGI: 0 67 | m_StitchLightmapSeams: 1 68 | m_SelectedEditorRenderState: 3 69 | m_MinimumChartSize: 4 70 | m_AutoUVMaxDistance: 0.5 71 | m_AutoUVMaxAngle: 89 72 | m_LightmapParameters: {fileID: 0} 73 | m_SortingLayerID: 0 74 | m_SortingLayer: 0 75 | m_SortingOrder: 0 76 | m_Sprite: {fileID: -585525762, guid: 5d31c3367170f054dbca6805b4358fcf, type: 3} 77 | m_MaskAlphaCutoff: 0.2 78 | m_FrontSortingLayerID: 0 79 | m_BackSortingLayerID: 0 80 | m_FrontSortingLayer: 0 81 | m_BackSortingLayer: 0 82 | m_FrontSortingOrder: 6 83 | m_BackSortingOrder: 5 84 | m_IsCustomRangeActive: 0 85 | m_SpriteSortPoint: 0 86 | --------------------------------------------------------------------------------