• 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 GuitarKirby · Mar 27, 2016 at 01:30 AM · raycastperformanceperformance optimizationclosest

Finding Closest Object with considering the Performance

Hey Guys, Does anyone have an idea how i could find the closest enemy object without ruining the performance by calling it every single frame ?

There are probably thousands of ways (maybe use multiple ray casts? ) but which is the best when it comes to performance ??

Thank you for any help and good night (3:30 am in German time)

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 grimmdeveloper · Mar 27, 2016 at 02:14 AM 0
Share

You could use an enumerator and yield every x seconds ins$$anonymous$$d for checking. Are you using 2D or 3D?

avatar image Fredex8 · Mar 27, 2016 at 03:25 AM 1
Share

I'm not going to post my solution because frankly it took me time to think up and write and you won't learn anything by just being given it.

However I will say that the second example here is a good place to start. On paper using FindGameObjectsWithTag frequently sounds like a bad idea but before I wrote my solution I had dozens of objects calling that function every single frame with hundreds of enemies on screen without any noticeable drop in performance.

Point is: write something that works first and don't worry about performance too much until later.

4 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by DesignPie · Mar 27, 2016 at 02:03 PM

Good question. For my projects, I do something by the lines of this;

 using UnityEngine;
 using System.Collections;
 
 public class ExampleClass : MonoBehaviour {
     public Transform target;
     public float closeDistance = 25.0F;
     void Update() {
         if (target) {
             Vector3 offset = target.position - transform.position;
             float sqrLen = offset.sqrMagnitude;
             if (sqrLen < closeDistance)
                 //If the [target] is closer than [closeDistance] away from me,
                 //execute code here.
             
         }
     }
 }

Make sure closeDistance is the squared amount of the distance you want. Usually, the magnitude script performs the sqrt function which is quite memory expensive, so sqrMagnitude is a faster alternative. I'm sure computers can do maths without eating your memory away unlike calculating multiple raycasts on a 3D or 2D space. Hopefully, that helps ;)

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 Riderfan · Mar 28, 2016 at 02:09 PM 0
Share

This is very similar to the solution I use and there's no problem with performance. $$anonymous$$y game often needs to do 24 characters checking the distance of the 23 other characters every frame and with a similar algorithm, I run at a very s$$anonymous$$dy 60 frames a second.

Unless you're doing hundreds or thousands of checks every frame, the above method works perfectly well.

avatar image
1

Answer by TCROC · Mar 27, 2016 at 02:03 PM

Hey I had a similar situation earlier today. I was able to solve it by using Physics.OverlapSphere. This allows you to detect objects around you 360 degrees. If you don't want to call this method every frame, you can call it in a coroutine instead of update. Here is a code example.

 using UnityEngine;
 using System.Collections;
 
 public class Raycast_ToJump : MonoBehaviour {
                 
                 
                 float distanceToCheckForEnemy = 1;
                     
                 // Update is called once per frame
                 void Update () {
                     DetectEnemy(transform.position, 1);
                 
                 }
                 
                 private void DetectEnemy(Vector3 center, float radius) {
                     var hitColliders = Physics.OverlapSphere(center, radius);
                 
                     for (var i = 0; i < hitColliders.Length; i++) {
                         // collect information on the hits here
                         print(hitColliders[i].tag);
                    }
          }
  }










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

Answer by Martian-Games · Mar 27, 2016 at 05:57 AM

Here is an optimized solution that allows you to set how often to run a check "findDelay". I'm using the optimized Vector3.SqrMagnitude instead of Vector3.Distance because we only need to know which enemy is closest, not the exact meter distance (which would need Square-Root). The list of enemies is stored at start so you may need to update the list if an enemy is added or removed. Attach on any GameObject in scene, and from any script: EnemyFinder.closestEnemy to access current closest enemy. Hope it helps! :)

 using UnityEngine;
 using System.Collections;
 
 public class EnemyFinder : MonoBehaviour {
 
     public float findDelay=0.25f;//updates 4 times per second
     public static GameObject closestEnemy;
 
     GameObject[] enemies;
 
     void Start () {
         enemies=GameObject.FindGameObjectsWithTag("Enemy");
 
         InvokeRepeating("findClosestEnemy",0f,findDelay);
     }
     
     public void findClosestEnemy(){
         float smallestDist=float.MaxValue;
         Vector3 playerPos=Camera.main.transform.position; // assuming player is in same position as main camera
         GameObject newClosestEnemy=closestEnemy;
 
         foreach(GameObject enemyObj in enemies){
             float dist=Vector3.SqrMagnitude(enemyObj.transform.position-playerPos);
             if(dist<smallestDist){
                 newClosestEnemy=enemyObj;
                 smallestDist=dist;
             }
         }
 
         if(newClosestEnemy!=closestEnemy){
             closestEnemy=newClosestEnemy;
             print("NEW Closest Enemy = "+closestEnemy);
         }
     }
 }
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 grimmdeveloper · Mar 27, 2016 at 06:22 AM 0
Share

Invoke repeating is okay, but it wont give you much control over delay except for when it very first executes the repeating function and from what I've been told string functions execute slower.

avatar image Martian-Games grimmdeveloper · Mar 27, 2016 at 09:15 AM 0
Share

I've found InvokeRepeating has a slight performance benefit over IEnumerator when it does not need to be called more than once. But indeed IEnumerator would be favorable if control is needed over the update frequency.

avatar image
0

Answer by GuitarKirby · Mar 28, 2016 at 01:49 PM

Thanks for the tips !

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

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

71 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

Related Questions

Why is CapsuleCast/Raycast performance effected by rigidbody? 1 Answer

More than 20 instances of a certain script cause fps to skyrocket, is there something I'm doing wrong here? 0 Answers

Help reading Profiler 1 Answer

Calling gameobject.transform vs. just calling transform directly - Performance negligible? 1 Answer

Figuring out which specific objects are slow to render? 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