Need tiles to contain data/reference

Hello everyone. I need help with tilemaps. So I have a tilemap and I need the tiles to store an Item class (which is a scriptable object class i created). I created an “Item” for every tile i have. But i need a single tile to reference its own “item” so i can for example grab its particle color(a variable in the Item class) and set the appearing particle color to that(i have a block breaking system which emits the particles of the block you break). I basically need every tile the player breaks to reference its item(scriptable object). Much thanks to any help

Derive a custom class from either TileBase / Tile /Rule Tile, whichever is appropriate.

using UnityEngine.Tilemaps;

public class ItemTile : TileBase
{
     public ItemData itemData;
}

Then you can access and obtain the ItemData before the player breaks the tile. Because ItemData is a ScriptableObject, it can easily be plugged in via the Inspector.

1 Like

I’ll try that. Thanks

@Lo-renzo bro I still can’t figure it out. I did the code and yeah I can see in the inspector the Item place and I can put my Item scriptable objects in there but how do I hook it up with the tiles i have? What does inheriting the TileBase class provides me? Need your help for the next step

You need to inherit from some TileBase-derived class (TileBase, Tile, RuleTile, etc) in order to then add your own field to the class so you can hook up ItemData. Sounds like you’ve got that part working. The Tilemap only works with classes that ultimately derive from TileBase.

The next part is accessing your tile before you destroy the tile. The most basic way to “destroy” a tile right now is to null it out.

Vector3Int cell = new Vector3Int(1, 1, 0); // or whatever tile is being destroyed
myTilemap.SetTile(cell, null);

But it sounds like you want to create a particle effect when destroying it. For that you need to call your own destroy method that checks whether anything special happens when you destroy the tile.

public static class TilemapExtensions
{
    public static void DestroyTile(this Tilemap tilemap, Vector3Int cell)
    {
        var tile = tilemap.GetTile(cell);
        if(tile is ItemTile itemTile)
        {
             Vector3 worldPoint = tilemap.CellToWorld(cell);
             itemTile.itemData.OnDestroyCreateParticleEffect(worldPoint);
             tilemap.SetTile(cell, null);
        }
    }
}

To explain what’s going on above: first we get the cell to check the kind of tile that’s on that cell (if any). If it’s an ItemTile, we know it contains itemData, which I assume has some kind of method for instantiating a Particle System that makes a destruction effect. Importantly, we convert our cell from cellspace to worldspace. This ensures that when we create the particle effect, it’s in the correct spot.

I’ve written it as an extension method so that it’ll automatically appear as a method on any tilemap you work with. An alternative way to do this would be to have a wrapper class that you use instead which wraps calls to the Tilemaps API.

What’s left to you is to write OnDestroyCreateParticleEffect which would presumably have a prefab that it would instantiate using that world point. After the effect is over, the Particle System then needs to destroy itself.

1 Like

@Lo-renzo Thanks so much dude! I actually had the working tile breaking system and particle system and all I needed was a code that finds the scriptable object of the tile you’re breaking. And I realized I didn’t need that scriptable object at all since when you inherit your class as Tile it already offers you the properties of a scriptable object and it shows up in the inspector automatically. So i changed the ItemTile class name to Item and deleted the old one. So now I have one scriptable object type and I can treat it both like a inventory item and a tile. It can even be directly dragged and dropped to the tile palette. Anyways it’s working. I appreciate your help bro

Yeah but that means ALL instances of a certain tile type have to have the same data and data values.

bro why are you mass necroing 3 years old threads

1 Like

Unity still exists, these pages are still public on the internet and are still indexed by Google and often old posts are still the latest information.

This isn’t a steam game forum.

2 Likes

whats your point? Thats why I called it mass necro…

We already understand that you want one different game object per tile instance, going through every thread saying it doesnt exist wont solve your issue

The answer is appropriate for OP’s reqs. Each tile type instance could have different data.

From your other post, it sounds like what you require is a regular gameobject.

1 Like

The point is this information and any updates are still relevant. It also helps people that are currently searching for this information with up to date information as all of these posts are right at the top of Google search results. ‘We’ is not everyone and certainly not those who are now searching.
This is not the childish steam forums where kids post ‘this is a necro’ rubbish for fun. This is historical repository of information this is updated like everywhere else.

1 Like

Yeah that’s the conclusion I’ve come to as well. I was hoping this data could be tied to actual tiles/tile instances like the have been in almost every other tile engine since the 80s

which is unfortunate because instead of a 3 year reply to add nothing of new we could have a 30 year old necro, now that would be a sight to behold. Unity should really up their game in this instance, getting outdone by the super nintendo created tilemaker deluxe for amateur developers who used the nintendo tilemap feature, including 1 game object per tile instance on their 4mb cartridges.

Funny enough, I’ve returned to this project after like 2 years and now I’m experiencing the same problem. I need each tile instance to have different properties. For example: I have a Portal tile and each portal needs to have a different destination. So I need to be able to store a position value in each tile instance. It’s sad how many basic stuff is absent in Unity.

1 Like

if they added that feature with the disclaimer THIS WILL DECREASE PERFORMANCE

would you still use it? or would you opt for the version that doesnt

I set for myself simple rules using tiles in Unity.

  • Tiles are a background element.
  • I don’t need to store data “in the tile” I only need its coordinates to check its properties in a simple matrix.
  • I need special unique futures like the teleport you wrote, I just put a game object with the trigger on the tile.

Edit: Unity is just an engine. You must fit your game logic to its core mechanic and features. Doing a game with the rule “I must do all on tiles” is just a bad approach. Tiles are just one feature. You have a toolset, you don’t work with just a hammer. Each task needs a different tool and approach.

You have several options.

1. Instantiate a new tile anywhere you need per-cell data: var newTile = ScriptableObject.Instantiate(yourTileToCopy). This makes tiles less memory efficient but plays well with Unity.

2. For any cell that needs data, use game objects. This gives you the full suite of per-cell properties and flexibility of attaching MonoBehaviours as needed. TileData has a slot for a gameobject so this is the most built-in option. This option may be more appropriate for games with pre-defined levels because you can control placing gameobjects so their number is reasonable. For a more dynamic game, unless you’re careful about what cells have g.o.s then it could become a problem if maps are large.

3. Keep an independent data store. Parallel to your tilemap, keep a collection (array for static maps, dictionary for dynamic) where you can look up per-cell gameplay data. This allows you to retrieve either the tile information or the gameplay information given a particular cell. This approach treats Unity’s tilemaps as just a visual layer while you control the gameplay data yourself.

2 Likes

I long since abandoned using tiles for anything more than something just visual and even then, there’s limitations due to size and overlapping. For anything more than that I use full blow game objects. Which works out better as I have some rather complex scenarios for almost everything that isn’t just a dumb visual anyway.

Unity claims to have a fully featured tile editing and rendering engine. Going back all the way to the 1980’s, tile engines and editors have always had the ability to add properties to tiles as part of that engine. Unity doesn’t, you have to use something else or create your own mechanism for this (the lookup table you mention is one example).
That’s the point here, it’s missing core features that is very common and expected with tile engines.