@Eupherin,
Your code does not work because you are instantiating a new object as a component, then attempting to access a component of the “new object”. You have to use AddComponent and GetComponent. The code you have:
//bulletInstance.rigidbody2D.AddForce(new Vector2(100f,0));
bulletInstance.rigidbody2D.velocity = new Vector2 (100, rigidbody2D.velocity.y);
Doesn’t work for two reasons: you created bulletInstance as a rigidbody, so trying to access a component of it will not work (only game objects can do this, and rigidbodies are components). The second is that you’re attempting to access the component as if it were a field of bulletInstance, with the period (“.”) operator. You must use instead GetComponent(), and then you may access any public methods or fields of the Rigidbody class.
So, let’s fix this up. First, we need to change that instantiate line:
GameObject bulletInstance = Instantiate (playerShot, gun.transform.position, Quaternion.Euler (new Vector3 (0, 0, 0))) as GameObject;
This creates bulletInstance as a GameObject (at gun.transform.position). GameObjects can have components added to them, like this:
bulletInstance.AddComponent<Rigidbody2D>();
You can then play with the rigidbody2d all you like, but to do that, you need to access it. Since GameObjects are slightly different than “regular programming objects”, in that you cannot just use a period to access all of its fun bits, you must use “GetComponent()”:
bulletInstance.GetComponent<Rigidbody2D>().AddForce(new Vector2(5f, 0f));
Alternatively, since GetComponent is pretty slow, if you are using the component a lot in the script (particularly if you are using it in Update(), you’ll want to simply add a field to your class that holds a reference to whatever component you’re using. At the top of your class (under the “public class blahblah”, with all of your variables, or fields), try this:
private Rigidbody2D rigidbody;
Then add this to your start method (also at the top):
void Start() {
rigidbody = GetComponent<Rigidbody2D>();
}
Now you can access your rigidbody anywhere in this class by simply using rigidbody.method_or_field.
Hope this helped.
Edit: I thought I might try to clear up the reason you had this problem. Again, it is because of the difference between GameObjects and their components (and perhaps Objects as they’re known in the programming world, which are different from GameObjects in Unity).
In Unity, everything in the scene is a GameObject. The ground, the trees, the items; everything is a game object. Each game object has components, which allow the game objects to do different things (physics, scripts, animation, etc). To access the component of a game object via script, we must use the GetComponent<type>()
method, which is available to all GameObjects (all MonoBehaviours).
If you create a new, empty GameObject in Unity, they always have one component added by default which cannot be removed (and is therefor special): the transform. Unlike all other components, transforms do not need the GetComponent method call, because all GameObjects will have one. Thus, you can reference yours by using game_object_here.transform
.
We can see all of the components of a GameObject using the Inspector pane of Unity. The components sort of belong to the object (the same way 4 wheels belong to a car), and so using something like GetComponent<type>()
only makes sense if the object we’re using it on has the component we’re looking for. So while Car.GetComponent() makes sense, Wheel.GetComponent() does not. This is because
- Wheel is not a GameObject; it is a component
- Even if Wheel were a GameObject, it certainly would not have a Motor component
I hope the difference is clear now.