Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Pick Up/Throwing Problem?

Discussion in '2D' started by CelticKnight, Nov 6, 2018.

  1. CelticKnight

    CelticKnight

    Joined:
    Jan 12, 2015
    Posts:
    378
    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.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class grabberScript : MonoBehaviour {
    6.  
    7.  
    8.     public bool isGrabbed;
    9.     RaycastHit2D hit;
    10.     public float distance = 2f;
    11.     public Transform holdPoint;
    12.     public LayerMask notGrabbed;
    13.  
    14.     //public LayerMask notGrabbed;
    15.     public float throwForce;
    16.  
    17.     //stop moving right?!?
    18.     //??
    19.     Rigidbody2D rb;
    20.  
    21.     // Use this for initialization
    22.     void Start () {
    23.         rb = GetComponent<Rigidbody2D>();  
    24.     }
    25.    
    26.     // Update is called once per frame
    27.     void Update () {
    28.         if (Input.GetKeyDown(KeyCode.B))
    29.         {
    30.             if (!isGrabbed)
    31.             {
    32.                 //grab object
    33.                 Physics2D.queriesStartInColliders = false;
    34.                 hit = Physics2D.Raycast(transform.position, Vector2.right * transform.localScale.x, distance);
    35.  
    36.                 if(hit.collider!= null  && hit.collider.tag =="grabbable")
    37.                 {
    38.                     isGrabbed = true;
    39.                     //rb.velocity = new Vector2(-1, 0);
    40.                 }
    41.                  
    42.             }
    43.             //thowing
    44.             else if(!Physics2D.OverlapPoint(holdPoint.position,notGrabbed))
    45.             {
    46.                 isGrabbed = false;
    47.                 hit.collider.gameObject.GetComponent<Rigidbody2D>().velocity =
    48.                     new Vector2(transform.localScale.x, 1) * throwForce;
    49.             }
    50.         }
    51.  
    52.  
    53.         if (isGrabbed)
    54.         {
    55.             hit.collider.gameObject.transform.position = holdPoint.position;
    56.             //rb.velocity = new Vector2(-10f, 0);
    57.         }
    58.  
    59.     }//end Update
    60.  
    61.  
    62.  
    63.     void OnDrawGizmos()
    64.     {
    65.         Gizmos.color = Color.green;
    66.         Gizmos.DrawLine(transform.position, transform.position+ Vector3.right*transform.localScale.x*distance);
    67.     }//end OnDrawGizmos
    68.  
    69.  
    70.  
    71. }//end GrabberScript
     
  2. barskey

    barskey

    Joined:
    Nov 19, 2017
    Posts:
    207
    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.
     
    vakabaka likes this.
  3. vakabaka

    vakabaka

    Joined:
    Jul 21, 2014
    Posts:
    1,153
    maybe make it child from the player for the time of grabing.
    Code (CSharp):
    1. if (isGrabbed)
    2.         {
    3. hit.collider.gameObject.transform.parent = gameObject.transform;
    4.             hit.collider.gameObject.transform.position = holdPoint.position;
    5.             //rb.velocity = new Vector2(-10f, 0);
    6.         }
    then by throwing
    Code (CSharp):
    1. else if(!Physics2D.OverlapPoint(holdPoint.position,notGrabbed))
    2.             {
    3.                 isGrabbed = false;
    4. hit.collider.gameObject.transform.parent = null;
    5.                 hit.collider.gameObject.GetComponent<Rigidbody2D>().velocity =
    6.                     new Vector2(transform.localScale.x, 1) * throwForce;
    7.             }
    or use other layer with disabled players collision in the layer matrix
     
  4. CelticKnight

    CelticKnight

    Joined:
    Jan 12, 2015
    Posts:
    378
    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<Rigidbody2D>().isKinematic = false;
    hit.collider.isTrigger = false;

    Thanks heaps for your reply Barskey :cool:.

    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 :D.
     
  5. barskey

    barskey

    Joined:
    Nov 19, 2017
    Posts:
    207
    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.