Drag to grid script help?

bad engrish incoming

hi everyone

from the serie “the day that i’ll finaly decide to start with real android game development those experiments could be certainly useful”, this time i’m trying to create a snap-to grid like the one in games like plants vs zombies or bad piggies.
So i have to drag objects and then when i release it it just collocate himself into a “slot” of a grid.
So my approach was that:

create a grid of prefabs: i use a two dimensional array of Vector3s and for every one of them i instantiate the prefab, wich is just a plane (for debug: at the end it’ll just be a collider) with attached a tag called slot (and it just says the prefab’s purpose).

As for the drag system, i just use the oldie but goodie physics.raycast system (not so good with little objects but i’ll find a way to fix it.

Then, at the event onmousedown, the object’s scripts finds the nearest object with the tag slot and the object’s position become the nearest slot’s position.

Is that a good approach? Anyway, that’s the draggable object script:

using UnityEngine;
using System.Collections;

public class draggable : MonoBehaviour
{
    //old drag-drop trick
    private Ray ray = new Ray();
    private RaycastHit hit = new RaycastHit();
    //if we're actually touching the object
    private bool isTouched = false;
    //nearest slot
    Transform slot;
    //slot tag's name 
    public string tagName = "Slot";

    void OnMouseDown()
    {
        isTouched = true;
    }

    void OnMouseUp()
    {
        isTouched = false;
        slot = findNearest();
        //if there is a slot
        if (slot != null)
        {
            transform.position = new Vector3(slot.transform.position.x, slot.position.y, 4.9F);
        }
    }

    Transform findNearest()
    {
        float nearestDistanceSqr = Mathf.Infinity;
        Transform taggedGameObjects = GameObject.FindWithTag(tagName).transform;
        Transform nearestObj = null;
        foreach (GameObject obj in taggedGameObjects)
        {
            Vector3 objectPos = obj.transform.position;
            float distanceSqr = (objectPos - transform.position).sqrMagnitude;

            if (distanceSqr < nearestDistanceSqr)
            {
                nearestObj = obj.transform;
                nearestDistanceSqr = distanceSqr;
            }
        }

        return nearestObj;
    }

    void Update()
    {
        //drag/drop system
        if (isTouched)
        {
            ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out hit))
            {
                transform.position = new Vector3(hit.point.x, hit.point.y, 4.9F);
            }
        }
    }
}

The problem is that… it doesn’t work. Or at least in an half-way, since i can drag the object without problems, but when i release the mouse, the plane doesn’t put himself in the nearest slot.
Since i can’t completely swear about the findNearest’s working garancy but i’m pretty sure that i’m missing something.

Could someone help me please?

Many thanks in advance;

regards, asduffo

You want to use FindGameObjectsWithTag() to find all the tagged objects:

 Transform findNearest()
    {
        float nearestDistanceSqr = Mathf.Infinity;
        GameObject[] taggedGameObjects = GameObject.FindGameObjectsWithTag(tagName);
        Transform nearestObj = null;
        foreach (GameObject obj in taggedGameObjects)
        {
            Vector3 objectPos = obj.transform.position;
            float distanceSqr = (objectPos - transform.position).sqrMagnitude;
 
            if (distanceSqr < nearestDistanceSqr)
            {
                nearestObj = obj.transform;
                nearestDistanceSqr = distanceSqr;
            }
        }
 
        return nearestObj;
    }

Also if you have your game setup on the standard XZ plane, line 28 should be:

        transform.position = new Vector3(slot.transform.position.x, 4.9f, slot.position.z);