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
1
Question by HighlordWeaponry · Dec 05, 2017 at 03:59 AM · lagcubedetectionlaggynearest

Efficient way to find nearest object with component

Hello,

So as the title suggests, I'm looking for a way to find the nearest object with a certain component that causes the least lag. Using OverlapSphere causes too much lag if there's too many game objects nearby, and this is due to the fact that I use tiny cubes with colliders as blood. (9 in total).

Is there perhaps a better way to fix this lag problem I'm having?

Code for Detection:

 public void senseEnemiesNearby(float radius){
         if (target == null) {
             Collider[] hitColliders = Physics.OverlapSphere(transform.position, radius);
             senseEnemies = true;
             savedLoc = loc;
             Cube cub = GetClosestEnemy (hitColliders, radius);
             if (cub != null) {
                 if (cub.team != team) {
                     setTarget (cub);
                 }
             }
         }
     }
 
     private Cube GetClosestEnemy(Collider[] enemies, float radius)
     {
         Cube cub = null;
         float minDist = radius;
         Vector3 currentPos = transform.position;
         foreach (Collider c in enemies)
         {
             if (c.gameObject != gameObject) {
                 if (c.gameObject.GetComponent<Cube> () != null && c.gameObject.GetComponent<Cube> ().team != team) {
                     Transform t = c.transform;
                     float dist = Vector3.Distance(t.position, currentPos);
                     if (dist < minDist)
                     {
                         cub = c.gameObject.GetComponent<Cube> ();
                         minDist = dist;
                     }
                 }
             }
         }
         return cub;
     }

Thanks HighlordWeaponry

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
2
Best Answer

Answer by Bunny83 · Dec 05, 2017 at 04:53 AM

Here are three general performance boosters to your algorithm:


  • First of all you may want to use layers. OverlapSphere has an additional layermask parameter.

  • Next you shouldn't use GetComponent more than once per object. Currently you use GetComponent up to 3 times per object. Just create a local variable inside the foreach loop and get the component once.

  • Finally when sorting objects based on the distance it's faster to compare sqrMagnitude. It of course doesn't tell your the actual distance but the greater than / lower than relation will stay the same.


So do something like this:

 public LayerMask layers;
 
 public void senseEnemiesNearby(float radius)
 {
     if (target == null)
     {
         Collider[] hitColliders = Physics.OverlapSphere(transform.position, radius, layers);
         senseEnemies = true;
         savedLoc = loc;
         Cube cub = GetClosestEnemy (hitColliders, radius);
         if (cub != null)
         {
             setTarget (cub);
         }
     }
 }
 
 private Cube GetClosestEnemy(Collider[] enemies, float radius)
 {
     Cube cub = null;
     float minDist = radius;
     Vector3 currentPos = transform.position;
     foreach (Collider c in enemies)
     {
         if (c.gameObject == gameObject)
             continue;
         Cube cube = c.GetComponent<Cube>();
         if (cube != null && cube.team != team)
         {
             Transform t = c.transform.position - currentPos;
             float dist = t.x*t.x + t.y*t.y + t.z*t.z;  // Same as "= t.sqrMagnitude;" but faster
             if (dist < minDist)
             {
                 cub = cube;
                 minDist = dist;
             }
         }
     }
     return cub;
 }


Note i removed your second team check in your "senseEnemiesNearby" method. Since your "GetClosestEnemy" method can only return an object that has to be on a different team the null check is enough.


How many objects are there in total and how many are usually in range of the OverlapSphere? I doubt that this actually caused much slowdown. Have you used the Profiler to narrow down your bottleneck?

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 HighlordWeaponry · Dec 05, 2017 at 02:00 PM 0
Share

Thanks for your reply. I will try it out as soon as possible. As for your answer for your question, it's mainly the cube particles that are the main problem. Currently when a target dies, he divides into 9 tiny cubes that launch in a direction, then vanish after 3 seconds. However, when having mass scale battles and having a constant range detection when no longer having a target (attack-move or guard), it can be quite laggy detecting all of those objects. The lag dies down when all of the blood cubes are gone though.

avatar image HighlordWeaponry · Dec 05, 2017 at 04:44 PM 0
Share

It worked! Adding layers greatly reduced the lag on the program! Thanks a lot!

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

72 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

Related Questions

How to do the following 0 Answers

Random lag spikes any time processor intensive tasks a scene 0 Answers

Unity Profiler - Loading.UpdatePreloading - Huge Lag Spikes 0 Answers

how to increase performance? 1 Answer

my android game lag sometimes 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