Search Unity

Destroy Tile on Collision (Tilemap)

Discussion in '2D' started by Scobiform, Jul 17, 2017.

  1. Scobiform

    Scobiform

    Joined:
    Sep 29, 2014
    Posts:
    3
    Hi there,

    I am trying to destroy just 1 tile at a time on collision in a 2D TileMap. I am using the 2017.2beta and I can debug the collision with the right coordinates, but I am not able to just destroy that 1 tile on contact.

    Also I have a weird bug, my walls (blocking layer) working fine on the outer walls but sometimes my character can just move through them, just in some parts of my tilemap.

    It is really strange, the collisions are all detected and working. What am I missing here?

    Thanks for some adivce.
     
    DBarlok likes this.
  2. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    Welcome to the forums.

    Would you share some code samples for how you're handling the collision/destruction? Be sure to use code tags.

    It's best to just focus on one problem at a time, but for your second point if you see colliders moving through each other, you're either moving them VERY fast, or you're not using the proper functions to move your character so that they take physics into account (or your physics layers aren't set up properly, but since you say it only happens sometimes, that's probably not the case). Your movement should be handled using Rigidbody only, not Transform.
     
    DBarlok and Scobiform like this.
  3. Scobiform

    Scobiform

    Joined:
    Sep 29, 2014
    Posts:
    3
    Ah thank you, moving to rigidbody2d.velocity(x & y) did the trick. Surely I had to hit freeze Rotation Z also and made my Character Dynamic. Collision are now working with all tiles. But my Character lost his 1 tile at a time movement (should be manageable for me to find the solution) and the sound for the footsteps is going nuts now :D

    But anyway, I´m guessing this is the right track. Learned a lot already about vector2 vector3. Appreciate :)

    Here my code for now, just the movement part.
    Code (csharp):
    1.  
    2. public Vector2 velocityX = new Vector2(0,5);
    3. public Vector2 velocityY = new Vector2(5, 0);
    4. public Rigidbody2D rb2D;
    5.  
    6.     void Start()
    7.     {
    8.         rb2D = GetComponent<Rigidbody2D>();
    9.     }
    10.  
    11.     void FixedUpdate()
    12.     {
    13.        
    14.         if (Input.GetKey(KeyCode.UpArrow))
    15.         {
    16.             rb2D.MovePosition(rb2D.position + velocityX * Time.fixedDeltaTime);
    17.  
    18.             animator.SetTrigger("isUpDown");
    19.             StartCoroutine(PlayFootSteps());
    20.         }
    21.  
    22.         else if (Input.GetKey(KeyCode.RightArrow))
    23.         {
    24.             rb2D.MovePosition(rb2D.position + velocityY * Time.fixedDeltaTime);
    25.  
    26.             mySpriteRenderer.flipX = false;
    27.  
    28.             animator.SetTrigger("isWalking");
    29.             StartCoroutine(PlayFootSteps());
    30.  
    31.         }
    32.         else if (Input.GetKey(KeyCode.DownArrow))
    33.         {
    34.             rb2D.MovePosition(rb2D.position - velocityX * Time.fixedDeltaTime);
    35.  
    36.             animator.SetTrigger("isUpDown");
    37.             StartCoroutine(PlayFootSteps());
    38.         }
    39.         else if (Input.GetKey(KeyCode.LeftArrow))
    40.         {
    41.             rb2D.MovePosition(rb2D.position - velocityY * Time.fixedDeltaTime);
    42.  
    43.             mySpriteRenderer.flipX = true;
    44.  
    45.             animator.SetTrigger("isWalking");
    46.             StartCoroutine(PlayFootSteps());
    47.  
    48.         }
    49.         else
    50.         {
    51.             animator.SetTrigger("isIdle");
    52.             StopCoroutine(PlayFootSteps());
    53.         }
    54.  
    55.     }
    56.  
     
    DBarlok likes this.
  4. Scobiform

    Scobiform

    Joined:
    Sep 29, 2014
    Posts:
    3
    For the tile problem:
    Code (CSharp):
    1.  
    2. private void OnCollisionEnter2D(Collision2D collision)
    3.     {
    4.         //Detecting the Grid Position of Player
    5.         if (collision.gameObject.name == "Player")
    6.         {        
    7.             pPos = tilemap.WorldToCell(collision.rigidbody.position);
    8.             Debug.Log("pPos:" + pPos);        
    9.             tilemap.SetTile(pPos, null);
    10.         }
    11.  
    12.     }
    How can I detect the actual tile that collided with the player?

    To destroy a specific tile I can just:

    Code (CSharp):
    1. tilemap.SetTile(new Vector3Int(-7,3,0), null);
    May be I should sleep a few hours over this.
     
    Last edited: Jul 18, 2017
    DBarlok likes this.
  5. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    In OnCollisionEnter, you get a Collision2D object passed into the function, which contains all the information you need about the collision. Using collision.gameObject you could do a GetComponent<Tile>() or whatever you need to in order to figure out which specific tile it is.

    Your code sample there seems like it should work if your WorldToCell function is returning the proper tile position, is it not?

    Also, you can use the function Rigidbody.MovePosition if that's easier. You should be able to use that in place of a transform.position set, without having to get into setting velocity.
     
    DBarlok and Scobiform like this.
  6. rimawi

    rimawi

    Joined:
    Mar 5, 2011
    Posts:
    34
    did you find a solution for this issue i am having same problem
    Code (csharp):
    1.  
    2.  private void OnTriggerEnter2D(Collider2D collision)
    3.     {
    4.         if (collision.gameObject.tag == "shot")
    5.         {
    6.             var tilePos = tilemap.WorldToCell(collision.gameObject.transform.position);
    7.             Debug.Log("location:" + tilePos);
    8.             tilemap.SetTile(tilePos, null);
    9.             tilemap.SetTile(new Vector3Int(tilePos.x, tilePos.y, tilePos.z), null);
    10.         }
    11.  
    12.     }
     
    DBarlok likes this.
  7. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    In the 2D tech demos there is an example of a brick breaker game:
    https://github.com/Unity-Technologies/2d-techdemos

    Here's the ball script:
    https://github.com/Unity-Technologies/2d-techdemos/blob/master/Assets/Tilemap/Brick/Scripts/Ball.cs
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Tilemaps;
    5.  
    6. public class Ball : MonoBehaviour
    7. {
    8.     public Vector2 initialVelocity = new Vector2(1.0f, 10.0f);
    9.     public GameObject tilemapGameObject;
    10.  
    11.     Tilemap tilemap;
    12.  
    13.     void Start()
    14.     {
    15.         var rb = GetComponent<Rigidbody2D>();
    16.         rb.velocity = initialVelocity.x * UnityEngine.Random.Range(-1f, 1f) * Vector3.right + initialVelocity.y * Vector3.down;
    17.         if (tilemapGameObject != null)
    18.         {
    19.             tilemap = tilemapGameObject.GetComponent<Tilemap>();
    20.         }
    21.     }
    22.  
    23.     void OnCollisionEnter2D(Collision2D collision)
    24.     {
    25.         Vector3 hitPosition = Vector3.zero;
    26.         if (tilemap != null && tilemapGameObject == collision.gameObject)
    27.         {
    28.             foreach (ContactPoint2D hit in collision.contacts)
    29.             {
    30.                 hitPosition.x = hit.point.x - 0.01f * hit.normal.x;
    31.                 hitPosition.y = hit.point.y - 0.01f * hit.normal.y;
    32.                 tilemap.SetTile(tilemap.WorldToCell(hitPosition), null);
    33.             }
    34.         }
    35.     }
    36. }
     
    cobear25, DBarlok and callamfry like this.
  8. rimawi

    rimawi

    Joined:
    Mar 5, 2011
    Posts:
    34
    Thank you it worked
     
    DBarlok likes this.
  9. Durium

    Durium

    Joined:
    Feb 1, 2020
    Posts:
    37

    Pleeeease help me with this. collision.contacts does not work anymore....
     
  10. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,423
    You're making multiple posts and just saying it does not work. It does work, it's that you have a problem. Rather than necroing threads, please put some effort into describing what you're doing as your issue isn't necessarily related to the thread at all.