Drag Drop with Snap To Grid Feature

Hello there,
Even I checked the forum about this problem, I couldn’t find a proper solution. I am trying to make a game for my graduation project as a graphic design student. Since I am not experienced in scripting, my aim is to create 3D assets and try to find a solution to scripting.

My game will be more likely a table-top game like Dungeons and Dragons, where you put tokens into grids. I have created tiles for my grid-based layout and so, and created a dummy game object to work on “Drag and Drop with Snap to Grid”. So far I managed to use Drag and Drop properly, but cant implement the Snap to Grid unfortunately.

Can someone help me about how to implement snapping to grid into this code?

The code I am using right now (I am more comfortable with JavaScript since I used to make web design with jQuery frameworks)

var object : GameObject;

var normalCollisionCount = 1;
var moveLimit = .5;
var collisionMoveFactor = .01;
var addHeightWhenClicked = 0.0;
var freezeRotationOnDrag = true;
var cam : Camera;
private var myRigidbody : Rigidbody;
private var myTransform : Transform;
private var canMove = false;
private var yPos : float;
private var gravitySetting : boolean;
private var freezeRotationSetting : boolean;
private var sqrMoveLimit : float;
private var collisionCount = 0;
private var camTransform : Transform;
 
function Start () {
	myRigidbody = rigidbody;
	myTransform = transform;
	if (!cam) {
		cam = Camera.main;
	}
	if (!cam) {
		Debug.LogError("Can't find camera tagged MainCamera");
		return;
	}
	camTransform = cam.transform;
	sqrMoveLimit = moveLimit * moveLimit;	// Since we're using sqrMagnitude, which is faster than magnitude
}
 
function OnMouseDown () {
	canMove = true;
	myTransform.Translate(Vector3.up*addHeightWhenClicked);
	gravitySetting = myRigidbody.useGravity;
	freezeRotationSetting = myRigidbody.freezeRotation;
	myRigidbody.useGravity = false;
	myRigidbody.freezeRotation = freezeRotationOnDrag;
	yPos = myTransform.position.y;
}
 
function OnMouseUp () {
	canMove = false;
	myRigidbody.useGravity = gravitySetting;
	myRigidbody.freezeRotation = freezeRotationSetting;
	if (!myRigidbody.useGravity) {
		myTransform.position.y = yPos-addHeightWhenClicked;
	}
}
 
function OnCollisionEnter () {
	collisionCount++;
}
 
function OnCollisionExit () {
	collisionCount--;
}
 
function FixedUpdate () {
	if (!canMove) return;
 
	myRigidbody.velocity = Vector3.zero;
	myRigidbody.angularVelocity = Vector3.zero;
	myTransform.position.y = yPos;
	var mousePos = Input.mousePosition;
	var move = cam.ScreenToWorldPoint(Vector3(mousePos.x, mousePos.y, camTransform.position.y - myTransform.position.y)) - myTransform.position;
	move.y = 0.0;
	if (collisionCount > normalCollisionCount) {
		move = move.normalized*collisionMoveFactor;
	}
	else if (move.sqrMagnitude > sqrMoveLimit) {
		move = move.normalized*moveLimit;
	}
 
    myRigidbody.MovePosition(myRigidbody.position + move);
}
 
@script RequireComponent(Rigidbody)

I didnt read the whole script , but i have an idea for you :

Try to use Physics.OverlapSphere where ever you drop that thing for a certain radius you chose ( to catch at least 4 grid points ) .
This function will put all the colliders in that radius an array, then, use Vector3.Distance funcion to check the distance between you and each coollider in the array .
From this point, all you have to do is :

ThingYouDropped.position=MostColserCollider.position .

Tell me how it goes :slight_smile:

Why bother with all that? If it’s a grid then just round the X and Z components of your move vector to the closest grid increment.

1 Like

Lol, yeah i guess you can to that too XD

Thanks! KelsoMRK’s solution sounds more suitable but I have no idea how to research it. Can you please give me a hint to research or if you have a script like that can you please share? Sounds like a bit hard for me to do it from scratch, but I will do my best!

Thanks again :slight_smile:

I forgot to add something important:
Am I suppose to move pivot point to the corner to make rounding X and Z axis translations work? Otherwise it sounds like it will snap to gridlines instead of middle of the grid.

http://forum.unity3d.com/threads/77029-in-game-snap-to-grid

Vector3 temp;
temp = new Vector3(Mathf.Round(transform.position.x),Mathf.Round(transform.position.y),0);
transform.position = temp;

Edit : Damn LaneFox was Faster ! :S

It is working flawless! Thanks so much guys, now I understand how it is done :slight_smile:
Cheers!

hey I know it’s pretty old thread but can anyone suggest how can I create a list of objects that can be dragged and snapped to position and also There should be bit of elasticity like behavior.