1. We're looking for feedback on Unity Starter Kits! Let us know what you’d like.
    Dismiss Notice
  2. Unity 2017.2 beta is now available for download.
    Dismiss Notice
  3. Unity 2017.1 is now released.
    Dismiss Notice
  4. Introducing the Unity Essentials Packs! Find out more.
    Dismiss Notice
  5. Check out all the fixes for 5.6 on the patch releases page.
    Dismiss Notice
  6. Help us improve the editor usability and artist workflows. Join our discussion to provide your feedback.
    Dismiss Notice

Destroy Tile on Collision (Tilemap)

Discussion in '2D' started by Scobiform, Jul 17, 2017 at 2:39 PM.

  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:
    1,701
    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 at 7:22 PM
  5. jeffreyschoch

    jeffreyschoch

    Joined:
    Jan 21, 2015
    Posts:
    1,701
    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.