playMaker

Author Topic: Destroy only "collided with" rule tiles  (Read 717 times)

LordVecna

  • Playmaker Newbie
  • *
  • Posts: 6
Destroy only "collided with" rule tiles
« on: September 19, 2022, 06:59:01 PM »
I have tried for a week to make this work, and I figured it is time for some help so I can get unstuck and continue to learn.

I am creating a tank dueling game very similar to "Artillery Duel" from the classic atari era. I found a script to procedurally generate a series of tiles as a terrain. I got it working, but it doesn't actually produce "clones" viewable in the hierarchy. Not sure why but I don't think that detail is important at the moment.

The situation is that I fire a mortar from a cannon. That mortar on its collision creates a new object called "explode" that has a larger translucent sprite and a mask to hide the terrain behind it. So it looks like I destroyed the terrain with an explosion, but I haven't actually yet.

The problem is I want to actually destroy the tiles that have now collided with the newly created "explode" objects collider. This is important so the tanks fall when the impact is under them, or a new mortar doesn't continue to collide with terrain that was already impacted.

I placed an FSM on the "explode" object. I have tried messing around with the actions Get Collision Info, Set Tile, Set Rule Tile, Array List Get Object Inside Collider 2d(which had me messing around with tags but that didn't work either) It is a shame I can't just use Destroy Object in a way that lets me remove certain tiles in the collider, instead of destroying the entire terrain.

I am stumped. If someone could just lay it all out for me so I can see what I am doing wrong, or if I am just completely wrong about my way of going about it....I would be eternally grateful. I attached the terrain generating script and a screen cap of the editor if that helps.

Code: [Select]
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;

public class TerrainGenerator : MonoBehaviour
{

    [SerializeField] int width, height;
    [SerializeField] float smoothness;
    [SerializeField] float seed;
    [SerializeField] TileBase groundTile1;
    [SerializeField] Tilemap groundTilemap;
    int[,] map;

    // Start is called before the first frame update
    void Start()
    {
        seed = Random.Range(0, 100000);
        Generation();
    }

     // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {     
            Generation();
        }
    }

    void Generation()
    {
        groundTilemap.ClearAllTiles();
        seed = Random.Range(0,100000);
        map = GenerateArray(width, height, true);
        map = TerrainGeneration(map);
        RenderMap(map, groundTilemap, groundTile1);
    }

    public int[,] GenerateArray(int width, int height, bool empty)
    {
        int[,] map = new int[width, height];
        for (int x = 0; x < width; x++)
        {
            for (int y = +0; y < height; y++)
            {
                if (empty)
                {
                    map[x, y] = 0;
                }
                else
                {
                    map[x, y] = 1;
                }
            }
        }
        return map;
    }

    public int[,] TerrainGeneration(int[,] map)
    {
        int perlinHeight;
        for (int x = 0; x < width; x++)
        {
            perlinHeight = Mathf.RoundToInt(Mathf.PerlinNoise(x / smoothness, seed) * height);
            for(int y = 0; y < perlinHeight; y++)
            {
                map[x, y] = 1;
            }
        }
        return map;
    }

    public void RenderMap(int[,] map, Tilemap groundTileMap, TileBase groundTilebase)
    {
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                if (map[x,y] == 1)
                {
                    groundTilemap.SetTile(new Vector3Int(x, y, 0), groundTilebase);
                }
            }
        }
    }
}

LordVecna

  • Playmaker Newbie
  • *
  • Posts: 6
Re: Destroy only "collided with" rule tiles
« Reply #1 on: September 20, 2022, 06:37:02 PM »
I think after more research, I need to somehow get the tiles in the collider in an array, or detect them from the array and use set tile to null on those tiles. I still can't figure out how to make that happen.

Anyone?

Groo Gadgets

  • Beta Group
  • Full Member
  • *
  • Posts: 175
Re: Destroy only "collided with" rule tiles
« Reply #2 on: September 20, 2022, 07:02:13 PM »
Quote
I got it working, but it doesn't actually produce "clones" viewable in the hierarchy. Not sure why but I don't think that detail is important at the moment.

I think this is the key to your problem. Is the generated terrain one single object with one 2D collider?

LordVecna

  • Playmaker Newbie
  • *
  • Posts: 6
Re: Destroy only "collided with" rule tiles
« Reply #3 on: September 20, 2022, 07:16:06 PM »
Well it looks like it has separate colliders when I click on the Grid parent object. Maybe I am making an assumption here? Is there anything you can see in the script I showed that would tell us if it was one object?

The inspector on the "mountain" object in the scene(child of Grid) shows Tilemap collider 2d

Is it maybe combining itself in to one object, and I need to remove that? Forgive me....I am very very new. Trying to not give up though
« Last Edit: September 20, 2022, 07:49:04 PM by LordVecna »

Groo Gadgets

  • Beta Group
  • Full Member
  • *
  • Posts: 175
Re: Destroy only "collided with" rule tiles
« Reply #4 on: September 20, 2022, 08:37:47 PM »
Right, I see now. It's using Unity's Tilemap component. After doing a search for "tilemap" in the PM forum I found this post which is exactly what you're looking for:
https://hutonggames.com/playmakerforum/index.php?topic=23798.msg103670#msg103670

LordVecna

  • Playmaker Newbie
  • *
  • Posts: 6
Re: Destroy only "collided with" rule tiles
« Reply #5 on: September 20, 2022, 09:23:54 PM »
Funny thing is I already have that, but totally missed the "get tile content to array" which might allow me to give each tile an identity of sorts using its location in the array, then its just finding a way to reference and change those tiles to empty....and then I may also have to refresh it to update the collider.

I will give it another go. Worst case is I get the Destructible 2D asset from the store and go that route.