Pick Up/Throwing Problem?

Hi All,

I have been trying to find a tutorial on Picking and Throwing on object in Unity for a 2D project and well, I only found one quite old and well it’s useless for asking questions to.

I could tell there were problems with the script just after he starting showing the code and was typing it in line by line, like a good little boy. Until I ran into a problem I couldn’t solve, than I panicked got the whole code pasted it in and played around to get it in the order used in the project. Still didn’t like the look of it, fixed up all the linkages in the code as per the instructions and the code did indeed pick of the objects and throw it as per the title of the vid.

However, there was one major difference, with the code whenever the character picked up the object the character was immediately pushed continually backwards, like an addForce has been applied to the Player controller except I can’t figure out how or why?!? I tried setting the velocity to zero after getting the object but that didn’t work - so I’m completely lost as to what’s happening. So, I am posting the code being used in the hope that one of you may be able to tell me why my player is going backwards at a rate of knots, and also how I might be able to stop this motion. If you are able to help here is a big thankyou in advance.

Regards.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class grabberScript : MonoBehaviour {


    public bool isGrabbed;
    RaycastHit2D hit;
    public float distance = 2f;
    public Transform holdPoint;
    public LayerMask notGrabbed;

    //public LayerMask notGrabbed;
    public float throwForce;

    //stop moving right?!?
    //??
    Rigidbody2D rb;

    // Use this for initialization
    void Start () {
        rb = GetComponent<Rigidbody2D>();   
    }
   
    // Update is called once per frame
    void Update () {
        if (Input.GetKeyDown(KeyCode.B))
        {
            if (!isGrabbed)
            {
                //grab object
                Physics2D.queriesStartInColliders = false;
                hit = Physics2D.Raycast(transform.position, Vector2.right * transform.localScale.x, distance);

                if(hit.collider!= null  && hit.collider.tag =="grabbable")
                {
                    isGrabbed = true;
                    //rb.velocity = new Vector2(-1, 0);
                }
                  
            }
            //thowing
            else if(!Physics2D.OverlapPoint(holdPoint.position,notGrabbed))
            {
                isGrabbed = false;
                hit.collider.gameObject.GetComponent<Rigidbody2D>().velocity =
                    new Vector2(transform.localScale.x, 1) * throwForce;
            }
        }


        if (isGrabbed)
        {
            hit.collider.gameObject.transform.position = holdPoint.position;
            //rb.velocity = new Vector2(-10f, 0);
        }

    }//end Update



    void OnDrawGizmos()
    {
        Gizmos.color = Color.green;
        Gizmos.DrawLine(transform.position, transform.position+ Vector3.right*transform.localScale.x*distance);
    }//end OnDrawGizmos



}//end GrabberScript

Sounds like possibly the collider of the picked-up object and player are interacting, and the physics engine is causing the object to push the player. If that is the case, you could try disabling the object collider or setting the object to kinematic when it is picked up, or set its collider to a Trigger.

1 Like

maybe make it child from the player for the time of grabing.

if (isGrabbed)
        {
hit.collider.gameObject.transform.parent = gameObject.transform;
            hit.collider.gameObject.transform.position = holdPoint.position;
            //rb.velocity = new Vector2(-10f, 0);
        }

then by throwing

else if(!Physics2D.OverlapPoint(holdPoint.position,notGrabbed))
            {
                isGrabbed = false;
hit.collider.gameObject.transform.parent = null;
                hit.collider.gameObject.GetComponent<Rigidbody2D>().velocity =
                    new Vector2(transform.localScale.x, 1) * throwForce;
            }

or use other layer with disabled players collision in the layer matrix

I tried what you said and had a bit of trouble implementing it. The code for some reason if checking twice if an item is grabbed, and it just throws me into an indefinite loop looking at the code. Maybe this shows my in-expertise understanding other people’s code.

Anyway, I set the object to kinematic, and changed it to isTrigger like you said, and picking up the object was no problem whatsoever. Then to throw the object I had to add 2 lines. One to turn off the kinematic, the other to turn off the isTrigger so the item wouldn’t fall through everything :p, which turned out to be easier than I thought.

hit.collider.gameObject.GetComponent().isKinematic = false;
hit.collider.isTrigger = false;

Thanks heaps for your reply Barskey :sunglasses:.

Sorry Vakabaka, I didn’t try out your solution this time, I checked my email and there was Barskey’s reply and immediately set to work from that, didn’t even see your reply till I loaded up the page, but, you’ve help me out heaps already :smile:.

Glad you got it working.

To clarify kinematic and trigger… Setting the collider as a trigger will make it so it does not push your player, and vice versa. Setting the rigidbody to kimematic will make it not be affected by any forces (including gravity), and hence will need to be moved via code. You may not need to do both in your situation.