2

I'm trying to learn Unity. My goal is to build a little asteroids clone.

Currently, my character is able to fly, shoot and rotate towards the mouse location. However, the bullets are somehow effected by the player turning.

Here is some sample code:

player.cs

    private void Shoot()
    {
        Instantiate(Bullet, transform);
    }

    private void FaceMouseDirection()
    {
        Vector2 direction = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
        float angle = Mathf.Atan2(direction.x, direction.y) * Mathf.Rad2Deg;
        Quaternion rotation = Quaternion.AngleAxis(angle, Vector3.back);
        transform.rotation = Quaternion.Slerp(transform.rotation, rotation, turningSpeed * Time.deltaTime);
    }

bullet.cs

    private GameObject parent;
    private Vector3 Force;

    // Use this for initialization
    void Start () 
    {
        parent = GameObject.Find("Player");
        Force = parent.transform.up * bulletSpeed;
    }

    void FixedUpdate()
    {
        transform.Translate(Force * Time.fixedDeltaTime);
    }
}
NullOrNotNull
  • 365
  • 1
  • 4
  • 11
  • When a gameobject is the child of another object it uses the parents transform. Its own transform becomes relative to the parent. Just dont set the parent and you're good to go – DetectivePikachu Nov 20 '19 at 20:36

3 Answers3

3

The bullet is being set as a child of the player. Children objects keep the same rotation as their parent.

In your bullet's Start() you will want to remove the parent from the bullet after setting the force.

Off the top of my head you should be able to do that with

transform.parent = null;
Spencer Stream
  • 616
  • 2
  • 6
  • 22
  • Thanks alot, its working that way. The bullets are flying strange tho because they don't fly alone the green axis.. but i guess thats off topic. – NullOrNotNull Nov 20 '19 at 20:46
1

First, don't have the bullets be children of the player. (Don't use Instantiate(Bullet, transform);)

Second, set the rotation and position of the bullet to be the same as the player when the bullet is instantiated. ( Do use Instantiate(Bullet, transform.position, transform.rotation); )

Third, don't base the bullet's movement on the transform of the player. Just use its own transform. ( Do use Force = transform.up * bulletSpeed; instead of Force = parent.transform.up * bulletSpeed )

player.cs

    private void Shoot()
    {
        GameObject bullet = Instantiate(Bullet, transform.position, transform.rotation);
    }

    private void FaceMouseDirection()
    {
        Vector2 direction = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
        float angle = Mathf.Atan2(direction.x, direction.y) * Mathf.Rad2Deg;
        Quaternion rotation = Quaternion.AngleAxis(angle, Vector3.back);
        transform.rotation = Quaternion.Slerp(transform.rotation, rotation, turningSpeed * Time.deltaTime);
    }

bullet.cs

    private Vector3 Force;

    // Use this for initialization
    void Start () 
    {

        Force = -transform.right * bulletSpeed;
    }

    void FixedUpdate()
    {
        transform.Translate(Force * Time.fixedDeltaTime);
    }
}

Fourth, you should consider using a technique called object pooling for your bullets, as instantiating and destroying many near-duplicates of gameobjects is not usually very efficient.

Note: If you're using Rigidbody or Rigidbody2D on the bullets, you should rather use rb.MovePosition(transform.position + Force * Time.deltaTime); (Time.deltaTime is the same as Time.fixedDeltaTime in FixedUpdate) because it will interpolate properly for frames that render between calls to FixedUpdate.

Ruzihm
  • 19,749
  • 5
  • 36
  • 48
  • Thanks a lot for sharing! Do you have an idea, why my bullet flight is offset? When the player looks towards north, bullts fly there. But when the player looks east, the bullets fly to the south... – NullOrNotNull Nov 20 '19 at 20:52
  • @NullOrNotNull Because the bullets were rotated in a way that their local up wasn't the correct direction for them to travel. From your comment, it sounds like they really ought to travel in their local left direction, but without a screenshot showing their local axes and the direction they are meant to travel, it is hard to be sure. Anyway, I edited the `bullet.cs` part of my answer. Let me know if that changed anything for you. – Ruzihm Nov 20 '19 at 21:14
  • 1
    Actually for bullets I would simply set it's `rb.velocity = -transform.right * bulletSpeed;` once and not use `Update` or `FixedUpdate` at all :) – derHugo Nov 21 '19 at 06:29
  • @derHugo yeah that's probably better :) – Ruzihm Nov 21 '19 at 06:30
0

That's probably because you're instantiating bullets as child of the object's transform. Then, when the object rotates, the bullets rotate as well.

You want to instantiate them in the world/root, or maybe in a static object at (0,0,0) if you want to group them in the hierarchy.

Object.Instantiate(bullet).transform.position = base.transform.position

geekley
  • 1,231
  • 10
  • 27