Drag/Drop problem

Hi

I have problem with drag and drop script. I was searching everywhere and i found loots of ideas but still nothing what i need.
Everyone asking about “drag object with mouse” but this is simple. I know how to do that and i was trying to change it but always was a problem.

I wanna pick up object using E key (3rd person cam) so his position is at front of the player. When we press E again, then player drop it.

Help me guys. I spend on this two days and still nothing.

Gonna need some more details I think - what have you tried and where is it failing? If you’re at the point where you know what object the player is picking up, then you would just need to update the object’s position each frame to move infront of the player. Hard to give any useful advice without more details.

I don’t have any script now because I destroy it.
That was something like:

private var ray : Ray;
private var hit : RaycastHit;
var hand = Transform;

function Update() {
if(Input.GetButton(“Fire2”){ // Fire2 is a E key
ray = Camera.main.ScreenPointToRay(Input.hand);
if(Physics.Raycast(ray, hit)){
transform.position.x = hit.point.x;
transform.position.y = hit.point.y;
}
}
}

Something like that but this is not working. I’m really new in coding.

Player have invisible box at front, this is a hand. When we coming closer to some box or another object, and we press the Fire button, then this object is in hand. Then we can take it to somewhere and drop it.

Maybe someone have a simple script of it? or some good example.

Hmmm - OK. I can give you general advice and direction, but I program in C# and not Javascript so a good amount of the details involved you’ll have to work at yourself.

I think you can solve your problem by defining 2 script components:

  1. One that keeps track of whatever object (if any) is in range.
  2. One that checks for input and parents/unparents the object in range to the player and enables/disables its Rigidbody IsKinematic property.

For 1: If you are using Unity’s physics engine (as in the “invisible box at front” is a BoxCollider with IsTrigger ticked and your pickable objects have Ridbody and Collider components attached) then component 1 should be attached to the invisible box object and define an OnTriggerEnter method to store a reference to whatever object has triggered it (and setting that reference to null on FixedUpdate to always only have a reference that is valid).

For 2: Use Input.GetButtonUp(“Fire2”) to only toggle picking up / dropping an object once per key press. If we currently have a reference to an object having been picked up then we just need to unparent it and make it not kinematic. Otherwise, we check component 1 for an object that’s in range, parent it to the player, and make it kinematic.

I know you mentioned you’re new to programming, but see how far you can get and I’ll help you more from there.

I write something like this.

private var grabObj:boolean = false;
private var hitObj:GameObject;
private var hit : RaycastHit;
 
function Update() {
 
	if(Physics.Raycast (transform.position,transform.forward, hit, 5)) {
		if(hit.collider.gameObject  Input.GetButtonDown("Grab")  grabObj == false){
			hitObj = hit.collider.gameObject;
			grabObj = true;
		}
	}
		else if(Input.GetButtonDown("Grab")  grabObj == true){
			grabObj = false;
		}
 
	if(grabObj){
		
		hitObj.transform.position.x = gameObject.transform.position.x;
		hitObj.transform.position.y = gameObject.transform.position.y+2;
		hitObj.transform.position.z = gameObject.transform.position.z+2;
	}
}

Works fine but not perfect. Object is always at this same position, even if we turn.

Problem is at this line “hitObj.transform.position.x = gameObject.transform.position.x;”
He should be always at front of the player.

If you have a trigger collider representing that player’s grabbing area you don’t need to do a raycast. Try adding the following scripts to the game object that has your invisible box in front of the player:

#pragma strict
	//ObjectInRange.js	

    public var ObjectInRange : GameObject;
    
    function FixedUpdate()
    {
		ObjectInRange = null;
	}

    function OnTriggerEnter(other : Collider)
    {
		ObjectInRange = other.gameObject;
	}

    function OnTriggerStay(other : Collider)
    {
		ObjectInRange = other.gameObject;
    }

and

#pragma strict
    //GrapDropObject.js

    var ObjectInHand : GameObject;
    var ObjectInRange : ObjectInRange;

    function Update()
    {
		if(Input.GetButtonUp("Fire2"))
		{
			if(ObjectInHand != null)
			{
				ObjectInHand.transform.parent = null;
				ObjectInHand.rigidbody.isKinematic = false;
                                ObjectInHand = null;
			}
			else if(ObjectInRange.ObjectInRange != null)
			{
				ObjectInHand = ObjectInRange.ObjectInRange;
				ObjectInHand.transform.parent = transform;
				ObjectInHand.rigidbody.isKinematic = true;
			}
		}
	}

Just set the GrapDropObject.ObjectInRange reference to the ObjectInRange component and that should be it - once the object in hand is parented to the player (or a child of it) then it will follow and rotate along with it as desired. Make sure that your object has Rigidbody with Collider components and that your grabbing area object has a Collider with IsTrigger ticked.

Looks good. How to change y position for object? Now when I grab it he is on the ground.
When I press again the button to drop, object was dropped but is still in “hand”.

        function OnTriggerEnter(other : Collider)
        {
        	if(other.CompareTag("Dynamic")){
            	ObjectInRange = other.gameObject;
            }
        }
     
        function OnTriggerStay(other : Collider)
        {
            if(other.CompareTag("Dynamic")){
            	ObjectInRange = other.gameObject;

Now i can take only Dynamic objects. Earlier I caught a whole house :stuck_out_tongue:

Oh right, forgot to null out the ObjectInHand reference (updated script to add that line).

If you need to lift the object off the ground I recommend you create an empty game object parented to the player that represents its target position, and interpolate the object’s position when you pick it up to the target over time. You can use Vector3.Lerp to help you with that.

Give it a try - I’ll help if you can describe any problem you run into.

Vector3.Lerp is really easy! Yesterday I trying how to use it but always was something wrong. Today I write this again and works fantastic!
It’s a very simple, just one command line. :sunglasses:

ObjectInHand.transform.position = Vector3.Lerp(hand.position, realHand.position, 2.5);

Roland, You are a good teacher. Thanks. :slight_smile:

You got it - although, I’m a little unsure about your specific use of Lerp. But hey, if it’s working then it doesn’t need fixing.
Good coding to you!