#How do i assign hitpoints to tiles?

1 messages · Page 1 of 1 (latest)

past fox
#

I try to make a game where you mine gems and other kind of things, but i want different tiles to break with more hits than other.

Like dirt needing 3 clicks to break and iron needing 6 clicks.

I just came back to unity after quitting for 1 year and I was hoping to learn more.

I couldn't find any tutorials on how i can achieve this so i hoped i could get some help here.

This is the script i use to break tiles, but i do not know how i can assign different tiles hitpoints, I'm still a beginner at this so my knowledge is quite small.

glacial pine
#

The built-in tile map was not really made to have individual data for each tile, beyond what tile it is.
You could get around this by assigning a prefab to tiles that have a durability and accessing the instances of the tiles' respective prefabs through their gameObject property.
However, that would be sacrificing performance. Not to mention that you would on top of having all the objects spawned, also need GetComponent calls on them.
A better alternative may be to store a Tile's hit points inside a Dictionary<Vector3Int, CustomTileData> or CustomTileData[,] (where CustomTileData is a struct or class containing the hit points and possibly other data), and keeping track of individual tiles' data that way. Do keep in mind that this collection would have to be initialized once on startup, but after that lookups would almost be free if done correctly.

past fox
#

If so, how do I make Iron exist. Do i make a [SerializeField]?
For this i mean:

The name 'iron' does not exist in the current context
glacial pine
#

That dictionary would be representing the tiles' current values. That is also why I used a Vector3Int as key.
You can't just throw in arbitrary values; we're not working with JavaScript here lol

How you get the initial values for each tile is an entirely separate issue; Since each Tile has an associated Sprite, you could use that sprite to determine the type of the tile and set the values accordingly.
To associate a value (or a set of values) with a tile type, you'll also need some kind of collection. A dictionary would be preferable, but since Unity can't serialize those, a list can suffice as well.

past fox
glacial pine
#

This approach kind of defies the purpose.
If you assign the same TileData instance to every tile of a certain type, its values will be shared - which means you would damage all tiles with the same TileData at once.

past fox
#

ah

#

I'm kinda lost i dont know how to solve this

#

How do i make it separate for each tile?

#

I apologize for my 2 braincells, as they can barely comprehend anything as it is now

glacial pine
#

You could do something like this (note that I won't write the whole code, just some things to give you an idea):```cs
// component on your Tilemap object
public class TileDataHolder : MonoBehaviour
{
[SerializeField] private Tilemap map;
[SerializeField] private TileData[] data;

private TileState[,,] tileStates;

private void Start ()
{
InitializeTileStates();
}

private void InitializeTileStates()
{
// iterate over all tiles in your grid
var size = map.size;
var initData = GetInitialData();

// init states
tileStates = new TileState[size.x, size.y, size.z];

for(x < size.x)
{
  for(y < size.y)
  {
    for(z < size.z)
    {
      // get tile in looked-at cell
      var cell = map.GetTile(new Vector3Int(x, y, z));
      // get initial data linked to cell type. should probably be done via "TryGetValue()"
      var initial = initData[cell.sprite];
      // set initial state for [x, y, z] and **copy** over initial values
      tileStates[x, y, z] = new TileState() { HP = initial.InitialHP };
    }
  }
}

}
}

private Dictionary<Sprite, TileData> GetInitialData()
{
// convert "data" to a dictionary (using "data[n].Sprite" as key and "data[n]" as value)
}

// TileData class
[Serializable]
public class TileData
{
public Sprite Tile;
public int InitialHP;
// ...
}

// TileState struct
public struct TileState
{
public int HP;
}Note that since `TileState` is a `struct`, you have to get, manipulate and set it again to change a tile's value: cs
// get copy of tile state
var state = tileStates[x, y, z];
// modify HP of state
state.HP--;
// re-assign state to tile
tileStates[x, y, z] = state;```

#

Also note that I'm using a three-dimensional array instead of a dictionary, because we won't have to resize the array and thus it's a little lighter on memory than the dictionary.

past fox
#

what does this do

glacial pine
#

It defines a multidimensional array.
Normal (1-dimensional) arrays Type[] are accessed with 1 index.
Multidimensional arrays Type[,] are accessed with n indices, where n is the number of commas between the brackets + 1.

past fox
#

ill google how i can setup this thing untill i find an answer, i do not understand anything

glacial pine
#

Do that.
Or have a look at the code I sent; I'm already setting up the array there (if that's what you mean).

past fox
#

i looked at it, i did not understand most of it

glacial pine
#

That is unfortunate. Perhaps you are better off using prefabs for each tile, then.
Still an option, albeit not the best imo.