0
\$\begingroup\$

I'm experiencing a rather annoying bug and I was hoping someone could offer some help because this just isn't making sense to me. I have a Ballistic script that tells the bullet to move in its local forward direction, which should be whichever way the gun is pointing. I have a PlayerAttack script that calls for a bullet to spawn with OnShootEnter(). It sets the bullets position to that of a bulletSpawn transform, which is a child of the gun.

OnShootEnter() is being properly called and bulletSpawn is properly assigned; and yet, when the bullet spawns, its facing Vector3.forward, instead of it facing bulletSpawn.forward. These are the only two scripts affecting the bullets spawn, rotation, and direction. Everything looks in order to me; what am I missing?


public class PlayerAttack : MonoBehaviour 
{
    public GameObject bulletPrefab;

    public Transform gun;
    public Transform bulletSpawn;
    public float damage;

    void OnShootEnter()
    {
        GameObject bullet
            = Instantiate(bulletPrefab, bulletSpawn.position, bulletSpawn.rotation);
     }
}

public class Ballistic : MonoBehaviour 
{
    public GameObject model;
    public float range;
    public float accuracy;
    public float speed;

    Vector3 dir = Vector3.zero;

    void Start () 
    {
        model.transform.SetParent (this.transform);
        dir = transform.forward;
    }

    void Update () 
    {
        transform.GetComponent<Rigidbody> ().velocity = dir.normalized * speed;
        range -= Time.deltaTime;

        if (range <= 0)
            Destroy (this.gameObject);
    }
}
\$\endgroup\$
  • \$\begingroup\$ So what's the sample output for debug? BulletSpawn forward != BulletForward? \$\endgroup\$ – MichaelHouse Mar 13 '17 at 21:20
-1
\$\begingroup\$

Vector3.forward is not really a forward , as per official documentation, it is the shorthand for new Vector3(0,0,1). That means that Vector3.forward will increase your z direction by 1, not by your objects real "forward" .

Transform.forward is the blue axis of the transform, in world space. In other words, the blue line is the Z axis / direction of the transform, as per official documentation. If this thing is unclear, transform.forward means only move your object along the Z axis / direction.

Z axis / direction is like a compass; no matter your rotation, the north and south direction will have no change; the compass will still be pointing north and south.

\$\endgroup\$
  • \$\begingroup\$ That's why I'm using transform.forward, not Vector3.forward. Transform.forward is shorthand for the forward position of that specific transform... \$\endgroup\$ – A20T3M4 Mar 14 '17 at 13:17
  • \$\begingroup\$ @A20T3M4 edited \$\endgroup\$ – user6668201 Mar 14 '17 at 14:39
  • \$\begingroup\$ I'm confused. But doesn't the transform's z-axis stay consistent with its rotation? I don't see how this prevents it from working... \$\endgroup\$ – A20T3M4 Mar 14 '17 at 18:05
  • \$\begingroup\$ @A20T3M4 , example you have a compass , no matter you rotate or not , the north and south direction will have no change , the compass still pointing at north and south . \$\endgroup\$ – user6668201 Mar 15 '17 at 12:12
  • \$\begingroup\$ I realise what your error was, here. Your reading off of official documentation, but not putting it into practice. The blue axis does, in fact, have the ability to rotate around in real space. You can see that this works in my above answer, where I demonstrate how transform.forward gives a variety of directions, and in most practicalities the asker's script works. Also note that I have removed edit from your answer, among other changes. We do not mark edits, here, as we already keep an edit record, and it gives an unwanted "forumesque" feel. \$\endgroup\$ – Gnemlock Apr 28 '17 at 2:37
-1
\$\begingroup\$

You should try this in OnShootEnter():

GameObject bullet = 
    Instantiate(bulletPrefab, bulletSpawn.position, bulletSpawn.rotation);

bullet.GetComponent<Rigidbody>().velocity = bullet.transform.forward * 6;
\$\endgroup\$
  • \$\begingroup\$ I gave this a shot but it didn't help... is there a reason setting the velocity here would make a difference? \$\endgroup\$ – A20T3M4 Mar 14 '17 at 13:32
  • 1
    \$\begingroup\$ Indeed, @A20T3M4, if forward is the wrong direction, 6 steps forward is also the wrong direction. \$\endgroup\$ – Gnemlock Apr 28 '17 at 2:39
1
\$\begingroup\$

I have actually tested your scripts, and as far as I can tell, it works perfectly fine. I can rotate my gun, and shoot bullets out in the appropriate "forward direction". You can see this behaviour in the below screen capture, where I have ammended a custom editor script to provide a direct button to call OnShootEnter().

When I rotate the gun and shoot a bullet, the bullet exits the gun at the correct angle, and travels at the correct forward vector.

Why doesn't it work for me?

There is one element I can not account for; Ballistic.model. There is no explanation for this member, and the only logic applied to it is model.transform.SetParent(this.transform) in the Start() method. We know that this member reference has been set up, as the entire script will not run, without it.

How could an additional child interfere with transform.forward?

I speculate that this is the source of your interference. I can only speculate, based off the name and logic, that this member represents the unique bullet model. In turn, I speculate that you have this model over the top of the game object containing Ballistic, and only need to ensure it is parented so it follows the movement and life cycle of your core Ballistic game object.

This should not be setting transform.forward to (0, 0, 0); it might angle the game object, but not specifically to Vector3.forward. It might be possible that the rotation is being thrown off, and it only appears to be a deliberate Vector3.forward direction. This could be the result of moving two game objects that are on top of each other, which is even more likely given that the core Ballistic game object has a rigid body on it. It could also be the after effects of a bug, as I have personally encountered a fair few regarding the transform of an object with the addition of a new parent or child.

How do I fix it?

If my speculation is correct, you should simply have the model directly attached to your Ballistic game object, regardless. You can then interchange the mesh in order to display different models. Alternatively, simply use the core model game object with an attached Ballistic script. There is really no reason why you would need two separate game objects for the functionality of a bullet.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.