Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by charlesaverill20 · Dec 09, 2020 at 04:05 AM · 2dtilemaptiles

How to programmatically switch tile palettes in Unity2D

Scenario: User has different tile palettes for each season (Summer, Fall, etc.) and switching between the two using popular Unity techniques would be tedious if the number of tiles in the tileset is greater than 5 or 10. How would said user switch between their tile palettes programmatically, instead of using a wasteful solution like prefab tiles?

This problem seems significant enough that Unity docs would cover it. However I found myself digging through years-old forum posts to come up with my solution. Here's what I came up with, and it's not too complicated.

1) Create your tilesets. Import your tilesets as multi-sprite spritesheets, and split them using the Unity sprite editor. Do not bother naming each sprite. Each tileset should be organized the same exact way (bushes/trees/objects should be in the same spot on every season's tilesheet). When you are finished, create a folder "Resources" in your "Assets" folder. Inside of resources, create a folder "Spritesheets", and place your spricesheets in it.

2) Run this renaming script:

 using UnityEngine;
 using UnityEditor;
 using System.Collections;
 
 public class SpriteRenamer : MonoBehaviour
 {
     public Texture2D[] texture2Ds;
     public string newName;
 
     private string path;
     private TextureImporter textureImporter;
 
     void Start ()
     {
         foreach(Texture2D texture2D in texture2Ds){
             path = AssetDatabase.GetAssetPath (texture2D);
             textureImporter = AssetImporter.GetAtPath (path) as TextureImporter;
             SpriteMetaData[] sliceMetaData = textureImporter.spritesheet;
 
             int index = 0;
             foreach (SpriteMetaData individualSliceData in sliceMetaData)
             {
                 sliceMetaData[index].name = string.Format (newName + "_{0}", index);
                 print (sliceMetaData[index].name);
 
                 index++;
             }
 
             textureImporter.spritesheet = sliceMetaData;
             EditorUtility.SetDirty (textureImporter);
             textureImporter.SaveAndReimport ();
 
             AssetDatabase.ImportAsset (path, ImportAssetOptions.ForceUpdate);
         }
     }
 }

Attach it to an empty GameObject in an empty Scene (just for simplicity). Drag and drop your spritesheets into the Texture2D array. Set the newName field to whatever you want, it will be the prefix for the name of each sprite in each spritesheet. Finally, run the scene and each spritesheet's sprites will be renamed to make each corresponding sprite have the same name.

3) We now have each of our seasons' tilesheets modified so each tile is identically named. The next step is to create a Grid object with a child TilePalette. Draw all of your scenery, collision, etc. You can use as many TilePalettes as needed, as long as they are children of the Grid object. Now, create a script called ReskinnableTileBase:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.Tilemaps;
 
 public class ReskinnableTileBase : TileBase
 {
     public Sprite sprite;
 
     public override void GetTileData(Vector3Int position, ITilemap tilemap, ref TileData tileData)
     {
         tileData.sprite = sprite;
     }
 }

4) Attach this Reskinner script to your Grid object:

 using System;
 using System.Linq;
 using UnityEngine;
 using UnityEngine.Tilemaps;
 
 public class Reskinner : MonoBehaviour
 {
 
     Sprite[] subSprites;
     Tilemap[] tilemaps;
 
     void Start(){
         tilemaps = GetComponentsInChildren<Tilemap>();
         SetSkin("#INSERT DEFAULT TILE PALETTE NAME HERE#");
     }
 
     public void SetSkin(string name){
         reloadSprites(name);
         foreach(Tilemap tilemap in tilemaps){
             for(int x = (int)tilemap.localBounds.min.x; x < tilemap.localBounds.max.x; x++){
                 for(int y = (int)tilemap.localBounds.min.y; y < tilemap.localBounds.max.y; y++){
                     TileBase tb = tilemap.GetTile(new Vector3Int(x, y, 0));
                     Debug.Log(tb);
 
                     ReskinnableTileBase rtb = (ReskinnableTileBase)ScriptableObject.CreateInstance(typeof(ReskinnableTileBase));
 
                     if(tb == null || rtb == null || tb.name.Length < 1){
                         continue;
                     }
 
                     Sprite replace = getSubSpriteByName(tb.name);
                     rtb.sprite = replace;
                     rtb.name = tb.name;
 
                     tilemap.SwapTile(tb, (TileBase)rtb);
                 }
             }
         }
     }
 
     void reloadSprites(string name){
         subSprites = Resources.LoadAll<Sprite>("Spritesheets/" + name);
     }
 
     Sprite getSubSpriteByName(string name){
         foreach(Sprite s in subSprites){
             if(s.name == name){
                 return s;
             }
         }
         return null;
     }
 }

5) And there you go! Now, any time you need to change the skin/season/tilesheet, just use a reference to the Grid's Reskinner script, and call the SetSkin method, like so:

 Reskinner reskinner = gridObject.GetComponent();
 reskinner.SetSkin("summer");






Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

314 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

[Tilemap] Can you spawn a Prefab (with colliter) together with a tile when placing it? 0 Answers

Streaming in 2D tiled maps for seamless world, does this conflict with Unity's editor? Do I need to use an external editor? 1 Answer

[Tilemap] Can you spawn a Prefab (with colliter) together with a tile when placing it? 0 Answers

Checking the probability of an attack in certain tiles 0 Answers

Need help finding a library/solution for efficient 2D tilemap rendering, collisions and interaction. 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges