Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 Addyarb · Apr 11, 2015 at 06:13 AM · arraylisttargeting

Find Target From List

Hi there Unity,

I'm having trouble consistently pulling my desired target from a list. Here's what I've set up. This is for a tower defense game, and the tower has two main settings. First and Last. As you can imagine, this sets the tower to either attack the first target in the list, or the last in the list. The targets are spawning and then running through a maze to the end zone.

  1. Target spawns and gets added to list

  2. If target dies, it gets subtracted from list.

The tower starts out (usually) attacking the first in the list, but once that target dies and gets subtracted, the tower moves to the last target. The tower's priority level is on First the entire time, but it acts as if it is on Last.

Here's my code!

Also, if you guys have any suggestions on how to efficiently check if the first in the list isn't necessarily the closest to the end zone, that would be a huge help.

 void Update(){
 UpdateTarget();
 }
 
     public void UpdateTarget()
     {
         //If I don't have a target...
         if (myTarget != null) {
             //Get the distance between me and the target.
             if (Vector3.Distance (myTarget.gameObject.transform.position, this.transform.position) > maxAttackRange) {
                 //If the target is too far away, set target to null.
                 myTarget = null;
             } else {
                 //Else, if my target is not in the target list...
                 if (!eList.targetList.Contains (myTarget)) {
                     //Set target to null
                     myTarget = null;
                 }
             }
             return;
         } else {
             //Else, if I DO have a target...
             switch(selectPriorityLevel){
                 //If the priority level is set to first (Attack first enemy in the list...)
             case priority.first:
             //Iterate through the list and get the first available target in the list that is close enough to attack.
             for (int i = 0; i < eList.targetList.Count; i++) {
                     //If the distance to the referenced target is within the maximum attack range..
                 if (Vector3.Distance (eList.targetList [i].transform.position, this.transform.position) < maxAttackRange) {
                         //Set said target to MY target.
                     myTarget = eList.targetList [i];
                         //Rotate tower to follow enemy.
                     FollowEnemy ();
                         //If this is an AoE tower, exit function. Else, attack.
                     if (launchStyle == projectileLaunchStyle.aoe)return;
                     StartCoroutine (AttackEnemy ());
                     }
                 }
                 break;
             case priority.last:
                 //If priority level is set to last (Attack last enemy in list...)
             for (int i = 0; i < eList.targetList.Count; i++) {
                     //Iterate through the list and get the last available target in the list that is close enough to attack.
                 if (Vector3.Distance (eList.targetList[eList.targetList.Count-1].transform.position, this.transform.position) < maxAttackRange) {
                     myTarget = eList.targetList [eList.targetList.Count-1];
                         //Rotate tower to follow enemy.
                     FollowEnemy ();
                         //If this is an AoE tower, exit function. Else, attack.
                     if (launchStyle == projectileLaunchStyle.aoe)return;
                     StartCoroutine (AttackEnemy ());
                     }
                 }
                 break;
             }
         }
     }









Comment
Add comment
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

1 Reply

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

Answer by NoseKills · Apr 12, 2015 at 09:09 AM

In case priority.first: you don't break out of the search loop if you find a target, so you end up going through the whole list and the last thing you do will be attacking the last item on the list that is within range, not the first one you find.

In the second one you loop eList.targetList.Count times but you compare distance to the last item on the list every time Vector3.Distance (eList.targetList [eList.targetList.Count - 1]....

Since you want to do the same thing in both cases, just in reverse order, you could do like this

 public void UpdateTarget ()
     {
         if (myTarget != null)
         {
             if (Vector3.Distance (myTarget.gameObject.transform.position, this.transform.position) > maxAttackRange)
             {
                 myTarget = null;
             }
             else
             {
                 if (!eList.targetList.Contains (myTarget))
                 {
                     myTarget = null;
                 }
             }
         // no need to have a return; here because there's no code after the if.
         // we entered the "if" so we won't enter the "else".
         //    return;
         }
         else
         {
             if (selectPriorityLevel == priority.first)
             {
                 for (int i = 0; i < eList.targetList.Count; i++)
                 {
                     if (trySetAsTarget(eList.targetList[i]))
                         return;
                 }
             }
             else
             {
                 for (int i = eList.targetList.Count-1; i >= 0; i--)
                 {
                     if (trySetAsTarget(eList.targetList[i]))
                         return; // if target was found, stop searching
                 }
             }
         }
     }
 
     // return whether a target was found or not
     bool trySetAsTarget(MyTargetType target)
     {
         if (Vector3.Distance (target.transform.position, this.transform.position) < maxAttackRange)
         {
             //Set said target to MY target.
             myTarget = target;
             //Rotate tower to follow enemy.
             FollowEnemy ();
             //If this is an AoE tower, exit function. Else, attack.
             if (launchStyle == projectileLaunchStyle.aoe)
                 return true;
             StartCoroutine (AttackEnemy ());
 
             return true; // target found and set
         }
         return false; // not close enough
     }
Comment
Add comment · Show 1 · 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 Addyarb · Apr 14, 2015 at 08:00 PM 1
Share

This works beautifully. Thank you for taking the time to read/edit. This was one of the first times I've tried to use switch statements in place of if/else so I'm sure that's why I got confused. I assumed there was some benefit to them in this instance, but this way looks much more logical.

Thanks again!

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

19 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

Related Questions

A node in a childnode? 1 Answer

Selection list from Array Unity - Random - GameObjects array 1 Answer

How to see what element is the current one 2 Answers

Value will not return from ArrayList, C# 1 Answer

foreach a array inside a generic list 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