2D How do i choose one out of two or three colliding gameobjects of the same type?
Hi guys i have a simple AI for my enemies that chase the player when they see them, let me show you my situation (see picture below please).
On situation 1the enemies chase the player and approach him, on situation 2, the enemies engage the player with melee attacks, on situation 3 the player moves away and on situation 4 the enemies follow the player, the problem is that the 2 enemies will stack up, and become one since they move at the same speed, since they all share the same script and the same float variable for the speed.
So my question is, how do i get a list or array of all enemies that are overlapping one another and pick one enemy at random from that list to increase its movement speed variable? this will have the effect that overtime they will separate, but i dont know how to acomplish this, please, any help is appreciated, i searched everywhere and no answer, thanks a lot!!
Edit: this should work even if not only 2 enemies overlapp, but also 3, 4, 5...
its a 2d game, please see what i wrote below in repply to @justinijan
i require that when 2 enemies collide, only one of them gets its movement speed changed. but only one
public class Enemy
{
public bool hasCollided = false;
Collider2D col;
private void OnTriggerEnter2D(Collider2D other)
{
if (other.transform.CompareTag("Enemy"))
{
Enemy script = other.transform.GetComponent<Enemy>();
if (!script.hasCollided)
{
col = other;
script.hasCollided = true;
Debug.Log("Collision" + script.hasCollided + hasCollided);
}
}
}
private void OnTriggerExit2D(Collider2D other)
{
if (other == col)
{
hasCollided = false;
}
}
}
this script wite to the console each time it collides with another enemy, i set a variable on one of the enemies triying to make the other enemy unable to detect collision also
but event still
this is the output in the console
This is what i need, that when 2 enemies collide, the code only get triggered in one of the enemies.
I think that a more efficient solution would be to add navmesh agent components to enemies, the agents can't overlap and the built in path finding and avoidance systems will spare you of many potential problems you can have with your AI system in the future.
As for putting all enemies in an array there are many ways to do that depending on the structure of your project and enemy controller scripts. For example you can create a script in which you declare a public array and then assign the values in the inspector. Then you can do something like:
for (var i = 0; i < enemiesArray.Length; i++)
{
//Set random speed values to every enemy using Random.Range().
}
As for picking one random element of an array or list it is usually done using shuffle algorithms, but u can just select a random number using Random.Range(0, enemiesArray.Length)
and pass that number as an array index.
Its a 2d game, so, no navmesh, i know how to picka random item froma list or array, but the problem is that i need to get a list of all gameobjects collising with each other, once i have a list, i know how to choose a random item
the problem is that if i try to get a list of colliding gameobjects using Physics2D.OverlapSphere when 2 enemies collide, and then i choose one of the items from the list that Physics2D.OverlapSphere returns to change the movement speed of the chosen enemy, this will happen also in the other enemy script, and the effects will be nullified
since the collision and enemy choosing code will execute at the same time on each enemy's script, what i need is to have the code executet only on one of the enemy's script and only once
let me put a simplier example, when 2 enemies collide, i require that one of those 2 enemies get chosen at random, this is what i need, so when this enemy gets selected i will execute the Physics2D.OverlapSphere on that enemy script only
maybe another example
i require that when 2 enemies collide, only one of them gets its movement speed changed. but only one
Answer by Ali-hatem · Mar 26, 2016 at 02:21 PM
why don't you use random number for speed when enemyes collide with each other that last for secondes & then back to normal speed & don't worry if they use the same script the resault will be different for each object i have already tested it so cheek this example :
public int speed = 5;
public int RandomSpeed;
void OnTriggerEnter2D(Collider2D other){
if (other.tag == "Enimy") {
print ("stay out of my way");
StartCoroutine (changeSpeed());
}
}
IEnumerator changeSpeed(){
RandomSpeed = Random.Range(1,5);
speed = RandomSpeed;
yield return new WaitForSeconds (3);
speed = 5;
}
Thats an easy solution, but the problem is that there exist the possiblity that both enemies will get a very similar speed or the same speed, i want this to enver happen
but thanks a lot for your solution, i will keep it as plan B if im not able to find a solution that is 100% sure that not enemies will have the same speed
if by chance they get the same speed that means they will remain collided & as we tested if they collided will keep generate random speed.
i guess it could be useful to after changing the speed, check to see if the speeds are within a range, and if both speeds are too smilar, get a new random speed for both
thnkas for you help :)
Answer by kcather · Mar 26, 2016 at 07:40 PM
"i managed to make the code only trigger on one of the enemies on collision, what i had to do, is to change the hasCollided varaible to true in the local script instead of triying to change the veraible to true in the other enemy."
Hey Luna, it's Kenny. This is just a thought and I could be wrong.
I believe the reason you had to change it in the local script instead of the enemy is you've already initialized the enemy object. You're not changing a property of the enemy, you're just changing how fast the enemy moves in the room. So, it might be advantageous to make it a room property.
Or somewhere other than in the enemy class because you're running into the problem you described of changing it for all the enemies at once.
I dunno...we can try a few different approaches if you want.
yes, that was my thinking when i tried doing it the other way around, and it worked
i have yet not solid answer, but im still working in finding one @Ali hatem guggested a simple solution, but before i give up and go with that one, i want to research more
:)
Your answer
Follow this Question
Related Questions
Detecting missing collision in 2D platformer to change direction for enemy - without Raycast 1 Answer
Player passenger moving when being pushed by two platforms 0 Answers
Transform.position in 2d game or better way to move player working with colliders. 1 Answer
Snake like movement in 2D space 0 Answers
Issues with 2D collision/overlap detection,Help detecting 2D collision/overlap 0 Answers