2D tank firing projectile in C# - transform.foward doesn't seem to work

Hi all. I’ve been following the tutorial below on how to create instances of a shell, and have it shoot off in the same direction of the barrel, however transform.forward doesn’t seem to work to me. Multiplying the transform.forward by any amount seems to have no effect - the shell just falls to the ground.


I’m using C#. If anyone could tell me what I’m doing wrong, that would be great… My code is below.

using UnityEngine;
using System.Collections;

public class Fire : MonoBehaviour {

	public Rigidbody2D ArtyShell;
	public Transform EndOfTurret;
	public Vector2 ShellMove;

	void Example() {
				animation.wrapMode = WrapMode.Once;

	public KeyCode Fire_KC;

	private Animator animator;

	// Use this for initialization
	void Start () {
	animator = this.GetComponentInChildren<Animator> ();
	// Update is called once per frame
	void Update () {
//		if ((Input.GetKey (Fire_KC)) Input.GetKeyDown (Fire_KC)) {
		if (Input.GetKeyDown (Fire_KC)) {

		// turns on the int that triggers the animation
			animator.SetBool("FireYN", true);

			//creates a shell at the end of the turret, and gives it a push
		Rigidbody2D ShellInstance;
			**ShellInstance = Instantiate(ArtyShell, EndOfTurret.position, EndOfTurret.rotation) as Rigidbody2D;
			ShellInstance.velocity = transform.forward * 50000;**
		//turns off the int that turns off the animation
		else {
			animator.SetBool("FireYN", false);


Rigidbody2D.velocity is a Vector2 - it’s only got velocity in two dimensions, as you’d expect. Transform.velocity, however, is a Vector3. So what you’re doing on line 40 is assigning a Vector3 to a Vector2. Normally you wouldn’t be able to do that, because they’re different structs, but Vector2 defines an implicit conversion operator from Vector3. What happens when you do the assignment is that the x and y components of the Vector3 are copied into the Vector2, and the z component gets ignored. So the following code

Vector2 foo;
Vector3 bar=Vector3.forward; //(0,0,1)

will print (0.0, 0.0) to the console.

Now, what I suspect is happening is that transform.forward is returning (0,0,1) - that’s the default orientation. So the line ShellInstance.velocity = transform.forward * 50000; assigns the vector (0,0,50000) to a Vector2, which gives you (0,0). Possibly you should be using EndOfTurrent.transform.forward rather than transform.forward, but in any event, it’s the conversion that I think is giving you trouble. You can check easily enough by adding Debug.Log(transform.forward) in there and seeing what you get.

If you’re doing some sort of sidescrolling tank game, which is what it sounds like from your description, then z is probably into the screen, and the game takes place in the x-y plane. If you’re moving one end of the turret up and down and leaving the other end fixed, you’re rotating it around the z-axis. So you might have to construct your ‘forward’ vector by rotating Vector3.right by EndOfTurrent.transform.eulerAngles.z, or something similar. There’ll be a few extra things to handle - you’ll have to change things if the tank faces the other way, for example - but that may get you on the right track.