Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

3D character picking up item

Discussion in 'Physics' started by M_Keyla_M, May 28, 2020.

  1. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    Hey everyone!
    I want my 3D character to be able to pick up an item, hold it in both hands and walk around with it but i can't seem to find a tutorial for this. I don't want the object to go straight to inventory, it should stay in the characters hands. When you drop the object it should just rag doll on the ground. It's a third person game btw.
    I hope anyone can help me! :)
     
    KatinkaMom likes this.
  2. elliotfriesen

    elliotfriesen

    Joined:
    Mar 17, 2020
    Posts:
    71
    This is a very general way of doing it but you can create a box collider with a trigger surrounding the object and when the player enters the trigger you can enable a function to let you pick it up. Then when the button is clicked that you want to pick up items, your going to want to set the object to be a child of the arms then set the position of the object to the position of the hands. Then when you want to drop it just simply remove it from the parent object.
     
    shbeeb likes this.
  3. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    Oo thank you! i totally understand what you're saying! however...im a noob when it comes to scripting and stuff so i don't know how to make your advice into a reality XD any chance you wanna help me set it up?
     
  4. elliotfriesen

    elliotfriesen

    Joined:
    Mar 17, 2020
    Posts:
    71
    Below is the code for a simple version. For the setup in the scene view you are going to want to attach a collider to the gameobject you want to pick up also another collider but mark it as trigger, then add a rigidbody, and tag the gameobject exactly the same as the one you use in the code shown below. I tried explaining what each part does next to each line of code but if it isnt thorough enough or if there are any problems then reply and I'll try to fix it
     
    Last edited: May 28, 2020
    saschasaft likes this.
  5. elliotfriesen

    elliotfriesen

    Joined:
    Mar 17, 2020
    Posts:
    71
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PickUpObject : MonoBehaviour
    6. {
    7.     public GameObject myHands; //reference to your hands/the position where you want your object to go
    8.     bool canpickup; //a bool to see if you can or cant pick up the item
    9.     GameObject ObjectIwantToPickUp; // the gameobject onwhich you collided with
    10.     bool hasItem; // a bool to see if you have an item in your hand
    11.     // Start is called before the first frame update
    12.     void Start()
    13.     {
    14.         canpickup = false;    //setting both to false
    15.         hasItem = false;
    16.     }
    17.  
    18.     // Update is called once per frame
    19.     void Update()
    20.     {
    21.         if(canpickup == true) // if you enter thecollider of the objecct
    22.         {
    23.             if (Input.GetKeyDown("e"))  // can be e or any key
    24.             {
    25.                 ObjectIwantToPickUp.GetComponent<Rigidbody>().isKinematic = true;   //makes the rigidbody not be acted upon by forces
    26.                 ObjectIwantToPickUp.transform.position = myHands.transform.position; // sets the position of the object to your hand position
    27.                 ObjectIwantToPickUp.transform.parent = myHands.transform; //makes the object become a child of the parent so that it moves with the hands
    28.             }
    29.         }
    30.         if (Input.GetButtonDown("q") && hasItem == true) // if you have an item and get the key to remove the object, again can be any key
    31.         {
    32.             ObjectIwantToPickUp.GetComponent<Rigidbody>().isKinematic = false; // make the rigidbody work again
    33.          
    34.             ObjectIwantToPickUp.transform.parent = null; // make the object no be a child of the hands
    35.         }
    36.     }
    37.     private void OnTriggerEnter(Collider other) // to see when the player enters the collider
    38.     {
    39.         if(other.gameObject.tag == "object") //on the object you want to pick up set the tag to be anything, in this case "object"
    40.         {
    41.             canpickup = true;  //set the pick up bool to true
    42.             ObjectIwantToPickUp = other.gameObject; //set the gameobject you collided with to one you can reference
    43.         }
    44.     }
    45.     private void OnTriggerExit(Collider other)
    46.     {
    47.         canpickup = false; //when you leave the collider set the canpickup bool to false
    48.      
    49.     }
    50. }
    51.  
     

    Attached Files:

  6. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    Thank you so much! I will try this out tomorrow and I’ll let you know how it went! Many many thanks!
     
    ag_bellegarde likes this.
  7. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    Hey! i applied the code and it works almost perfectly!! i just can't get the item to be dropped once i pick it up. and is there a way to add an animation to the pick up movement?
    Thanks again for helping me!
     
  8. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    And my character moves back (as if a force is being applied to it) when i pick up the object. Im guessing it's because of the colliders of the object and the character touching because when the object is far away enough it stops moving the character back but the place the object is at makes it look weird. Any easy way to fix this?
     
  9. elliotfriesen

    elliotfriesen

    Joined:
    Mar 17, 2020
    Posts:
    71
    Sorry about the code I forgot to put in one function. To be able to drop an item you are going to want to say "hasItem = true" under the input.getkeydown("e") function, you should put it below the other lines of code where it says to make the object a child of your hands, and then under the input.GetKeyDown("q") function you are going to want to say hasItem = false. That should fix the dropping of the item

    also for the animation, you can create a picking up animation or find one online and trigger it when you press the pick up key, and just delay the item that goes into your hand by how ever amount of time till your hand reaches the ground in the animation so it would look like you are picking it up

    And for the knocking back of the character, you could decrease the mass of the item so that it wont have as big as an effect on the player. If that doesn't work there is one more way to fix it which is that you can disable the collider of the item when you pick it up which would most likely fix the problem but would require two more lines of code which is perfectly fine too.
     
  10. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    Thank you! i can drop the object now! :D
    the knockback is still there even when i lower the mass but i just made the normal collider small enough so it doesn't pose a problem anymore, however it would be great if i could have the 2 lines of code just incase! the object im picingup right now is an apple but i worry that when i use a different object im gonna struggle with the colliders.
    And for the animation, how do i trigger it when i press the pick up button? i figure i have to add a line of code for that. A bool method im guessing?
     
  11. elliotfriesen

    elliotfriesen

    Joined:
    Mar 17, 2020
    Posts:
    71
    I added the collider lines of code to it and in order to trigger an animation you can do many different methods, my favorite is to use the integer function, so to do this go to your asset folder and right click and create a new animator controller then double click it to open it up in the animator window, if it is not there then go to window, animator window then inside the animator you should see a green bar and right click anywhere inside the animator window, create an empty state, then drag and drop your animation into the window. Then to set up the animation you can use a integer by going over to the parameters in the animator window and create a new integer and call it anything you like, for example if you call it "pickUp" then you click enter and it should save the parameter. Then right click on the empty state and set it as "set layer as default state" unless it already is, once completed you should have a empty state that is orange and your animation which is gray. To connect them, right click on the orange state and select create transition, drag it to the other animation and do the same to the your animation and drag it to the empty state. Then select the arrow and click the plus and create a condition, you should be able to set the integer to any number. On the arrow pointing toward the grab animation set it as one, and the one in reverse. In the code i added the animation script also, so it should work



    this is a link to a video that shows what I wrote above, sorry if you already know how to use the animation window but I tried to explain it just in case
    one more thing in the code I forgot to reference to animator so in the start method say "anim = GetComponent<Animator>();"
     

    Attached Files:

  12. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    Thank you again! but unfortunately my character has stopped picking the object up :( it says object reference not set to an instance of an object
     
  13. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    unity also references to line 28 in the code
     
  14. elliotfriesen

    elliotfriesen

    Joined:
    Mar 17, 2020
    Posts:
    71
    Do you have a animator component on your character because if not then it won’t work
     
  15. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    I do yea because I’m already using an idle and walk animation
    I added the pick up animation to my already usable idle animation using the transitions you said
     
  16. elliotfriesen

    elliotfriesen

    Joined:
    Mar 17, 2020
    Posts:
    71
    Nother reason it might not work for line 28 is becuase your animation controller parameters have to be exactly the same as you typed in the line anim.SetInteger("pickUp", 1) it is cap sensitive so make sure that your parameter is spelt the same
    if that doesnt work can you send your error log
     
  17. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    Unfortunately that ain't it either, i did misspell it at first but i changed but it still shows the error :( This is the error i get every time i start pressing the "e" key
     

    Attached Files:

  18. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    This is what the animator looks like
     

    Attached Files:

  19. elliotfriesen

    elliotfriesen

    Joined:
    Mar 17, 2020
    Posts:
    71
    did u reference the animator controller by saying anim = GetComponent<Animator>(); in the start method
     
  20. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    That worked to get the pick up and dropping back on! The character has also stopped moving backwards when picking up! just the animation won’t work but I’ll try and fix that...if I can XD
    Thank you so much for your help! Any chance I could come to you with more questions??
     
  21. elliotfriesen

    elliotfriesen

    Joined:
    Mar 17, 2020
    Posts:
    71
    Yea anytime! if you have any questions on Game dev you can email me here "elliot.friesen7@gmail.com" And I'll try to get back to you asap
     
  22. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    How would I go about adding a walking with object animation and a idle while holding object animation? I already have a normal walking and idle animation
    How would I make those transitions? Do I edit the script?
     
  23. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    Thank you so much! You have no idea how badly I need your help! I have big plans for my game but no idea how to actually do it
     
  24. elliotfriesen

    elliotfriesen

    Joined:
    Mar 17, 2020
    Posts:
    71
    you would have to create new animations for each and then in the script you can check if the player has an item by the function if(hasItem == true) and then if it is true then trigger the new item in hand animations, and if it is not true then you can trigger the normal animations, to answer your question from above, also no problem!
     
  25. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    I think I almost have it!
    I used the pickup Int for the transition from idle to holding and back (only going back to idle doesn't work)
    And i used my IsWalking bool for the transition for walking and holding so the holding animation knows when the character is walking :)
    So only going back to idle (and then ofcourse also going back to normal walking) doesn't work.
    I figure the normal animations should trigger when you press Q to drop the item, right?
     

    Attached Files:

  26. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    so i figured out how to get it to go back to idle but it happens after a few seconds.
    So you press E, the character picks up the object and plays the holding animation. That goes well, except it changes back to idle after a few seconds of holding. How do i make it continue to use the holding animation?? i already set it on loop but that didn't do the trick.
     
  27. elliotfriesen

    elliotfriesen

    Joined:
    Mar 17, 2020
    Posts:
    71
    instead of the line StartCoroutine(waitforanimation()); your going to want to make some other way of transitioning it back, you might just be able to say anim.SetInt("pickUp", 0); when you press q if that's what you are looking for
     
  28. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    That worked!!! Took me a couple times to get it right in the script but it worked!!! thank you so much!
    I will go on with the next step now which is making a potion crafting system (you drop a base, water or something in else, in a pot together with 3 ingredients and that will create a potion)
    Will try to figure this out myself! but if I can’t I’ll send you an email! Thnx again!
     
  29. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    oke wait! one more thing!
    So i have been using your script to try and make the object drop in a designated spot when you get to the collider. Like when you wish to put a potion bottle on a shelf.
    When you press Q (to drop) the object should position itself into the designated spot, ofcourse you should also be able to remove it with E. Is there also a way to have multiple designated spots?
    So far i just butchered your code XD but i got the designated spot to work, except for the following issues:
    -The spot always triggers when i press Q, so not when you're in the collider
    -The object doesn't stay in an upright position ( i guess that's because i left the rigidbody on..)
    -When you pick op de object the character moves back, like a force is applied to it.

    Below you can find the butchered code, sorry i made a mess of it but i hope you have a way to make things right.
    This is how i try to learn so i can one day do it myself :)

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlaceObject : MonoBehaviour
    6. {
    7.     private Animator anim;
    8.     public GameObject ItemSpot; //reference to your hands/the position where you want your object to go
    9.     bool candropdown; //a bool to see if you can or cant drop the item
    10.     GameObject ObjectIwantToPickUp; // the gameobject onwhich you collided with
    11.     bool hasItem; // a bool to see if you have an item in your hand
    12.                   // Start is called before the first frame update
    13.  
    14.     void Start()
    15.     {
    16.         anim = GetComponent<Animator>();
    17.         candropdown = false;    //setting both to false
    18.         hasItem = true;
    19.     }
    20.  
    21.     // Update is called once per frame
    22.     void Update()
    23.     {
    24.      
    25.         if (Input.GetButtonDown("q") && hasItem == true) // if you have an item and get the key to remove the object, again can be any key
    26.         {
    27.             BoxCollider[] bc = ObjectIwantToPickUp.GetComponents<BoxCollider>();
    28.             foreach (BoxCollider b in bc)
    29.             {
    30.                 b.enabled = true;
    31.             }
    32.             ObjectIwantToPickUp.GetComponent<BoxCollider>().enabled = true;
    33.             ObjectIwantToPickUp.GetComponent<Rigidbody>().isKinematic = true; // make the rigidbody work again
    34.             hasItem = true;
    35.             ObjectIwantToPickUp.transform.position = ItemSpot.transform.position; // sets the position of the object to your hand position
    36.                 ObjectIwantToPickUp.transform.parent = ItemSpot.transform; //makes the object become a child of the parent so that it moves with the hands
    37.         }
    38.     }
    39.     private void OnTriggerEnter(Collider other) // to see when the player enters the collider
    40.     {
    41.         if (other.gameObject.tag == "object") //on the object you want to drop set the tag to be anything, in this case "object"
    42.         {
    43.             candropdown = true;  //set the drop down bool to true
    44.             ObjectIwantToPickUp = other.gameObject; //set the gameobject you collided with to one you can reference
    45.         }
    46.     }
    47.     private void OnTriggerExit(Collider other)
    48.     {
    49.         candropdown = false; //when you leave the collider set the candropdown bool to false
    50.  
    51.     }
    52.     IEnumerator waitforanimation()
    53.     {
    54.  
    55.         yield return new WaitForSeconds(1);
    56.         anim.SetInteger("pickUp", 0);
    57.     }
    58. }
     
    asig396 likes this.
  30. elliotfriesen

    elliotfriesen

    Joined:
    Mar 17, 2020
    Posts:
    71
    I think your going to want to say if (Input.GetButtonDown("q") && candropdown == true) instead of if (Input.GetButtonDown("q") && hasItem == true)becuase in the script you sent has item will always be true
     
  31. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    I changed it but the issues stayed the same :(
     
  32. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    I just figured because your script had a pick up and drop down method based on colliders, I should be able to modify that to work for dropping something in a designated spot once you step in the collider and also pick it up again when you enter the collider
    The object should stay upright though, in its original position
     
  33. elliotfriesen

    elliotfriesen

    Joined:
    Mar 17, 2020
    Posts:
    71
    you can do it the same way, are you sure that the designated spot has a trigger tagged with the correct name, also for the rotation you can do this
    public GameObject object;
    //then in the start method
    {
    this.transform.rotation = object.transform.rotation
    }
    this will set a gameobject to your pick up objects rotation in the start of the game, then when you drop the item set the rotation of the object to the previously scripted objects rotation by doing a similar script
     
  34. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    Ah oke! I feel rude asking this because you’ve helped me so much already but...any chance you could show me how? Like how to make the new script for this?
    I have 0 knowledge when it comes to scripting
    Of course I’ll be trying on my own too! Because I really wanna learn how to do this
     
  35. elliotfriesen

    elliotfriesen

    Joined:
    Mar 17, 2020
    Posts:
    71
    It’s ok I’m perfectly fine in doing it, I don’t have my computer on me right now but once I get get it I’ll write the code in visual studio
     
  36. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    Thank you so much! I’ll wait!
    I hope I can learn a lot from you so I can help others too one day :)
    will also credit you when I finish the demo for my game! I already made some connections with game companies for when it’s done
     
  37. M_Keyla_M

    M_Keyla_M

    Joined:
    Dec 24, 2014
    Posts:
    57
    Hiii! Did you get a chance to look at the new code?
     
  38. Menatombo

    Menatombo

    Joined:
    Feb 6, 2014
    Posts:
    26
    Sorry to necro this, but I wanted to mention that this has helped me out a lot! I was trying to pick up and move objects and this code put me on the right path.
     
    PutridEx likes this.
  39. Gtw_

    Gtw_

    Joined:
    Jul 4, 2022
    Posts:
    1
    poor keyla, she never got answered :(
     
    M_Keyla_M likes this.
  40. D2fficial

    D2fficial

    Joined:
    Dec 14, 2022
    Posts:
    1
    rip :(
     
    M_Keyla_M likes this.
  41. Dabomguy77

    Dabomguy77

    Joined:
    Jun 8, 2023
    Posts:
    1
    which object do you apply the code to?
     
  42. Bulletez

    Bulletez

    Joined:
    Nov 12, 2023
    Posts:
    1
    fortnite