Search Unity

"Homing Missile" Script problem

Discussion in 'Scripting' started by nzkiller, Aug 20, 2013.

  1. nzkiller

    nzkiller

    Joined:
    Aug 9, 2013
    Posts:
    17
    Hi, the following are my scripts for a homing missile, it works, however it just flies straight ahead, without any tracking at all, any help would be appreciated (Yes the tags and rigidbodies have been applied) This tutorial was used: http://www.youtube.com/watch?v=s87zyCwHLgE

    This one is attached to the main camera to fire the missile
    Code (csharp):
    1. var projectile : GameObject;
    2. function Update () {
    3.     if (Input.GetButtonDown ("Fire1")) {
    4.     Instantiate (projectile, transform.position, transform.rotation);
    5.     }
    6. }
    This one is attached to the missile mesh
    Code (csharp):
    1. var Speed : float;
    2.  
    3. var Turn : float;
    4.  
    5.  
    6.  
    7. function Update (){
    8.  
    9.  
    10.  
    11.     var targets: GameObject[] = GameObject.FindGameObjectsWithTag("Enemy");
    12.  
    13.     var closest: GameObject;
    14.  
    15.     var ClosestDist = Mathf.Infinity;
    16.  
    17.  
    18.  
    19.     for (Target in targets){
    20.  
    21.     var dist = (transform.position - Target.transform.position).sqrMagnitude;
    22.  
    23.  
    24.  
    25.     if(dist < ClosestDist){
    26.  
    27.     ClosestDist = dist;
    28.  
    29.     closest = Target;
    30.  
    31.     }
    32.  
    33. }
    34.  
    35.  
    36.  
    37.     Quaternion.Slerp(transform.rotation,Quaternion.LookRotation(closest.transform.position-transform.position),Turn*Time.deltaTime);
    38.  
    39.  
    40.     transform.position+=transform.forward*Speed*Time.deltaTime;
    41.  
    42. }
    43.  
    44.  
    45.  
    46. function OnCollisionEnter(collision : Collision){
    47.  
    48.     Destroy (gameObject);
    49.  
    50. }
     
  2. kral

    kral

    Joined:
    Aug 7, 2011
    Posts:
    25
    i think this is the problem

    Code (csharp):
    1.  
    2.  Quaternion.Slerp(transform.rotation,Quaternion.LookRotation(closest.transform.position-transform.position),Turn*Time.deltaTime);
    3.  
    4.  
    TO:

    Code (csharp):
    1.  
    2.  transform.rotation = Quaternion.Slerp(transform.rotation,Quaternion.LookRotation(closest.transform.position-transform.position),Turn*Time.deltaTime);
    3.  
    4.  
     
  3. nzkiller

    nzkiller

    Joined:
    Aug 9, 2013
    Posts:
    17
    Changed it, still flies straight ahead :/ any other ideas?
     
  4. kral

    kral

    Joined:
    Aug 7, 2011
    Posts:
    25
    Did you asign the Turn value from inspector?
     
  5. nzkiller

    nzkiller

    Joined:
    Aug 9, 2013
    Posts:
    17
    Yes. I did changed it from 3,10,300,3000 all doesn't turn at all
     
  6. kral

    kral

    Joined:
    Aug 7, 2011
    Posts:
    25
    interesting try to disable use gravity from rigidbody
     
  7. nzkiller

    nzkiller

    Joined:
    Aug 9, 2013
    Posts:
    17
    It was never enabled :p
     
  8. nzkiller

    nzkiller

    Joined:
    Aug 9, 2013
    Posts:
    17
    It can hit my target, if it is directly in front of it but yeah it doesnt turn at all.. ._.
     
  9. kral

    kral

    Joined:
    Aug 7, 2011
    Posts:
    25
    Did your missle have a tag? if have a tag change tag to untagged
     
  10. nzkiller

    nzkiller

    Joined:
    Aug 9, 2013
    Posts:
    17
    Missile is untagged, I literally cannot see anything else wrong with it but it refuses to track :/
     
  11. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    There are numerous problems with this script.

    1. You search for a new target every frame. This is not only bad (REALLY bad), but it is most likely confusing your missile.
    2. You are manipulating position/rotation on a rigidbody. This is also bad.

    The best solution Ive found for my missiles is setting the velocity directly, and setting the rotation via MoveRotation. In your situation, I will add function for setting a target.

    This is not only better, but its the correct way to do what youre trying to do.

    I use c#, so I cant be sure this will be grammatically correct.

    Code (csharp):
    1.  
    2.  
    3. var _velocity : float = 10;
    4. var _torque: float = 5;
    5. var _target : Transform;
    6. var _rigidbody : Rigidbody;
    7.  
    8. function Start()
    9. {
    10.   _rigidbody = transform.rigidbody;
    11. }
    12.  
    13. function Fire()
    14. {
    15.    var distance = Mathf.Infinity;
    16.  
    17.    for (var go : GameObject in GameObject.FindGameObjectsWithTag("Enemy"))  {
    18.       var diff = (go.transform.position - position).sqrMagnitude;  
    19.       if(diff < distance)
    20.       {
    21.          distance = diff;
    22.          _target =  go.transform;
    23.       }
    24.  
    25.    }
    26. }
    27.  
    28. function FixedUpdate()
    29. {
    30.   if(_target == null || _rigidbody == null)
    31.      return;
    32.  
    33.    //missiles forward momentum
    34.   _rigidbody.velocity = Vector3(0,0,_velocity);
    35.  
    36.  
    37.    //missile turning momentum
    38.    var step = _torque * Time.deltaTime;
    39.  
    40.    var relativePos = _target.position - transform.position;
    41.    var targetRotation = Quaternion.LookRotation(relativePos);
    42.    var rotation = Quaternion.RotateTowards(transform.rotation, targetRotation , step);
    43.  
    44.   _rigidbody.MoveRotation(_rigidbody.rotation * rotation);
    45.  
    46.  
    47. }
    48.  
    49. function OnCollisionEnter(collision : Collision)
    50. {
    51.    Destroy(gameObject);
    52. }
    53.  
    54.  
    I think ive got my rotation/velocity stuff right. If it doesnt work, let me know and ill check my actual code (this was done from memory)
     
  12. nzkiller

    nzkiller

    Joined:
    Aug 9, 2013
    Posts:
    17
    Only error that comes up is this:

     

    Attached Files:

  13. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    line 16: should be...

    var diff = (go.transform.position - transform.position).sqrMagnitude;
     
  14. nzkiller

    nzkiller

    Joined:
    Aug 9, 2013
    Posts:
    17
    Alright, now the missile just sits there (screenshot attached)

     
  15. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    Did you call the fire function?

    Its probably easiest for now to put it in the start function
     
  16. nzkiller

    nzkiller

    Joined:
    Aug 9, 2013
    Posts:
    17
    Like this: "
    function Fire("Fire1"))"

    ?
     
  17. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    Code (csharp):
    1.  
    2.  
    3.  
    4. function Start()
    5. {
    6.   _rigidbody = transform.rigidbody;
    7.   Fire();
    8. }
    9.  
    10.  
     
  18. nzkiller

    nzkiller

    Joined:
    Aug 9, 2013
    Posts:
    17
    Unfortunately more errors than I started with... back to square one :/
     
  19. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    go do some tutorials.

    I made the mistake of thinking you know how to script
     
    Miscellaneous likes this.
  20. nzkiller

    nzkiller

    Joined:
    Aug 9, 2013
    Posts:
    17
    Um, I did to a tutorial, if you had read my first post the link is right there
     
  21. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    tutorials. plural. multiple.

    Go do some more. You should be able to fix the syntax. Also, this tutorial is obviously terrible if what you posted is the example code.
     
  22. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    anyway, this is code that doesn't contain errors... incidentally, neither did the original script, however it wasn't working correctly...

    Here is a complete js script (note: there should be NO other code in this file)

    This works correctly. If it doesnt, youve done something else wrong.

    Code (csharp):
    1.  
    2.  
    3. #pragma strict
    4.  
    5. var _velocity : float = 10;
    6. var _torque: float = 5;
    7. var _target : Transform;
    8. var _rigidbody : Rigidbody;
    9.  
    10. function Start()
    11. {
    12.   _rigidbody = transform.rigidbody;
    13.   Fire();
    14. }
    15.  
    16. function Fire()
    17. {
    18.    var distance = Mathf.Infinity;
    19.    for (var go : GameObject in GameObject.FindGameObjectsWithTag("Enemy"))  {
    20.       var diff = (go.transform.position - transform.position).sqrMagnitude;  
    21.  
    22.       if(diff < distance)
    23.       {
    24.          distance = diff;
    25.          _target =  go.transform;
    26.  
    27.       }
    28.    }
    29. }
    30.  
    31. function FixedUpdate()
    32. {
    33.  
    34.   if(_target == null || _rigidbody == null)
    35.      return;
    36.     _rigidbody.velocity = transform.forward * _velocity;
    37.  
    38.     var targetRotation = Quaternion.LookRotation(_target.position - transform.position);
    39.     _rigidbody.MoveRotation(Quaternion.RotateTowards(transform.rotation, targetRotation, _torque));
    40. }
    41.  
    42. function OnCollisionEnter(collision : Collision)
    43. {
    44.    Destroy(gameObject);
    45. }
    46.  
     
  23. theAfrican

    theAfrican

    Joined:
    Dec 15, 2012
    Posts:
    53
    Thanx JamesLeeNZ for this script. ill give it a go. also, is it too accurate or can some error in tracking be factored in? anyway, ill see if i can do it myself
     
  24. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    If you mess around with _torque you can adjust how fast it can track its target. The lower the torque, the slower it will turn towards its target.


    alternatively you could adjust the targeted center by adding some noise in (_target.position + new Vector3(val,val,val))
     
  25. theAfrican

    theAfrican

    Joined:
    Dec 15, 2012
    Posts:
    53
    thank you sir, cant believe it was that easy. i think this script is the best ive found for a homing missile
     
  26. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    Heh, it took me several iterations to come up with this solution. Tried a few different methods, but this one gave me the best missile behaviour.
     
    Miscellaneous likes this.
  27. PerfectlyInsane

    PerfectlyInsane

    Joined:
    Aug 9, 2013
    Posts:
    74
    Seems to work.. odd the missile kinds of steers away before hitting the cube.

    EDIT: my bad one my layers was affecting the missile. (the rain)

    Got this revised code working in under 1 minute. Lol spent over 1 hour on your original without getting it to work ;)



    function OnTriggerEnter (theCollider : Collider)
    {
    Debug.Log("HIT TAG: " + theCollider.tag + "HIT NAME: " + theCollider.gameObject.name );
    }



    //in update
    if(target == null)
    {
    Destroy(this.gameObject);
    return; //now the object is destroyed the script is no longer valid so we should simply return
    }
     
    Last edited: Sep 24, 2013
  28. Tavares-Antonio

    Tavares-Antonio

    Joined:
    Feb 21, 2014
    Posts:
    2
    I need convert FixedUpdade to c# can you help me JamesLeeNz?

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Missil : MonoBehaviour {
    5.  
    6.     public float velocidade = 100f;
    7.     public float torque = 25f;
    8.     public Rigidbody missilRb;
    9.     public Transform alvo;
    10.  
    11.  
    12.     void Start ()
    13.     {
    14.         missilRb = transform.GetComponent<Rigidbody> ();
    15.         Fire ();
    16.  
    17.     }
    18.     void FixedUpdade()
    19.     {
    20.         if (alvo == null || missilRb == null)
    21.        
    22.             return;
    23.  
    24.         missilRb.velocity = transform.forward * velocidade;
    25.        
    26.         var targetRotation = Quaternion.LookRotation(alvo.position - transform.position);
    27.         missilRb.MoveRotation(Quaternion.RotateTowards(transform.rotation, targetRotation, torque));
    28.         Debug.Log(missilRb.velocity);
    29.     }
    30.  
    31.     void Fire()
    32.     {
    33.         float distancia = Mathf.Infinity;
    34.         GameObject mairPerto;
    35.  
    36.         Vector3 position = transform.position;
    37.  
    38.  
    39.         foreach(GameObject go in GameObject.FindGameObjectsWithTag("Enemy"))
    40.         {
    41.             Vector3 diff = go.transform.position - position;
    42.             float distanciaAtual = diff.sqrMagnitude;
    43.  
    44.             if(distanciaAtual < distancia)
    45.             {
    46.                 distancia = distanciaAtual;
    47.                 alvo = go.transform;
    48.  
    49.             }
    50.         }
    51.  
    52.     }
    53.  
    54. }
    55.  
     
  29. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    it is c#

    although you've made a typo (FixedUpdade)
     
  30. fer490

    fer490

    Joined:
    Sep 4, 2015
    Posts:
    1
    What you wrote is in javascript not in c#
     
  31. vzheng

    vzheng

    Joined:
    Dec 4, 2012
    Posts:
    45
    Tavares-Antonio likes this.