So my goal at the moment is to make my character able to pick up a weapon from the ground when pointing at it and clicking F. Im also planning on adding a animation for when a weapon is picked up. My question here is how do I do this, I cant seem to figure it out, thanks.
Also I have no inventory system so far, so when the character picks up the weapon it should be that he can only hold one at a time, thanks.
Ok I appreciate the reasponse and I will definitely use those links. But I am very new to this and don’t even know where to start. Any help to get me started is appreciated.
Lets assume you have a collider on your weapon gameObject.
You’d have to do something like this :
public GameObject playerCamera; //this is a reference to the main camera (drag & drop)
// Update is called once per frame
void Update()
{
RaycastHit hitInfo; //a structure to hold hit information (gameobject we hit, position of the "impact" etc.)
Ray r = new Ray(playerCamera.transform.position, playerCamera.transform.forward); //A ray starting from the camera, going forward
//if we hit something
if(Physics.Raycast(r, out hitInfo))
{
//if it is tagged as a weapon
if (hitInfo.transform.CompareTag("Weapon"))
{
//if the user presses F
if (Input.GetKeyDown(KeyCode.F))
{
/*code to put the weapon in the player hands.
For instance you could have a playerHands gameobject and make the weapon transform
To be its child.
*/
}
}
}
}
Of course you’d need your weapon to have the tag “Weapon”.
Feel free to ask anything else if you need so.
But play with this, use the print() function to see what happen and when.
Hey I used your code and then went about research and trying to figure out how to make it a child of my playerHand but Im having trouble. This is what I have so far and Im getting two errors:
Assets/Scripts/PickUp.cs(31,58): error CS1061: Type bool' does not contain a definition for gameObject’ and no extension method gameObject' of type bool’ could be found. Are you missing an assembly reference?
Assets/Scripts/PickUp.cs(32,58): error CS0119: Expression denotes a type', where a variable’, value' or method group’ was expected
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PickUp : MonoBehaviour {
public GameObject playerCamera;
public GameObject playerHand;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update()
{
RaycastHit hitInfo;
Ray r = new Ray(playerCamera.transform.position, playerCamera.transform.forward);
//if we hit something
if(Physics.Raycast(r,out hitInfo))
{
//if it is tagged as a weapon
if (hitInfo.transform.CompareTag("Weapon"))
{
//if the user presses F
if (Input.GetKeyDown(KeyCode.F))
{
var weapon = gameObject.CompareTag("Weapon");
playerHand.transform.parent = weapon.gameObject.transform;
playerHand.transform.localPosition = Vector3(0, 0, 0);
playerHand.transform.localRotation = Quaternion.identity;
}
}
}
}
}
At line 32, you try to set the localPosition to Vector3(0,0,0)
What you have to do is allocate an new Vector3 with the coordinates (0,0,0)
You could do
playerHand.transform.localPosition = new Vector3(0, 0, 0);
//or...
playerHand.transform.localPosition = Vector3.zero;
This two have the same effect but in the first one you “create” a new Vector3 instance that you “feed into” the localPosition.
In the second solution you use a static reference of the Vector3 class which is just a Vector3 with coordinates (0,0,0)
You should look for programming courses on C# (Or any other OOP language) on the Internet, there are plenty of them and it would really help you to know what and how to do what you want.
Also you can, if you haven’t already, check the unity tutorials. They give a good grasp of the basic engine feature. https://unity3d.com/fr/learn/tutorials
Ok thanks that got rid of the first error. But I am still getting this error:
Assets/Scripts/PickUp.cs(31,58): error CS1061: Type bool' does not contain a definition for gameObject’ and no extension method gameObject' of type bool’ could be found. Are you missing an assembly reference?
I cant seem to fix it and there is no solutions online. Also I will be sure to check out that link and a good C# course, do you recommend any free or cheap ones?
You used the var keyword to store the result of the method compareTag(“Weapon”);
CompareTag() returns a boolean so your variable weapon contains a boolean.
By writing weapon.gameObject, you’re trying to access a member called gameobject on a boolean. Which does not exist.
Replace your line
var weapon = gameObject.CompareTag("Weapon");
by…
var weapon = hitInfo.transform.gameObject;
The var keyword seems really useful because it allows you to let the interpeter “figure it out” for you but your mistake is a great exemple of why you shouldn’t use it, espacially if you’re a beginner. It creates ambiguiety that leads to this kind of situation.
So you’d rather do :
GameObject weapon = hitInfo.transform.gameObject;
Here, it is clear that you’re dealing with a gameobject, instead of having to look at your code for 40 minutes trying to remember what variable is of what type.
Edit : No, I’m sorry, I don’t know good english C# courses as I am not english, I know some if you’re french, but I doubt it
But I’m pretty sure you could ask on this site. But don’t quote me on that, check the different forum to see which one is the more appropriate to ask
Ok thanks man that cleared the errors up. I am so sorry for bugging you but now when I play the game and look at the weapon on the ground then click F, nothing happens. I tagged the gun as Weapon and it is a rigidbody but I cant seem to pick it up, do you no why this is happening?
Then it’s a great time to try debugging.
Use the print function to see what got executed or what does not.
Have you added a collider on your weapon ? The collider needs to be on the same gameobject tagged as “Weapon” for this to work.
You have to know were the issue come from.
It could work but could simply not being called.
Or maybe it get called but simply don’t work.
For instance this :
// Update is called once per frame
void Update()
{
RaycastHit hitInfo;
Ray r = new Ray(playerCamera.transform.position, playerCamera.transform.forward);
//if we hit something
if(Physics.Raycast(r,out hitInfo))
{
print("We hit something");
//if it is tagged as a weapon
if (hitInfo.transform.CompareTag("Weapon"))
{
print("We hit a weapon");
//if the user presses F
if (Input.GetKeyDown(KeyCode.F))
{
print("We hit a weapon and user pressed F, we should pick up the weapon");
GameObject weapon = hitInfo.transform.gameObject;
playerHand.transform.parent = weapon.gameObject.transform;
playerHand.transform.localPosition = Vector3(0, 0, 0);
playerHand.transform.localRotation = Quaternion.identity;
}
}
}
}
This is quiet wordy but you can clearly see ingame what’s happening and figure out what part fail.
A great part of debugging is narrowing down the issue.
Oh, I just figured it out… I should read more carefully.
You’re doing it the other way around.
You’re setting the player hands to be child of the weapon. It should be the opposite.
//this...
playerHand.transform.parent = weapon.gameObject.transform;
//should be this...
weapon.gameObject.transform.parent = playerHands.transform;
Ok awesome it worked, when I click F he picks the weapon up. But now two more problems, ugh. When he picks it up the weapon stays where it is, it only starts moving with my character, it doesnt actually go into the physical hand. Also how would I go about making the character drop it?
That’s strange. Do you set the local position to be (0,0,0) ?
Is the playerHand transform in the right place ?
To make the player drop the weapon, you’d have to unparrent it from the player hands transform, and maybe add a rigidbody to make it fall on the ground.
Well, its the same as before in fact…
You did the same mistake as previously.
You’re doing it the other way around.
Here’s the what you should do
if (Input.GetKeyDown(KeyCode.F))
{
print("We hit a weapon and user pressed F, we should pick up the weapon");
GameObject weapon = hitInfo.transform.gameObject;
weapon.gameObject.transform.parent = playerHand.transform;
weapon.gameObject.transform.localPosition = new Vector3(0,0,0);
weapon.gameObject.transform.localRotation = Quaternion.identity;
}
Holy molly dude it worked. Im sorry for asking all these questions but Im new to this and its the only way to learn haha. Anyway changing what you said worked but now once the gun is in my hand my player goes crazy and flies around the screen everywhere. What is going on, agh.
Because your weapon has a collider and your player also has one .You’re sticking them inside of each other. It pisses off Unity and it tries to kill your player.
You have to disable the collider when the weapon is picked up and reanable it when you drop it.
if (Input.GetKeyDown(KeyCode.F))
{
print("We hit a weapon and user pressed F, we should pick up the weapon");
GameObject weapon = hitInfo.transform.gameObject;
weapon.gameObject.transform.parent = playerHand.transform;
weapon.gameObject.transform.localPosition = new Vector3(0,0,0);
weapon.gameObject.transform.localRotation = Quaternion.identity;
weapon.GetComponent<Rigidbody>().isKinematic = false; //"disabling" the rigidbody (it's still active but gravity won't apply to it.
weapon.GetComponent<Collider>().enable = false; //disabling the collider.
}
Again, you really should check the learn section of unity.
everything we’re talking about here is well explained. Well better than I could actually.
Also I was reading up on this pick up thingy and people were saying something about the gun on the ground being “fake” and that it is a trigger for when the player picks it up and then the “actual” gun is added into the players hand. Do you know what I am talking about?