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 Wolf0368 · Aug 16, 2021 at 08:24 AM · listrandomsorting

Sorting a list with multiple variables

Hey guys, I have a list that holds a class with a game object and an int. I am having trouble coming up with a way to sort the list so that it returns the game object with highest aggro, and so that if their are multiple game objects with the same aggro level, it will just pick one at random.

 public class AggroNode
 {
     public GameObject aggroPlayerObject;
     public int aggro = 0;

 }

 public class AggroHolder : MonoBehaviour
 {
     List<AggroNode> aggroTable = new List<AggroNode>();
     List<int> topAggro = new List<int>();

     public void AddToAggro(GameObject instigator, int damage)
     {
         foreach (AggroNode entry in aggroTable)
         {
             if (entry.aggroPlayerObject = instigator)
             {
                 entry.aggro += damage;
             }
             if (entry.aggroPlayerObject != instigator)
             {
                 AggroNode newEntry = new AggroNode();
                 newEntry.aggroPlayerObject = instigator;
                 newEntry.aggro += damage;
                 aggroTable.Add(newEntry);
             }
         }
         //SetAggroTarget();
     }


     public bool SetAggroTarget()
     {
         foreach (AggroNode entry in aggroTable)
         {
         }

     }
  }

 
Comment
Add comment · Show 1
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 Bunny83 · Aug 19, 2021 at 08:51 AM 0
Share

Be careful! In your line #17 you have

 if (entry.aggroPlayerObject = instigator)

This will assign the instigator every entry.aggroPlayerObject. So when this loop is done, all elements in your array would reference the same object, the one stored in instigator. So you most likely want to do a comparison here: == instead of =.


However your code has more issues than that. You can not add items to a list that you're currently iterating over with foreach. You could use a for loop instead, however I don't think your code does what you want. Say it contains 10 different objects and one may be the "instigator". Your second condition would be true for 9 of those 10 objects and for each of those you create a new node that you append at the end of the list. So the list would have countless duplicates and each time you call it it would grow by the amount of nodes that are not the instigator.


I guess your actual goal was to just add a node for the instigator in case it is not yet in the list. For such a task using a Dictionary makes much more sense as it would be way faster and doesn't require extra housekeeping that you're currently missing.

1 Reply

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

Answer by Ossi101 · Aug 18, 2021 at 03:34 PM

If you're only looking to find an AggroNode with the highest aggro there's no need to sort the list. You can just iterate over the list and check two nodes at a time and pick the highest one. Here's what I came up with, the comments explain the process further:

 public AggroNode HighestAggro(List<AggroNode> aggroList)
 {
     // Return null if an aggro list doesn't exist or is empty.
     if (aggroList == null || aggroList.Count == 0) return null;
 
     // Set first AggroNode as the highest so we can check it with the others.
     // If this is the only node then it will be the highest by default.
     AggroNode highestAggro = aggroList[0];
 
     // Looping over the aggro list.
     // It's important we start at index 1 (2nd element.) So that we don't trigger the equality check on the same node.
     for (int i = 1; i < aggroList.Count; i++)
     {
         // Compare the current highest AggroNode with the next element in the list.
         if (highestAggro.aggro < aggroList[i].aggro)
         {
             // If the current node is less than the next element, replace it.
             highestAggro = aggroList[i];
         }
         else if (highestAggro.aggro == aggroList[i].aggro)
         {
             // If the current node is equal to the next element, pick them at random;
             // 50% chance to choose the next element, otherwise it will stay as the last element.
             if (Random.value < 0.5f)
             {
                 highestAggro = aggroList[i];
             }
         }
     }
     return highestAggro;
 }

Here's the result of this code: alt text I hope this helps!


highestaggronode.png (34.1 kB)
Comment
Add comment · Show 2 · 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 Wolf0368 · Aug 19, 2021 at 12:08 AM 0
Share

Amazing! This works exactly as I asked it to... and thats the problem. This program is going to be called a few times a second and while doing that the AI is constantly switching between targets with the same aggro level. Is their a way so we can make it pick one at random first then it will only switch once an aggro level surpasses it or the original target is dead(I already have a getcomponent for this). Other than that this is perfect thank you!

avatar image Ossi101 Wolf0368 · Aug 19, 2021 at 12:44 AM 1
Share

Off the top of my head I think you would need a more complicated system than this that keeps track of what targets are selected, die and how to quickly get the highest value without passing over a list of nodes. The method I posted shouldn't cause much issue if you're calling it a few times a second, although realistically it would be called only when you need a new target. So after a cooldown period or when the other target has died. I'm not sure how you've got all that set up so it's hard to say, but I'm glad this helped you out!

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

135 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

Related Questions

A node in a childnode? 1 Answer

Sort list game objects based on name 3 Answers

Is List.Sort() reliable when some values are equal? 1 Answer

How to Detect Touch on a Random String from a List? 1 Answer

how to create random list of two diffrent prefab 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