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
0
Question by oliver344 · Jul 11, 2011 at 02:45 PM · vector3distancefor-loopcheck

Check distance between many objects

Hi,

i am trying to check the distance between many enemies ( their spawn position ) as they spawn at random positions.It works, but is obviously extremely very heavy on performance and sometimes Unity even freezes, so i wanted to ask if there is any better solution ( iam sure there is ).

Here is the code:

 if(i > 0)
 {
     for( var a : int = i; a > 0; a--)
     {
       while(Vector3.Distance(enemiesPosition[i], enemiesPosition[a - 1]) < spawnDistance)
       {
        SetRandomPosition();
        print("adjusting distance");
       }
     }
 }

I am looping index of an array. EnemiesPosition is Vector3, its position of current enemy and its comparing distance of the previous enemy. If it is in given range, it sets new position. If not it loops again with another enemy which was spawn earlier. I am having like 15 enemies and its totaly crushing Unity, so i guess that the looping for all enemies is the issue, but i dont know how to else check for all other enemies spawning positions so they dont spawn on same spot.

Thanks for any reply.

Luke

Comment
Add comment · Show 5
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 Peter G · Jul 11, 2011 at 03:07 PM 0
Share

I'm not real sure what i is, but I think I have the general idea of what you're trying to do. One thing that jumps out at me is that the while loop could become an infinity loop fairly easily, and from your code we can't tell if SetRandomPosition() is guaranteed to get a valid position.

avatar image Simon V · Jul 11, 2011 at 03:10 PM 0
Share

He does say his script works, but it's not easy on the CPU. ;)

And the while loop could indeed become infinite...

avatar image almo · Jul 11, 2011 at 03:40 PM 1
Share

I maintain that the potential for infinite looping means he should use a list-of-spawns solution as in my answer. $$anonymous$$aking it less hard on the CPU doesn't change the fact that this is a flawed method.

avatar image Peter G · Jul 11, 2011 at 03:57 PM 1
Share

@Simon V, he also says that Unity sometimes freezes, which could likely be an infinite loop.

Show more comments

3 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by almo · Jul 11, 2011 at 03:05 PM

Well, it can get stuck if this happens:

1) Place 14 enemies.

2) Place 15th.

3) It touches #13, try moving it.

4) It touches #10, try moving it.

5) It touches #5, try moving it.

So you need to do something else.

Like make spawn points, keep them in a list, and then remove them from the list as they are used.

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
0

Answer by Simon V · Jul 11, 2011 at 03:08 PM

There are two ways to optimize this.

First is to call update only once every x seconds

The other is to use yield.

I know these are both possible, but I haven't used them , so I don't know how they work exactly.

If you can't figure it out this way, I'll try to search how they work.

Also use Almo's answer ;)

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
0

Answer by aldonaletto · Jul 11, 2011 at 03:30 PM

You can span your loop over several frames using yield, which would reduce the load. You could do the following:

 private var busy = false; // declare this flag outside any function
 ...
 
 if(i > 0  && !busy){ // only checkEnemies when last job ended
   checkEnemies(i);
   i--; // only goes to the next enemy when this one was verified
 }
 ...
 
 function checkEnemies(i: int)
 {
     busy = true; // I'm busy here
     for( var a : int = i; a > 0; a--)
     {
       while(Vector3.Distance(enemiesPosition[i], enemiesPosition[a - 1]) < spawnDistance)
       {
        SetRandomPosition();
        print("adjusting distance");
       }
       yield; // continue in next frame
     }
     busy = false; // I'm done
 }

The checkEnemies function sweeps the enemies as before, but after checking each enemy it suspends execution with yield, and only resume in the next frame. It sets the variable busy at start to signal it's working - the caller code must not call this function again until it has finished - and clears it at the end. You must also pass to the next enemy only when checkEnemies has ended - that's why I placed the i decrement after checkEnemies (I'm supposing you're sweeping the enemies with variable i from the number of enemies to 0; if not, adapt this code to your logic).

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 aldonaletto · Jul 11, 2011 at 03:59 PM 0
Share

It may be better to move the yield instruction to inside the while in order to further reduce the CPU load.

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

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Enemy AI help with height check 1 Answer

How to click from specyfic distance? 2 Answers

Getting vectors on an object every so many units 0 Answers

Problem With Vector3.Distance 1 Answer

Vector3.Distance between camera and raycasthit 2 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