Search Unity

Homing bullet not working

Discussion in 'Scripting' started by kristianpayne1, Jul 15, 2019.

  1. kristianpayne1

    kristianpayne1

    Joined:
    Jun 11, 2019
    Posts:
    5
    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! :mad:

    Here is the script for the beam:
    Code (CSharp):
    1.  
    2. public class BeamController : MonoBehaviour
    3. {
    4.     public Rigidbody2D rb;
    5.     protected float speed = 20f;
    6.     private float rotateSpeed = 200f;
    7.     public GameObject impactEffect;
    8.     public bool isTargetMode;
    9.     private Transform target;
    10.     public GameObject Player;
    11.  
    12.     // Start is called before the first frame update
    13.     void Start ()
    14.     {
    15.         rb.velocity = transform.right * speed;
    16.         Player = GameObject.FindWithTag("Player");
    17.         PlayerController controller = Player.GetComponent<PlayerController>();
    18.         if(controller.isBeamTargeted == true)
    19.         {
    20.             isTargetMode = true;
    21.         }
    22.     }
    23.  
    24.     public void targetFound(Transform newTarget)
    25.     {
    26.         if(target == null)
    27.         {
    28.             target = newTarget;  
    29.         }
    30.     }
    31.  
    32.     void FixedUpdate()
    33.     {
    34.         if(isTargetMode && target != null)
    35.         {
    36.             Vector2 direction = (Vector2)target.position - rb.position;
    37.             direction.Normalize ();
    38.             float rotateAmount = Vector3.Cross (direction, transform.right).z;
    39.             rb.angularVelocity = -rotateSpeed * rotateAmount;
    40.             rb.velocity = transform.right * speed;
    41.         }  
    42.     }
    43.  
    44.     void OnCollisionEnter2D(Collision2D collision)
    45.     {
    46.         GameObject impact = Instantiate(impactEffect, collision.contacts[0].point, Quaternion.identity);
    47.         Destroy(impact, 0.1f);
    48.         Destroy(gameObject);
    49.     }
    50. }
    51.  
     
  2. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    1,970
    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(...);
     
  3. kristianpayne1

    kristianpayne1

    Joined:
    Jun 11, 2019
    Posts:
    5
    I've added this on line 36:
    Code (CSharp):
    1.          
    2. Debug.Log("Homing to target: " + target +" at position: x:" + target.position.x + "y: " + target.position.y);
    3.  
    The above code prints correctly (and properly spams) onto console.

    I've included some screen capture of the situation if its of aid:
     
  4. kristianpayne1

    kristianpayne1

    Joined:
    Jun 11, 2019
    Posts:
    5
    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?
     
  5. kristianpayne1

    kristianpayne1

    Joined:
    Jun 11, 2019
    Posts:
    5
    Found the solution:

    I had freeze rotation z set to true *facepalm*

    TIL: Print everything
     
    xVergilx likes this.
  6. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    1,970
    You can as well implement homing like this :
    Code (CSharp):
    1. // This one is similar to Quaternion.LookRotation(...) but instead of Z looks at X axis
    2. private Quaternion XLookRotation(Vector3 right, Vector3 up = default) {
    3.         if (up == default) up = Vector3.up;
    4.  
    5.         Quaternion rightToForward = Quaternion.Euler(0f, -90f, 0f);
    6.         Quaternion forwardToTarget = Quaternion.LookRotation(right, up);
    7.  
    8.         return forwardToTarget * rightToForward;
    9.     }
    10.  
    11.     private void FixedUpdate() {
    12.         Vector3 dir = (_target.position - transform.position).normalized;
    13.         _rgb.MoveRotation(XLookRotation(dir, Vector3.up));
    14.     }
    To add interpolation:
    Code (CSharp):
    1. Quaternion deltaRot = Quaternion.RotateTowards(_rgb.rotation, XLookRotation(dir, Vector3.up), Time.fixedDeltaTime * _speed);
    2. _rgb.MoveRotation(deltaRot);
     
    kristianpayne1 likes this.