- Home /
Dragging objects like in Amnesia
Hello! My game needs to have some sort of physical interaction, I'd quite like to implement a sort of grab and drag mechanic, much like in Amnesia: The Dark Descent, or like in Anna (a recent indie game made in unity) Where you can simply click on an object and by moving the mouse, it will move the object being dragged around in the 3d world smoothly, does anyone know how to make such a mechanic, and if so, how please? Thanks.
Edit: I would use OnMouseEnter() but my mouse is bound to the centre of my screen and hidden so sadly on mouse enter doesn't work
Answer by Doireth · Jul 19, 2012 at 09:24 PM
A bit messy. (C# version)
using UnityEngine;
using System.Collections;
public class AMnesiaPickup : MonoBehaviour {
public Transform empty;
public LayerMask interactLayer;
private float dist = 0;
private Transform target;
// Update is called once per frame
void Update () {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit h;
if(Physics.Raycast(transform.position, ray.direction, out h, interactLayer) && target == null) {
if(Input.GetButtonDown("Fire1")) {
dist = Vector3.Distance(h.point, transform.position);
empty.position = transform.position+(ray.direction.normalized * dist);
target = h.transform;
}
}
Rigidbody rb = null;
if(target != null) rb = target.GetComponent<Rigidbody>();
if(Input.GetButton("Fire1") && rb) {
rb.isKinematic = true;
target.transform.parent = empty;
empty.position = transform.position + (ray.direction.normalized * dist);
}
if(Input.GetButtonUp("Fire1") && rb) {
rb.isKinematic = false;
target.transform.parent = null;
target = null;
}
}
}
Hope this helps.
EDIT: Javascript version and minor correction to C# version
(Javascript version)
#pragma strict
var empty : Transform;
var interactLayer : LayerMask;
private var dist : float;
private var target : Transform;
function Update () {
var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
var h : RaycastHit;
if(Physics.Raycast(transform.position, ray.direction, h, 100, interactLayer) && target == null) {
if(Input.GetButtonDown("Fire1")) {
dist = Vector3.Distance(h.point, transform.position);
empty.position = transform.position + (ray.direction.normalized * dist);
target = h.transform;
}
var rb : Rigidbody = null;
if(target != null) rb = target.GetComponent(Rigidbody);
if(Input.GetButton("Fire1") && rb) {
rb.isKinematic = true;
target.transform.parent = empty;
empty.position = transform.position + (ray.direction.normalized * dist);
}
if(Input.GetButtonUp("Fire1") && rb) {
rb.isKinematic = false;
target.transform.parent = null;
target = null;
}
}
}
Oops, I forgot. The "empty" mentioned in the script is simply an empty object assigned through the editor. Nothing special has to be done to it, just need it for parenting.
It's not a great solution I know but it may hold you over until you get another.
Can work using this?
http://docs.unity3d.com/Documentation/ScriptReference/Transform-parent.html
public class example : $$anonymous$$onoBehaviour {
public Transform cameraTransform = Camera.main.transform;
void Example() {
cameraTransform.parent = transform;
cameraTransform.localPosition = -Vector3.forward * 5;
cameraTransform.LookAt(transform);
without the empty gameobject
Can't see how it would. You don't want to parent the moving object to the camera as you will/may want the object to move based on the mouse and independent of the camera which I assume would be attached or following the player. The empty object as a parent is cheap and quick.
The empty object requires no special work or changes done to it.
Answer by Alayna · Jul 19, 2012 at 09:25 PM
I am using OnMouseEnter() In my game currently so that when overtop of objects they light up. My cursor is hidden and locked to the center of the screen but it still functions properly. If the script you have with OnMouseEnter() doesnt work it's possible that something else is wrong with it? (I have a reticule in the center of the screen so you can tell where the cursor is despite being hidden)
Unity already has a script built in that allows for similar function as this as well. Its under StandardAssets/Scripts/GeneralScripts/DragRigidBody. It doesnt work perfectly so you'll probably want to refine it but it could be a place to start.
Your answer
Follow this Question
Related Questions
Grab and throw object immediately 1 Answer
Make EventSystem ignore a collider 0 Answers
Grab and Drag Terrain to move camera 0 Answers
Possible to drag items across tabs onto the same frame? 1 Answer