Search Unity

  1. We've closed the job boards. If you're looking for work, or looking to hire check out Unity Connect. You can see more information here.
    Dismiss Notice
  2. Unity 2017.3 has arrived! Read about it here.
    Dismiss Notice
  3. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

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.
     
  2. jeffreyschoch

    jeffreyschoch

    Joined:
    Jan 21, 2015
    Posts:
    2,145
    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.
     
    Scobiform likes 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.  
     
  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
  5. jeffreyschoch

    jeffreyschoch

    Joined:
    Jan 21, 2015
    Posts:
    2,145
    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.
     
    Scobiform likes this.
  6. rimawi

    rimawi

    Joined:
    Mar 5, 2011
    Posts:
    30
    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.     }
     
  7. jeffreyschoch

    jeffreyschoch

    Joined:
    Jan 21, 2015
    Posts:
    2,145
    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. }
     
  8. rimawi

    rimawi

    Joined:
    Mar 5, 2011
    Posts:
    30
    Thank you it worked