Hello Guest

Author Topic: Prefab in Tilemap graphic override  (Read 6460 times)

Pfaeff

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 25
    • View Profile
Prefab in Tilemap graphic override
« on: August 19, 2013, 07:44:11 pm »
Hi there,

I have a tilemap and want to attach a script to certain tiles, so I use a sprite as a prefab. That's fine. But if I want to have the same script running for different looking tiles, so I have to make a prefab for each one of them and change the sprite. It would be nicer, if the sprite could just use the image I chose from the tilemap spritesheet, but that doesn't seem to be possible at the moment.
Is there another elegant way to do it? Thanks a lot.

Greetings,
Pfaeff


unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Prefab in Tilemap graphic override
« Reply #1 on: August 19, 2013, 09:25:33 pm »
No there isn't. You will have to set up the prefabs manually / write a script to do it. We could probably add support for it if there is enough interest.

Pfaeff

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 25
    • View Profile
Re: Prefab in Tilemap graphic override
« Reply #2 on: August 19, 2013, 10:24:53 pm »
The only other way I could think of is read the sprite image off the tilemap at the prefabs position. Is there a way for the prefab to know its position or do I have to go through the entire tilemap at the beginning to set everything up? Thank you.


unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Prefab in Tilemap graphic override
« Reply #3 on: August 20, 2013, 11:29:10 am »
You can build a sprite prefab for all your sprites and then add the behaviours to them programatically, independent to the tilemap system. You can then assign them directly to the tilemap data object programatically. There is a tilePrefabs variable you can set up directly on that.

Pfaeff

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 25
    • View Profile
Re: Prefab in Tilemap graphic override
« Reply #4 on: August 23, 2013, 11:16:59 pm »
I could also put it on an extra layer in front of everything and make it have no sprite at all. This way I can set the sprite I want to display in a background layer.

subliminalman

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Prefab in Tilemap graphic override
« Reply #5 on: October 18, 2013, 08:26:46 am »
The only other way I could think of is read the sprite image off the tilemap at the prefabs position. Is there a way for the prefab to know its position or do I have to go through the entire tilemap at the beginning to set everything up? Thank you.

No there isn't. You will have to set up the prefabs manually / write a script to do it. We could probably add support for it if there is enough interest.

Could you please? I am currently using the script below to make the changes I need for the sprites and I feel like there could be an easier way within your system.

This code grabs the name of the sprite from the tile and calls SetSprite(spriteName) on the prefab.
Make sure to set the string value in the data tab for each tile to the sprite name from your collection, it won't work otherwise.

Select your tilemap before pressing the button.


edit: updated code to flip tiles appropriately. It won't rotate 90 yet.
edit2: updated so it goes through layers as well
edit3: did the flags wrong the first time, fixed now.


Code: [Select]
using UnityEngine;
using UnityEditor;
using System.Collections;

public class UpdateTilemap : EditorWindow {
string buttonText = "Update TileMap Prefabs";
[MenuItem ("Window/Update TileMap Prefabs")]
static void Init () {
// Get existing open window or if none, make a new one:
UpdateTilemap window = (UpdateTilemap)EditorWindow.GetWindow (typeof (UpdateTilemap));
}

void OnGUI () {
if(GUILayout.Button(buttonText)) {
            //add everthing the button would do.
buttonText = UpdateTileMapPrefabs();
        }
}

string UpdateTileMapPrefabs(){
try{
if (Selection.activeGameObject == null || Selection.activeGameObject.GetComponent<tk2dTileMap>() == null){
Debug.Log("Select a tile map before running this");
return "Select a tile map before running";
}
tk2dTileMap tilemap = Selection.activeGameObject.GetComponent<tk2dTileMap>();

for(int z = 0; z < tilemap.data.NumLayers; z++){
for (int x = 0; x < tilemap.width; ++x) {
for (int y = 0; y < tilemap.height; ++y) {
//Go through each tile and get it's spriteName
tk2dRuntime.TileMap.TileInfo tempInfo = tilemap.GetTileInfoForTileId(tilemap.GetTile(x, y, z));
if(tempInfo != null){
string spriteName = tempInfo.stringVal;

if(spriteName != null && !spriteName.Equals("")){

//Check every prefab in the tilemap to get matching spriteNames
for(int i = 0; i < tilemap.GetTilePrefabsListCount(); i++){
int tempX = 0, tempY = 0 , tempLayer = 0;
GameObject prefabObject;
//get the prefab
tilemap.GetTilePrefabsListItem(i, out tempX, out tempY, out tempLayer, out prefabObject);

if(tempX == x && tempY == y && tempLayer == z){
if(prefabObject != null){
//Update the sprite

tk2dSprite tempSprite = prefabObject.GetComponent<tk2dSprite>();

if(tempSprite.SetSprite(spriteName)){
//a hack to keep the change

tk2dTileFlags tileFlag = tilemap.GetTileFlags(x, y, z);

if(tileFlag == tk2dTileFlags.None){
tempSprite.FlipX = tempSprite.FlipY = false;
}else{
if((tileFlag & tk2dTileFlags.FlipX) == tk2dTileFlags.FlipX){
tempSprite.FlipX = true;
}
if((tileFlag & tk2dTileFlags.FlipY) == tk2dTileFlags.FlipY){
tempSprite.FlipY = true;
}
}
Debug.Log (tileFlag.ToString());

tempSprite.enabled = false;
tempSprite.enabled = true;
Debug.Log ("Success");
}else{
Debug.Log ("Failure");
}

break;
}
}//Wow that's a brace
}//There's another one
}//They keep going
}//...
}//grrrr
}//*flips table*
}

return "finished";
}catch(System.Exception e){
return "failed: " + e;
}
}
}
« Last Edit: October 20, 2013, 11:45:17 pm by subliminalman »

marsh

  • Newbie
  • *
  • Posts: 1
    • View Profile
Re: Prefab in Tilemap graphic override
« Reply #6 on: October 22, 2013, 02:58:48 am »
Registered just to say thanks subliminalman. Great Script. Saved me the time of writing it myself.