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 /
This question was closed Feb 09, 2020 at 06:58 AM by hballamco for the following reason:

The question is answered, right answer was accepted

avatar image
0
Question by hballamco · Feb 08, 2020 at 10:29 PM · gameobjectscript.if statementreturnpublic variable

Finding nearest and with highest health points

I have succeeded in writing a code to find the nearest enemy and it worked but I would like to include another parameter. Here is the code I am using:

 GameObject[] enemies;
         enemies = GameObject.FindGameObjectsWithTag("Enemy");
         GameObject closest = null;
         float distance = Mathf.Infinity;
         Vector3 position = transform.position;
 
         foreach (GameObject enemy in enemies)
         {
             Vector3 diff = enemy.transform.position - position;
             Target target = enemy.GetComponent<Target>();
             float curDistance = diff.sqrMagnitude;
 
             if (curDistance < distance && target.health > 25f)
             {
                 print("worked");
                 closest = enemy;
                 distance = curDistance;
             }
 
             else if (curDistance < distance)
             {
                 closest = enemy;
                 distance = curDistance;
             }
         }
         return closest;

Now as you can see, the other condition is basically check the target's health. If both conditions are met which are 1) nearest enemy + 2) health > 25 then choose that one. If not, then just choose the nearest. However, what is happening is that the returned game object is just the nearest even though the print function shows up and the conditions are met. please help.

EDIT: print function does not go through. always "else if" works only.

EDIT2: I have modified my code to this:

 foreach (GameObject enemy in enemies)
         {
             Vector3 diff = enemy.transform.position - position;
             Target target = enemy.GetComponent<Target>();
             float curDistance = diff.sqrMagnitude;
 
             if (curDistance < distance && target.health >= 25f)
             {
                 print("Yep!");
                 closest = enemy;
                 distance = curDistance;                           
             }
 
         }
         return closest;

Now, I get the nearest enemy with health greater than 25 followed by the further. Yet when those are destroyed other objects with health lower than 25 are not identified anymore which is not what I want! I want those enemies with health lower than 25 be targeted after those with health more than 25 killed. I tried using "else if" and "else" but the order of identifying get messed up. please help

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

  • Sort: 
avatar image
1
Best Answer

Answer by Bunny83 · Feb 09, 2020 at 12:04 AM

Your requirement doesn't make much sense. Whenever you have more than one sort criteria you have to deside which one is the first order criteria and which one is secondary.


So if we assume you just want a single splitting value at 25HP so that if there are one or more objects with more than 25HP we would pick the closest object out of those objects. If there is no object with more than 25HP we would simply pick the closest out of all objects regardless of the HP. To do this we would need two seperate "distance" and "closest" variables to track the two different conditions independently. For example in the for loop you would do

 if (curDistance < distance)
 {
     closest = enemy;
     distance = curDistance;
 }
 if (curDistance < hiDistance && target.health > 25f)
 {
     hiClosest = enemy;
     hiDistance = curDistance;
 }

After your for loop you can simply check if lowClosest contains any object. Because when all objects are above 25 hp you will never enter the second if statement and lowClosest would stay null. So if lowClosest is null, just use "closest". If it's not null, use "lowClosest".

 if (hiClosest != null)
     return hiClosest;
 return closest;


If you actually want to somehow use a weighted condition so both values (distance and hp) are considered at the same time, you have to define some kind of weighting system for both value types. Imagine this scenario

 //You are here|        | Enemy at 8 hp
 //            |        |
 //           \|/       |
 //            *       \|/
 //                     *
 //                          *
 //                         /|\
 //                          |
 //                          | Enemy at 12 hp

As you can see the enemy at 8 hp is closer to you than the enemy at 12hp. Which one do you want to pick? Based on which logic? Since 12 hp is higher than 8 hp, do you want to prefer this one? What if the 12 hp enemy is far to the right instead? Still want to prefer the enemy that is 100 units away over the one that's just 1 unit away? If you want some sort of critical switching point you have to decide how much "weight" each condition gets.


One approach is to unify both values into a single unitless "score". So enemies which are closer gets a higher score than enemies further away. Likewise enemies with a higher health would also get a higher score than those with a low HP value. Though the crucial point is what is the balance between those. So for example if you essentially decide that one unit of distance equals one point of HP you could simply subtract the distance value from the HP value. The highest result is the preferred result


To refer back to my example: If we assume the 8 HP enemy is 5 units away and the 12 HP unit is 7 units away, the 8 HP enemy would get a value of 8-5 == 3 while the 12 HP enemy gets a value of 12-7 == 5. So we would pick the 12 HP enemy. However if the 8 HP enemy moves further away, say to a distance of 11 units its value would decrease to 12 - 11 == 1 so the 8 HP enemy would be the new preferred one. So health and distance would essentially cancel each other out. "8HP at 5units" has the same priority as "12HP at 9units".


Hopefully you get the idea. If you want a different ratio between health and distance you would simply multiply one of them with a weight factor. For example if you choose your value to be "hp - 2*dist" it means 1 unit of distance has the same weight as 2 points of HP.


Keep in mind that while for pure distance sorting it doesn't matter if you use the actual distance or the distance squared. In the weighted case it does make a difference.

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 hballamco · Feb 09, 2020 at 12:40 AM 0
Share

my bad. I just updated the topic title. I want to target the nearest with highest hp then if those are dead, I want the order from the nearest to furthest only. Ill check your logic and will give feedback. By the way, your version of the code would only focus the nearest ignoring the health condition since it is in the "if" statement and all objects would be identified which result in ignoring the "else if". Correct me please if im wrong. thanks

avatar image Bunny83 hballamco · Feb 09, 2020 at 01:41 AM 1
Share

Yes, my bad, there should not be any else statement ^^. I will edit my answer. Since you now flipped the condition around I will also adjust my examples to fit your question.


However again you said you want the nearest with highest hp. This just doesn't make sense. Based on your statement that you want "the nearest with highest hp" it would actually be the object with the highest HP, no matter at which distance it is located. So in effect you only sort by HP. When exactly do you want to take the distance into account? Imagine there are these objects:

 5HP at 2 units distance
 10HP at 5 units distance
 20HP at 7 units distance
 100HP at 100 units distance

Just tell me how would you order those objects based on your requirements? Which is the one you want to pick first? If that would be gone, what would be the second, third, ... ? Here again the closest object with the highest HP is the one at 100 unit distance. The second closest with the highest HP would be the one at 7 units distance. If you just look at that result you essentially only sorted on the HP value and ignored the distance completely. The only case where it would make sense to use the distance as a second ordering condition is when you have two or more objects with the exact same health value. So if there are 3 objects all with a health value of 100 you could pick the closest one of those 3. But if there's an object with 101 HP that would be preferred over all the 100 HP objects. Is that what you're looking for?

avatar image hballamco · Feb 09, 2020 at 12:53 AM 0
Share

O$$anonymous$$, I tried your logic. It worked in the case of targeting nearest highest hp enemies. But, after that other nearest low hp enemies are not targeted. Also, how to return either closest and lowClosest in your version of code? because I need to return something which in your code it is either closest or lowClosest. thanks

avatar image Bunny83 hballamco · Feb 09, 2020 at 02:08 AM 1
Share

I actually said in my answer what to return when. I have completely reworked all my examples. I also explicitly added the return code logic just as mentioned in the answer.

avatar image hballamco Bunny83 · Feb 09, 2020 at 06:58 AM 0
Share

You made my day. It worked! Thanks a lot

Follow this Question

Answers Answers and Comments

201 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 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 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

How to prevent a script on a disabled object from firing? 0 Answers

How to access a game object from a different scene? 0 Answers

Calculating Scrolling GameObject x position scrolling pass another GameObject x postion (2D Game) 1 Answer

How do I play gameobjects in my scene from one script / Script is not working 0 Answers

How to double spirte/gameobject/prefab and control the result on those items? 0 Answers


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