- Home /
Drag a Specific GameObject around the screen in a 2.5 sidescroller
I have a 2.5d Sidescroller and I need to find a way to drag a specific platform with my mouse.
(I don't want it to be a Rigidbody.)
I also need the platform only to be drag-able along 2 axis (x,y).
Answer by Bunny83 · Apr 16, 2011 at 01:03 AM
First, a rigidbody is needed if you want to move an object and want that other objects can interact with it. If you set the rigidbody to isKinematic
it can only be moved by a script. If the platform isn't moving it's like there's no rigidbody, but if you move it (draggin or auto-moving like an elevator) you need a rigidbody. Otherwise the platform can pass through everything.
Now to your problem:
It might be a bit complicated for complete beginners but i would use the Plane class. Just create an infinite plane through your 0 z-level so you can raycast against it. That way you get the point on this plane and that's "almost" all you need ;)
You didn't tell us what language you're using so i use my preferred one (C#)
(tested and works, just attach it to the platform)
using UnityEngine; using System.Collections;
public class DragObject : MonoBehaviour { private Plane plane; private bool dragging = false; private Vector3 offset;
void Start ()
{
// the first vector is the normal vector pointing towards us.
// that results in a xy-plane.
// the point at the end specifies through which point the plane goes
plane = new Plane(-Vector3.forward,new Vector3(0,0,0));
}
Vector3 GetMousePos()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
float distance;
if (plane.Raycast(ray, out distance))
{
return ray.GetPoint(distance);
}
return Vector3.zero;
}
void OnMouseDown()
{
dragging = true;
offset = transform.position - GetMousePos();
}
void Update ()
{
if (dragging && Input.GetMouseButton(0))
{
transform.position = GetMousePos() + offset;
}
else
{
dragging = false;
}
}
}
edit
Here's the quickly converted JS version ;) most stays the same:
private var plane : Plane; private var dragging = false; private var offset : Vector3;
function Start () { plane = new Plane(-Vector3.forward,new Vector3(0,0,0)); }
function GetMousePos() : Vector3 { var ray = Camera.main.ScreenPointToRay(Input.mousePosition); var distance : float; if (plane.Raycast(ray, distance)) { return ray.GetPoint(distance); } return Vector3.zero; }
function OnMouseDown() { dragging = true; offset = transform.position - GetMousePos(); }
function Update () { if (dragging && Input.GetMouseButton(0)) { transform.position = GetMousePos() + offset; } else { dragging = false; } }
Thanks a lot, this worked perfectly and i greatly appreciate the help
Thanx Shaun
Hey i like this script although, i am wanting to move an object in my game to another spot by clicking and then moving it and then unclicking. It works with this script except its not perfect, when click and try to move it it starts to head towards the camera and then it dissapears if i keep moving it. i only want the object to move along the x,z axis. ?
I think this script drags in XY plane, not XZ. So, you want this scripts Y movement to translate to Z movement. You need to "swap" the Y and Z components of the vector returned by Get$$anonymous$$ousePos().
To be honest I didn't completely read Bunny's script so please tell me if I misunderstood something really bad :D
If you want a different "plane", just create it as you need it. The normal vector of my plane is -z (-forward) so the plane is the x-y-plane. When you want the x-z-plane you need +y (+up) as normal:
plane = new Plane(Vector3.up, Vector3.zero);
This is a mathematical plane defined by a point and a normal vector
Answer by Fattie · Mar 19, 2017 at 10:30 PM
Here's the easiest way. Very simply:
Actually make a plane,
it will be your "touch plane".
Put it anywhere you want.
(Make it big enough to cover the whole camera frustrum.)
Of course, just turn off the renderer so it is invisible.
Copy and paste Drag.cs
below. Put Drag
on the blue object.
Be sure to drag your "touch plane" to the Plane
variable.
You're done. It all works.
// Drag.cs - 2017
using UnityEngine;
public class Drag : MonoBehaviour {
public MeshCollider plane; // drag your plane to here in the Editor
private Vector3 holdOffset;
private bool dragging = false;
Vector3 PointOnPlane() {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit h;
if (plane.Raycast(ray, out h, 30f)) { return h.point; }
return Vector3.zero;
}
void OnMouseDown() {
dragging = true;
holdOffset = transform.position - PointOnPlane();
}
void OnMouseUp() { dragging = false; }
void Update () { if (dragging) { transform.position = PointOnPlane() + holdOffset; } }
}
That's it.
note Unity currently have a laughable bug, where in short, a lot of stuff doesn't work if you happen to have two monitors. In this example, if you have the Play window on one of your monitors and the Scene window on another monitor, it won't work when you try to Play in the editor. (You'll see the position sort of flickers when you drag.) Just another unity screw-up. Simply keep the Play window on the same monitor, or of course just build to a device.
Your answer
Follow this Question
Related Questions
rotate 2d circle on z axis ? 1 Answer
I'm not sure how to approach this. 2 Answers
How to move objects away from each other (not what you think) 1 Answer
2D Animation does not start 1 Answer