Homing bullet not working

Hi!

Been working on my first game on Unity which is a simple asteroid shooting game. Currently been adding power-ups to my game and wanted to to add one which guides the beam (aka. the bullet) to the closest asteroid. How I’ve implemented it so far is that the beam will continue to shoot straight where the player has aimed until the child object, an empty object with a large collider (as trigger) in front, collides with an asteroid which then becomes the beam’s target.

Unfortunately, I can’t seem to get the thing working as the beam seems to just continue straight and doesn’t track the asteroid at all! :rage:

Here is the script for the beam:

public class BeamController : MonoBehaviour
{
    public Rigidbody2D rb;
    protected float speed = 20f;
    private float rotateSpeed = 200f;
    public GameObject impactEffect;
    public bool isTargetMode;
    private Transform target;
    public GameObject Player;

    // Start is called before the first frame update
    void Start ()
    {
        rb.velocity = transform.right * speed;
        Player = GameObject.FindWithTag("Player");
        PlayerController controller = Player.GetComponent<PlayerController>();
        if(controller.isBeamTargeted == true)
        {
            isTargetMode = true;
        }
    }

    public void targetFound(Transform newTarget)
    {
        if(target == null)
        {
            target = newTarget;  
        }
    }

    void FixedUpdate()
    {
        if(isTargetMode && target != null)
        {
            Vector2 direction = (Vector2)target.position - rb.position;
            direction.Normalize ();
            float rotateAmount = Vector3.Cross (direction, transform.right).z;
            rb.angularVelocity = -rotateSpeed * rotateAmount;
            rb.velocity = transform.right * speed;
        }   
    }

    void OnCollisionEnter2D(Collision2D collision)
    {
        GameObject impact = Instantiate(impactEffect, collision.contacts[0].point, Quaternion.identity);
        Destroy(impact, 0.1f);
        Destroy(gameObject);
    }
}

Before diving into your math, is your target is actually being set?

Make sure your target is actually != null. Try outputting your current target, e.g. via Debug.Log(…);

I’ve added this on line 36:

Debug.Log("Homing to target: " + target +" at position: x:" + target.position.x + "y: " + target.position.y);

The above code prints correctly (and properly spams) onto console.

I’ve included some screen capture of the situation if its of aid:
courteousacademicant

Okay so I’ve been adding loads of Debug.Log around my function and landed on something.

When I add Debug.Log(rb.angularVelocity) after line 39, it simply prints 0. Could this be the issue?

Found the solution:

I had freeze rotation z set to true facepalm

TIL: Print everything

1 Like

You can as well implement homing like this :

// This one is similar to Quaternion.LookRotation(...) but instead of Z looks at X axis
private Quaternion XLookRotation(Vector3 right, Vector3 up = default) {
        if (up == default) up = Vector3.up;

        Quaternion rightToForward = Quaternion.Euler(0f, -90f, 0f);
        Quaternion forwardToTarget = Quaternion.LookRotation(right, up);

        return forwardToTarget * rightToForward;
    }

    private void FixedUpdate() {
        Vector3 dir = (_target.position - transform.position).normalized;
        _rgb.MoveRotation(XLookRotation(dir, Vector3.up));
    }

To add interpolation:

Quaternion deltaRot = Quaternion.RotateTowards(_rgb.rotation, XLookRotation(dir, Vector3.up), Time.fixedDeltaTime * _speed);
_rgb.MoveRotation(deltaRot);
1 Like