Block dragging on collision in an grid style 2d game

Hello,

Iv’e been trying a long time to get this to work. As it is right now it kind of works. The function im trying to implement is a lot like Clash of Clans, when you drag an item it snaps to the grid and move one tile at the time. When two objects collide i don’t wont them to move or pass through each other. This is my code for moving an object:

using UnityEngine;
using System.Collections;

public class DragSnap : MonoBehaviour{

    private Vector3 screenPosOfObject;
    private Vector3 offset;
    private SpriteRenderer sprite;

    void OnCollisionEnter2D(Collision2D coll){
        Debug.Log ("Coll");
    }

    void OnMouseDown(){
        screenPosOfObject = Camera.main.WorldToScreenPoint(gameObject.transform.position);
        offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPosOfObject.z));
        Cursor.visible = false;
        gameObject.GetComponent<Rigidbody2D> ().isKinematic = false;
        Debug.Log ("Mouse Down");
    }
    
    void OnMouseDrag(){
        Vector3 curMouseScreenPos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, screenPosOfObject.z);
        Vector3 curMouseWorldPos = Camera.main.ScreenToWorldPoint (curMouseScreenPos) + offset;

        gameObject.GetComponent<Rigidbody2D> ().MovePosition (SnapToGrid (curMouseWorldPos));

        sprite = gameObject.GetComponentInChildren<SpriteRenderer>();
        sprite.sortingOrder = ((int) gameObject.transform.position.y)*-1;
    }
    
    void OnMouseUp(){
        gameObject.GetComponent<Rigidbody2D> ().isKinematic = true;
        Cursor.visible = true;
    }

    Vector3 SnapToGrid(Vector3 Position){
        GameObject grid = GameObject.Find ("grid");
        if (! grid)
            return Position;

        //    get grid size from the texture tiling
        Vector2 GridSize = grid.GetComponent<Renderer>().material.mainTextureScale;

        //    get position on the quad from -0.5...0.5 (regardless of scale)
        Vector3 gridPosition = grid.transform.InverseTransformPoint (Position);

        //    scale up to a number on the grid, round the number to a whole number, then put back to local size
        gridPosition.x = Mathf.Round( gridPosition.x * GridSize.x ) / GridSize.x;
        gridPosition.y = Mathf.Round( gridPosition.y * GridSize.y ) / GridSize.y;

        //    don't go out of bounds
        //gridPosition.x = Mathf.Min ( 0.4791667f, Mathf.Max (-0.4791667f, gridPosition.x) );
        //gridPosition.y = Mathf.Min ( 0.4791667f, Mathf.Max (-0.4791667f, gridPosition.y) );

        Position = grid.transform.TransformPoint (gridPosition);
        return Position;
    }
}

This is the result (bad quality but the message is clear):

My problem right now is that the positioning isn’t correct when objects are colliding…
Is there an easier way of solving this?

Edit #1
To clear things up… If an object is at the position (1,1) another object can’t get the position (1,2), instead the the position becomes (1,2.015). Is this due to my SnapToGrid function?

Edit #2
I did the following test to find out if box colliders could touch each other, but it seems like they can’t… Notice the distance between the sprites is 0.015.Images

I, too, am working on a game with dropping items on a grid. In my version, each square uses collision to detect if an item has been dropped on it, but multiple collisions at once and TriggerExit / TriggerEnter being called on different squares at odd times is really giving me grief and the item doesn’t always drop on the square it looks like it should drop on. Does anyone know of a smooth, robust way to implement this kind of thing? Is it a bad idea to use colliders for this kind of 2d item-placing-on-grid game altogether?

I think it’s ok to use colliders, but I would probably prefer to just keep track of the positions in an array or list or something to see if the space(s) is/are already occupied. If so, don’t update the object position. If it’s free, update away.

The offset value is probably due to contact offset, but I’m not sure if that’s an exposed property for Collider2D’s yet. You can read about it in the Collider class, though. Have you just tried making the colliders exactly small enough to compensate? If they use Rigidbody2D’s, they’ll update themselves to be on the edge of collision even if you change their transforms to make them overlap.