Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Shindy117 · Apr 18, 2017 at 06:00 PM · arrayclassarray of gameobjectsmissilehoming

Missiles move to already destroy objects [Problem][Update]

Hey guys I am having a issue with my homing missile.

We have to recreate a missile command game for class. Don't worry instructor says we can get help from the forums.

So here is my issue:

I have a working homing missile script that chooses the nearest target and moves to destroy it.

However the missile will still move towards a already destroyed object(Pictured below).

alt text

I know why it happens: I am using a Array for target selection so it is using the transform coordinates and moves towards that spot.

I do have my cities tagged as: "City" and I tried using "If" statements and "null" references to no avail. So how can I get my missiles to stop targeting already destroyed cities? I know it has to do with the Array but it is the only thing I could get working. Can you remove gameobjects from Arrays or make them smaller?

UPDATE: Made of changes based on your feedback and here it is however the Array is still choosing a already destroyed game object. I even untagged the game object and it still errors out. here is my code:

 public GameObject[] targets;
      public float speed;
 
      private Rigidbody rb;
      private GameObject chosenTarget;
 
      void Awake()
      {
          rb = GetComponent<Rigidbody>();
          targets = GameObject.FindGameObjectsWithTag("City");
          ChooseTarget();
      }
 
      void FixedUpdate()
      {
         if (chosenTarget != null)
         {
             transform.LookAt(chosenTarget.transform.position);
 
             float step = speed * Time.deltaTime;
 
             transform.position = Vector3.MoveTowards(transform.position, chosenTarget.transform.position, step);
         }
         else
         {
             ChooseTarget();
             transform.Translate(Vector3.forward * speed * Time.deltaTime);
         }
      }
 
     void ChooseTarget()
      {
         float shortestDistance = Mathf.Infinity;
         foreach(GameObject enemy in targets)
         {
             float distanceToEnemy = Vector3.Distance(transform.position, enemy.transform.position);
 
             if(distanceToEnemy < shortestDistance)
             {
                 shortestDistance = distanceToEnemy;
                 chosenTarget = enemy;
             }
         }
      }

 

capture.png (225.1 kB)
Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image farmland · Apr 19, 2017 at 03:23 AM 0
Share

How/where are you destroying objects?

avatar image Shindy117 farmland · Apr 19, 2017 at 03:26 PM 0
Share

The objects get destroyed in a script attached to the city game objects. They are my targets. Even when they are removed from the scene the missiles keep moving towards the destroyed cities' location.

4 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Thorny2000 · Apr 19, 2017 at 03:55 AM

First off, I'm assuming your "targets" array is having the destroyed targets removed in some other script, and that you either set them to inactive with "gameObject.SetActive(false)" or you make the entry in the array null.

What is happening at the moment is you chose the target in Start() with the call to ChooseTarget(). The missile doesn't choose a new target from that point and hence continues to the chosen point even if the target has gone.

You need to call ChooseTarget() occasionally to tell the missile to re-target on a new target. If the original target is still alive, the missile will simply choose that one again, as an added bonus if some other target is now closer the missile will move to that target instead.

You could check this every frame, it shouldn't cause many problems unless you had say 1000 missiles flying. You could also do it on a timer variable (as I've done below), or in a coroutine (a bit overkill for this but a good thing to know about - see https://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html ).

 public class HomingMissile : MonoBehaviour 
 {
     public GameObject[] targets;
     public float speed;
  
     private Rigidbody rb;
     private GameObject chosenTarget;
 
     private float checkTargetsTime;
  
     void Start()
     {
         rb = GetComponent<Rigidbody>();
         ChooseTarget();
     }
 
     void Update()           // Use Update, not FixedUpdate
     {
         transform.LookAt(chosenTarget.transform.position);
  
         float step = speed * Time.deltaTime;
         transform.position = Vector3.MoveTowards(transform.position, chosenTarget.transform.position, step);
 
         // Every half second, re-choose the nearest target.
         checkTargetsTime += Time.deltaTime;
         if( checkTargetsTime >= 0.5f )
         {
             checkTargetsTime = 0;
             ChooseTarget();
         }
     }
 
 
     void ChooseTarget()
     {
         float shortestDistance = Mathf.Infinity;
         foreach(GameObject enemy in targets)
         {        
             if( enemy!=null && enemy.activeSelf )       // Only look at targets that are not null and set active
             {
                 float distanceToEnemy = Vector3.Distance(transform.position, enemy.transform.position);
  
                 if(distanceToEnemy < shortestDistance)
                 {
                     shortestDistance = distanceToEnemy;
                     chosenTarget = enemy;
                 }
             }
         }
     }
 }


Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Shindy117 · Apr 19, 2017 at 03:20 PM 0
Share

Actually yes the cities have a script attached to them that destroys itself when the missile comes in contact. However even when the missile is removed from the scene. The missile will still move towards the destroyed cities location.

avatar image BaldBeardedMonk Shindy117 · Apr 19, 2017 at 03:39 PM 0
Share

public GameObject[] targets; Are you actually assigning the targets in the inspector? I am not sure but maybe the reference still remains in the array of GameObjects, even after the individual target gameobject is destroyed or it is changed to 'missing'.

avatar image Shindy117 BaldBeardedMonk · Apr 19, 2017 at 03:52 PM 0
Share

I mentioned that in the post. Yes the array is assigned in the inspector. However I made a new change based off some of the feedback on this post. I changed start to awake and in the awake function I called:

 targets = GameObject.FindGameObjectsWithTag("City")

that seems to be working however the array will sometimes choose a already destroyed gameobject then error out saying its not there. I am on the right track.

avatar image Shindy117 · Apr 19, 2017 at 04:28 PM 0
Share

How do you make entries in a array null? Cause that is my issue. It keeps selecting the same already destroyed game object and moves to that spot

avatar image Thorny2000 Shindy117 · Apr 19, 2017 at 07:09 PM 0
Share

If you look at my code in the Choosetarget() function, the line "if( enemy!=null && enemy.activeSelf )" only looks at that array entry if it is not null or if the gameObject is active. So in your other script when the gameObject is destroyed either of these lines will work: myTargetsArray[x] = null; ...or... myTargetsArray[x].SetActive(false);

Now, your second problem, the missile keeps going to the destroyed target will still happen unless you tell the missile to re-target. In my code, I am doing this with the lines after the comment " // Every half second, re-choose the nearest target.".

avatar image
2

Answer by KEric · Apr 18, 2017 at 06:59 PM

Don't use Time.deltaTime in FixedUpdate as it is used for Physics related computation.

At the start make a copy of an array to preferably Generic.List and do all what you want with it during the game play - add or remove objects. You can also use a Set for that matter.

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Joe-Censored · Apr 19, 2017 at 01:06 AM 0
Share

I agree, try using a list ins$$anonymous$$d of an array and remove objects from the list you are destroying.

avatar image Nikaas · Apr 19, 2017 at 01:46 AM 1
Share

There is no problem with using Time.deltaTime in FixedUpdate because Unity changes it to Time.fixedDeltaTime when used inside FixedUpdate.

According to Unity docs: When called (Time.deltaTime) from inside $$anonymous$$onoBehaviour's FixedUpdate, returns the fixed framerate delta time .

avatar image KEric · Apr 19, 2017 at 09:07 AM -1
Share

Time.deltaTime/fixedDeltatime -> http://answers.unity3d.com/questions/233918/fixed-update-and-timedeltatime.html

avatar image Commoble KEric · Apr 19, 2017 at 05:30 PM 0
Share

As the unity docs affirm, calling Time.deltaTime returns Time.fixedDeltaTime when called during the physics loop. This is easily provable by putting a Debug.Log in the update and fixed update of a script,

avatar image Shindy117 · Apr 19, 2017 at 03:42 PM 0
Share

Ill give lists a try. Cause thanks to a few of you the code works if the Array chooses a gameobject that is not destroyed. $$anonymous$$issile changes direction and moves towards a new city. However if the object is destroyed and the Array chooses it again it errors out.

Thanks for your help :)

avatar image Shindy117 · Apr 19, 2017 at 05:38 PM 0
Share

Okay I created the list but how do I remove it. All I did was

public List targets

but I am confused on how this works.

avatar image
1

Answer by Cuttlas-U · Apr 18, 2017 at 06:24 PM

hi; u just need an if statement to check if the target is null or not ;

         void FixedUpdate()
           {
     
     if ( chosenTarget != ull )
     {
               transform.LookAt(chosenTarget.transform.position);
      
               float step = speed * Time.deltaTime;
      
               transform.position = Vector3.MoveTowards(transform.position, chosenTarget.transform.position, step);
     }
     
     else
     
     {
 
 //your other code here
     //   transform.Translate(Vector3.forward * speed *  Time.deltaTime) ;
 
     }
           }


u see there is an else function there u need to writhe something u can destroy the missile or make it to just move forward like this;

 transform.Translate(Vector3.forward * speed *  Time.deltaTime) ;
Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Shindy117 · Apr 19, 2017 at 03:40 PM 0
Share

Hello your code half worked. If the game doesn't try accessing the same game object that has already been destroyed and it chooses any of the remain objects if will move toward that one. However if it chooses the any already destroy objects it errors out. On the right track thanks :)

avatar image BaldBeardedMonk Shindy117 · Apr 19, 2017 at 03:49 PM 0
Share

I think a better way would be to not choose already destroyed target. That is what ChooseTarget() should actually do. It should just select available targets and not the one that is destroyed. Think along this line.

avatar image Shindy117 BaldBeardedMonk · Apr 19, 2017 at 03:54 PM 0
Share

Yes I know that but my null references aren't working ill update post with my code.

avatar image
1

Answer by BaldBeardedMonk · Apr 19, 2017 at 03:05 PM

Hello,

Using tags should actually solve your problem. you need to modify the code in Choosetarget() to only select gameobjects which are not destroyed. Lets consider the targets are tagged as "EnemyTargets". Use this when you choose the target

 GameObjects[] Enemies = GameObject.FindGameObjectsWithTag("EnemyTargets");
 foreach(GameObject enemy in Enemies)

Also make sure that once a target is destroyed the tag is set to null gameObject.tag = "Untagged"; Add this in the function wherever you are destroying the target.

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Shindy117 · Apr 19, 2017 at 04:01 PM 0
Share

This worked for me however the code will sometimes choose the same Arrayed gameobject and error out. Even if I use a != null reference.

avatar image BaldBeardedMonk Shindy117 · Apr 19, 2017 at 05:21 PM 0
Share

The code is attached to a missile? and is it suppose to hit only one city? if only one target has to be chosen per missile (i.e the nearest one & both the missile and the city is destroyed after the collision) you should probably use co-routine ins$$anonymous$$d of FixedUpdate. Create a coroutine and call it from ChooseTarget() at the end. And do not use any if else inside the coroutine. The check is not needed because the coroutine is called only when the chosenTarget is selected. You just need to move it towards the city.

avatar image Shindy117 BaldBeardedMonk · Apr 19, 2017 at 05:35 PM 0
Share

Yes the this script I am working with is attached to the missile. Yes it is only suppose to hit one city.

ill see if I can create one thanks

Show more comments
Show more comments
avatar image BaldBeardedMonk · Apr 19, 2017 at 06:23 PM 0
Share

Call it outside. as it has to be called only once after the nearest enemy is selected

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

80 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Move missile to nearest target 1 Answer

How to create homing missile that follows path using Unity and iTween 1 Answer

Moving a prefab clone also moves all other clones in the scene 1 Answer

Class Object Array? 1 Answer

C# Array of Child Objects 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges