- Home /
Drag Object, same speed as mouse/touch
I am trying to drag an object when left clicking on it or when touching it on a Android device. The problems I have is that the object is moving faster or slower than my mouse.
I found a little script that is almost working, but I still have a problem. When I drag my object, his position sometime jump suddently and my object keeping moving when I drag my mouse, but it is no more on my mouse cursor. While dragging, my object is jumping on and away from my cursor randomly.
Can anyone help me solve this or explain me why this happen.
Here is the code. I need to use perpective camera too.
using UnityEngine;
using System.Collections;
public class Drag_Object : MonoBehaviour {
RaycastHit hit;
// Use this for initialization
void Start () {
hit = new RaycastHit();
}
// Update is called once per frame
void Update () {
}
void OnMouseDrag(){
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, 1000.0f)) {
Vector3 newpos = new Vector3(hit.point.x, hit.point.y, gameObject.transform.position.z);
gameObject.transform.position = newpos;
}
}
}
Hello, I am using this code for my created GameObject. But the problem is that i'am not able to achieve this code. when i drag the mouse my gameobject is not moving.. what should be done??
Answer by Lazrick · Sep 16, 2014 at 06:12 PM
Thx robertbu. I did try your code and with some tune up, I could make it works perfectly for my need. I found another solution too that I wanted to share.
The "linkedObject" is an object that is moving in same time as the dragged object. I did that because for a special reason, I couldn't make the object child of the dragged object. You can remove it if you don't need.
Here my current solution :
using UnityEngine;
using System.Collections;
public class DragObject : MonoBehaviour {
private float dist;
private Vector3 v3Offset;
private Plane plane;
private bool ObjectMouseDown = false;
public GameObject linkedObject;
void OnMouseDown() {
plane.SetNormalAndPosition(Camera.main.transform.forward, transform.position);
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
float dist;
plane.Raycast (ray, out dist);
v3Offset = transform.position - ray.GetPoint (dist);
ObjectMouseDown = true;
}
void OnMouseDrag() {
if (ObjectMouseDown == true){
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
float dist;
plane.Raycast (ray, out dist);
Vector3 v3Pos = ray.GetPoint (dist);
v3Pos.z = gameObject.transform.position.z;
v3Offset.z = 0;
transform.position = v3Pos + v3Offset;
if (linkedObject != null){
linkedObject.transform.position = v3Pos + v3Offset;
}
}
}
void OnMouseOut() {
ObjectMouseDown = false;
}
}
Thx again for your help.
Answer by robertbu · Sep 16, 2014 at 01:57 AM
Your code will use the hit on the surface of the cube as the position to set the object. This means 1) you will end up with a jump the first time the object is clicked, and 2) the object will move closer since the hit is not on the same plane as the object. Actually you want the plane of movement to match the plane of the camera. For an axes aligned camera, it can be done with ScreenToWorldPoint(), or you could create a Quad and use Collider.Raycast(), but a more general solution is to use Unity's mathematical Plane class. The resulting drag code will work for arbitrary camera rotation. Example:
using UnityEngine;
using System.Collections;
public class Drag_Object : MonoBehaviour {
private Vector3 offset;
void OnMouseDown() {
offset = transform.position - GetHitPoint();
}
void OnMouseDrag(){
transform.position = GetHitPoint() + offset;
}
Vector3 GetHitPoint() {
Plane plane = new Plane(Camera.main.transform.forward, transform.position);
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
float dist;
plane.Raycast (ray, out dist);
return ray.GetPoint (dist);
}
}
Note that in general when using Plane.Raycast(), the return value needs to be checked to make sure the plane was hit, but given Camera.main.transform.forward as the normal, as long as the object is in view (which it will be if OnMouseDown/OnMouseDrag fires), then the plane cannot be missed.
Thank you robertbu !! The code works, was having a hard time trying to figure out why Input.$$anonymous$$ousePosition is inaccurate on mobile devices...
Your answer
Follow this Question
Related Questions
Distribute terrain in zones 3 Answers
Touch - drag different objects 1 Answer
Dragging Camera based on Touch 0 Answers
Why does my app function correctly in Unity Remote but not compiled as an app? 0 Answers
Camera up and down on TouchField 1 Answer