Okay, guys, I happen to have this one pretty well figured out, at least for my purposes which involves click drag objects over a flat plane with a snap-to grid. There are several parts.
- “Holder.cs” the part that is being moved. this one has the “Holder” script attached to it.
- “HolderCollider.cs” sometimes you want the collider to be a different shape than the main parent game object, so I made a separate script for the child object that has the actual collider attached to it. This is optional.
so we have a game object hierarchy
So now the main GameObject, the parent object, can be an empty game object or character mesh or whatever contains the “Holder.cs” script. If this has a collider then you don’t need HolderCollider.cs.
If you want a separate collider object, then add a child object with the collider, and add the “HolderCollider.cs” script to it.
- the “Raycaster.cs” script which pays attention to where the mouse itself is. t/his is separate and can be a component of an empty ggame object.
Note in the background, the ‘floor’ of the world I am not using a terrain, but a plane which is a collider.
Start with the main script, Holder.cs which you put in the parent of the drag drop object:
using UnityEngine;
using System.Collections;
public class Holder : MonoBehaviour
{
Raycaster raycaster;
void Start()
{
// Find Raycaster Script:
GameObject raycasterObject = GameObject.Find("Raycaster");
raycaster = raycasterObject.GetComponent<Raycaster>();
}
public void OnMouseDown()
{
Select(true);
raycaster.Select(this);
}
public void OnMouseUp()
{
raycaster.LetGo();
}
public void Select(bool isit)
{
// put special effects here, if you want the object to Glow when it is selected
}
}
Now add the HolderCollider.cs which you add to the collider game object, which is a child of the main game object.
This is where the collider recognizes the mouse click and passes it on that the object is clicked:
using UnityEngine;
using System.Collections;
public class HolderCollider : MonoBehaviour
{
public Holder holder;
void OnMouseDown()
{
holder.OnMouseDown();
}
void OnMouseUp()
{
holder.OnMouseUp();
}
}
Now we know if we’re clicked or not, and pass the info on to the Raycaster, which moves things:
Raycaster.cs can be attached to an empty game object named “Raycaster”.
using UnityEngine;
using System.Collections;
public class Raycaster : MonoBehaviour
{
// Grid data:
float gridSnap = 2.0f;
bool dragging;
RaycastHit hit;
float adjustedHeight = 0.0f;
// Item data:
public Holder part; // the previously selected Part
Holder partScript; // the presently selected Part
// Click data:
float clickStart;
bool clicked = false;
void Update () {
if(clicked)
{
if (clickStart < Time.time - 0.2f)
{
clicked = false;
dragging = true;
}
}
if(dragging)
{
if(Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 500.0f, layerMask))
{
if(part != null)
{
Vector3 worldPosition = hit.point;
worldPosition.y = adjustedHeight;
float temp = (hit.point.x - gridSnap/2) % gridSnap + gridSnap/2;
worldPosition.x = hit.point.x - temp;
temp = (hit.point.z - gridSnap/2)% gridSnap + gridSnap/2;
worldPosition.z = hit.point.z - temp;
part.transform.position = worldPosition;
}
}
}
}
public void Select(Holder moveablePart)
{
if(moveablePart == null) return;
// first un-select last item:
if(part != null)
if(moveablePart != part)
{
part.Select(false);
}
// now load the new part:
this.part = moveablePart;
// and begin the placing procedure:
//placing = true;
clicked = true;
clickStart = Time.time;
}
public void Deselect()
{
// Un-select selected item:
if(part != null) part.Select(false);
part = null;
}
public void LetGo()
{
clicked = false;
dragging = false;
}
}
These are sections from my fully functioning scripts, and I didnt’ test them on their own, but I hope this helps everyone get going in the right direction toward full functioning click and drag action.
The “if (clicked)” part is in the Raycaster script to set the time where it’s not a click and release, but a click and drag. One click won’t work, you have to hold your mouse button down for more than 0.2 seconds for it to work.
This is all me just trying to figure it out. Constructive criticism is welcome. As is feedback on coding / functionality issues. Otherwise enjoy!