Pickup and Throw Script Unity

Started by
9 comments, last by xexuxjy 7 years, 4 months ago

I am relatively new to game development and am having a huge problem in my game scripts. I was following this tutorial, ->

, on how to pickup and drop objects.

I've gotten it to work fine for that purpose but I have been trying to add functionality for throwing and seem to have hit a wall (pun intended). It's a literal wall in fact, since every time I throw the object it goes in the same direction no matter which direction I am facing.

I have tried numerous other tutorials to no avail. Either they are outdated or not relevant or broken in some way that I cannot fathom.

I have also tried writing my own from scratch with multiple different ideas on how to accomplish the task , also to no avail.

Nothing I do seems to work and somewhere along the line I did something that broke my game completely. SO much so that even removing every script in the scene still rendered it unplayable....So now I am remaking it and am scared to death of the idea I might break the engine again.

Here are the things that I have tried so far:

Locking the rotation on pickup

Setting a new rotation on throw

setting the rotation to (0,0,0) then throwing

and numerous other slight tweaks to get it to go the direction it is facing

Unfortunately I am a giant noob and can't get anything I try to actually do what I want it to even though I thought I had a pretty good grasp on what I had to do....

Also the object rotates freely in my "hand" and moves when it bumps other objects but this still does not affect it's throw direction. I would love to be able to sort this problem at the same time.

Here is my code from the tutorial, made to work in Unity 5

I am not a particularly good programmer or anything so please break it down for a newbie if you don't mind. Also some explanation of why it works would be awesome so that I can acctually learn from it and apply the concepts in other projects down the road without having to make a forum post everytime I get stuck.

The goal is to be able to pick up an object with a rigidbody (and hopefully make it static in relation to my player while holding it) and throw it in the direction I am facing.

Thanks for any help in advance.


using UnityEngine;
using System.Collections;

public class GrabandDrop : MonoBehaviour {
	GameObject grabbedObject;
	float grabbedObjectSize;

	// Use this for initialization
	void Start () {
	
	}

	GameObject GetMouseHoverObject(float range){


		//Check for Collider with Raycast
		Vector3 position = gameObject.transform.position;
		RaycastHit raycastHit;
		Vector3 target = position + Camera.main.transform.forward * range;
		if (Physics.Linecast(position, target, out raycastHit ))
			return raycastHit.collider.gameObject;
		return null;
	}

	void TryGrabbedObject(GameObject grabObject){

		//Check for Object if not null Grab it
		if (grabObject == null || !CanGrab(grabObject))
			return;
		
		grabbedObject = grabObject;
		grabbedObjectSize = grabObject.GetComponent<Renderer>().bounds.size.magnitude;
	}

	//Can grab condition (RigidBody)
	bool CanGrab(GameObject candidate){
		return candidate.GetComponent<Rigidbody> () != null; 

	}

	void DropObject(){

        //Release Direction and Velocity
        //Set multiplier larger for more force
        grabbedObject.GetComponent<Rigidbody> ().velocity = Vector3.forward * 50;
        

        //Check if hands are empty
        if (grabbedObject = null)
			return;
		//if holding object
		if (grabbedObject.GetComponent<Rigidbody> () != null)
			//stop object before release
			grabbedObject.GetComponent<Rigidbody> ().velocity = Vector3.zero;

	}


	// UPDATE is called once per frame
	void Update () {
		//Assign Input for Grab
		if (Input.GetMouseButtonDown (1)) {


			if (grabbedObject == null)
				TryGrabbedObject (GetMouseHoverObject (5));
			//Set Grab and Drop as Same button (Right Mouse Button)
			else DropObject ();
		}

		if (grabbedObject != null) {
			//Set position of grabbed Object after grabbing
			Vector3 newposition = gameObject.transform.position + Camera.main.transform.forward * grabbedObjectSize;
			grabbedObject.transform.position = newposition;



		}




		Debug.Log (GetMouseHoverObject (5));

	
	}
}

Advertisement

In unity you can rotate vectors with a quaternion multiplication.
There're also direction vectors, those vectors are representations of relative coordinates to the center of your object.


Let's say you want to throw something to the right:

1) Transform.rotation.quaternion*vector(1,0,0) (or you can use transform.right). (I can't recall if it was vector*quaternion or backwards)
2) This will be the first step to your velocity vector, you can add magnitude if you multiply it with a float.

Ah so that might explain why one of my solutions didn't work. I was thinking it projected from the "front face" of the object (set by the direction of pickup) instead of the center of the object but I am still not sure when or how it determines the initial rotation.

I never really understood what that quaternions entail either even though I have scoured the unity docs and tried to make sense of the definition on wikipedia. One of my attempts used quaternion but I can't figure out how they work in the code. Is there any chance you could provide a generic example of how to manipulate them on a game object?

Imagine that quaternion multiplications are like applying a rotation (that means that quat1*quat2 isn't like quat2*quat1). You might get into the analytical stuff sooner or later, but you are ready to go over this problem.

I might add that when I said "center of your object", I was somehow wrong. When you talk about these "direction vectors" the object is always at (0,0,0).

Maybe I am missing something but I have applied them at pickup and at throw and neither one actually does anything noticeable to the object. Is there something I am missing? Is a parent/child thing? Do I set it or read it in? Does it inherit the parent's position? Maybe something to do with rigidbodies? Is it possible that my coding practices are shit? I make 3d models and and such and can rig, animate, etc but the programming aspect is the achilles heel that keeps most of my games from ever being published. Is there some fundamental concept that I obviously do not posses? If there is such a thing I cannot find it on google or youtube?

ANyway, no matter when or where I apply the rotation tt seems it is always the rotation on the object's origin instead of it's current position/rotation. The few times I can make a noticeable difference it is always on some sort of skewed plane I didn't declare. I know this problem should be an easy one but this is essentially the core mechanic of my game and though I have gone through countless iterations of solutions of the problem the real fix still eludes me. And last time I decided to try everything I broke something I couldn't fix even after deleting all of the scripts. ANd I feel like trying new stuff is going to result in the same thing, me remaking the whole thing from scratch.The large majority of my game is ready for alpha testing but without this mechanic it is all for naught. The weird thing is that I have been working on a multitude of scripts for the various mechanics and this is the ONLY one that refuses to cooperate. I am at my wits end here and am seriously considering abandoning the game at this point. Partially because of frustration but also because I have spent weeks on a part of the game I can't get to work and changing that part of the game means changing the whole thing, which I just can't do. Either I finish this thing or give up and I am not sure how I can continue trying to make games when I spend too much time trying to do it already.

Difficult stuff the first time. You need to make sure that you are using the correct components.

Let's say that you have your script in the throwable item.
You know your camera/shoot direction transform. You take your Transform.Forward from that transform, you multiplcate by speed, and then you modifiy the RigidBody.Velocity vector directly (the rigidbody from your throwable).

Not sure if a typo or something, but line 49 looks like you're setting grabbed object to null, rather than testing?

also line 45 you have :

grabbedObject.GetComponent<Rigidbody> ().velocity = Vector3.forward * 50;

when you _probably_ want something like :

grabbedObject.GetComponent<Rigidbody> ().velocity = grabbedObject.transform.forward * 50;

as your update code looks to be already setting the position/rotation of the object.

So I tried using the transform.forward and at least now it can leave my hands at something other than the same direction every time, which is good. But the problem still seems to be that it takes "forward" as a particular face on the object, in my case it seems to be the one that is facing "up" on the cube. When it rotates in my hand it keeps that face as forward but it is always spinning and I can't stop the rotation from in game aside from setting it down and picking it up again. I think the solution would be to set the rotation on pickup and lock it until I throw it but I still can't figure out how to implement that. I know this is probably simple for some people but I am new to programming and though I understand some of the the basic concepts I am still having a hard time figuring out how to manipulate functions of objects and such and getting the results I expect from them.

Finally figured it out.

I needed to set the rotation of the picked object like this:


var newRot = gameObject.GetComponent<Rigidbody> ().transform.rotation;
            grabbedObject.transform.rotation = newRot;

Really wish it wouldn't have taken me a week and a broken game to figure it out though.

This topic is closed to new replies.

Advertisement