Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 11 Next capture
2021 2022 2023
1 capture
11 Jun 22 - 11 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 Jeffkeuh · Jul 16, 2015 at 12:56 PM · aienemyscriptingbasicsalgorithmchase

Problem using boids algorithm for chasing enemies.

Hello,

I'm making a 2D game where I want the enemies to chase the player (think geometry wars). I don't want them to overlap and stack though. So they need to move away from eachother and chase the player in a smooth way.

While googling I came across flocking and boids. It's exactly what I need (I think). While I kind of understand what's supposed to happen I can only make it kind of work but not really. I'm self taught and may be overlooking some basic stuff. I've been following this explanation and trying to implement it in Unity. (http://www.kfish.org/boids/pseudocode.html).

I've also heard of and looked into UnitySteer (https://github.com/ricardojmendez/UnitySteer). Some of the examples are really cool but it's a bit above my level. I find it hard to understand and even harder to implement in my own project.

So here's the code. I'm using a list of enemies, each enemy has a velocity (that's set to Vector3.zero when they spawn) that contains the amount they need to move every update. (I think I may be doing/using this wrong).

The enemies do kind of move but they keep accelerating and spinning out of control like this. (https://www.youtube.com/watch?v=OYn4zVMD-9M&feature=youtu.be ).

This made me think that the velocity keeps stacking so I tried resetting the velocity to zero every update (and upping the movespeed) which results into this. (https://www.youtube.com/watch?v=mMuyqp1NZcs&feature=youtu.be ). I don't think that's how it's supposed to be since the velocity should get updated and compared to the last one in rule 3. Rule 2 is also not very smooth.

I'm not sure what's going wrong. I've tried singling out each rule but it's hard to find problems because I'm also not entirely sure what it's supposed to look like. Any help or suggestions would be appreciated.


 private void Update()
     {
         MoveEnemies();
     }
 
     private void MoveEnemies()
     {
         Vector3 v1,v2,v3,v4;
 
         for(int i = 0; i < AliveEnemies.Count; i++)
         {
 
             EnemyScript e = AliveEnemies[i];

             //e.veloc = Vector3.zero;

             v1 = rule1(e);    //fly towards (percieved) center
             v2 = rule2(e);    //distance other boids
             v3 = rule3(e);    //match (percieved) velocity with near boids
             v4 = rule4(e);    //move towards player
 
             e.veloc = e.veloc + v1 + v2 + v3 +v4;
             e.transform.position = e.transform.position + e.veloc*Time.deltaTime;
     
         }
 
     }
 
     private Vector3 rule1(EnemyScript ej)
     {
         Vector3 percievedCenter = Vector3.zero;
         
         for(int j = 0; j < AliveEnemies.Count; j++)
         {
             EnemyScript e = AliveEnemies[j];
 
             if(e != ej)
             {
                 percievedCenter = percievedCenter + e.transform.position;
             }
         }
 
         percievedCenter = percievedCenter / (AliveEnemies.Count-1);
 
         return(percievedCenter - ej.transform.position)/100f;
     }
 
     private Vector3 rule2(EnemyScript ej)
     {
         Vector3 center = Vector3.zero;
         
         for(int j = 0; j < AliveEnemies.Count; j++)
         {
             EnemyScript e = AliveEnemies[j];
             
             float enemyDistance = Vector3.Distance (ej.transform.position, e.transform.position);
 
             if(e != ej && enemyDistance <= 1f)
             {
                 center = center - (e.transform.position - ej.transform.position);
             }
         }
 
         return center;
     }
 
     private Vector3 rule3(EnemyScript ej)
     {
         Vector3 percievedVeloc = Vector3.zero;
         
         for(int j = 0; j < AliveEnemies.Count; j++)
         {
             EnemyScript e = AliveEnemies[j];
 
             if(e != ej)
             {
                 percievedVeloc = percievedVeloc + e.veloc;
             }
         }
 
         percievedVeloc = percievedVeloc / (AliveEnemies.Count-1);
         
         return (percievedVeloc - ej.veloc)/8f;
     }
 
     private Vector3 rule4(EnemyScript ej)
     {
         if(player != null)
         {
             Vector3 target = player.transform.position;
             
             return((target - ej.transform.position)/20f);
         }
         else
         {
             return(Vector3.zero);
         }
     }
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 _dns_ · Jul 16, 2015 at 02:29 PM 0
Share

Hi, this kind of behavior can be difficult to debug as every vector depends on other object's position etc... The best method I use to debug this is to reduce the number of objects to a $$anonymous$$imum and with fixed situations ( = only 2 or 3 objects and a player with a fixed position, then, when the behavior seems correct, try to move the player).

I would also try to find configurations that are easy to reproduce to debug each of the rules. I.e put the objects far from each other and check if they move toward a center with rule1 only. Each time you launch the program, the same thing will happen so it's easier to debug.

Other things to help: Debug.DrawLine or DrawRay with different colors representing the different vectors. It can help to "see" what's wrong. This is even more convenient with changing the time scale either by script (on a button pressed) or by changing the time scale in the editor project's settings.

avatar image Jeffkeuh · Jul 16, 2015 at 02:42 PM 0
Share

With upping the movespeed I just meant that I had to multiply time.deltatime because they moved really slow. Also thanks for the tips dns!

I think I don't actually have to implement all the flocking rules since that's not really what I need. I mostly need the chase while making sure the enemies don't overlap so I've tried using this and it's been working quite well. I only use the second boid rule together with a Vector3.$$anonymous$$oveTowards the player. (https://youtu.be/ELNC$$anonymous$$J4gFA4 ).

                      v1 = rule1(e);    //fly towards (percieved) center
                 v2 = rule2(e);    //distance other boids
                 v3 = rule3(e);    //match (percieved) velocity with near boids
                 v4 = rule4(e); //move towards player
                 
                 e.veloc = e.veloc + v2;
 
                 e.transform.position = e.transform.position + e.veloc*Time.deltaTime;
 
                 e.transform.position = Vector3.$$anonymous$$oveTowards(e.transform.position,player.transform.position, 4f*Time.deltaTime) ;

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by timohausmann · Jul 16, 2015 at 02:46 PM

As far as I can tell, you implemented everything according to the pseudocode. Maybe try to limit the velocity, instead of setting it back to zero, so the movement won't be as exaggerated as in your first video example:

 e.veloc = Vector3.ClampMagnitude(e.veloc, 6); //play with this value
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.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Enemy AI Problem 0 Answers

How to connect generated points on a sphere? 0 Answers

makeing enemies 1 Answer

How do I make it so that a walking animation plays for the enemy AT THE SAME TIME it is moving toward the player? 0 Answers

Enemy's NavMesh not working 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