Hi guys,
I’m training an agent who is represented by a triangle in the below image. His purpose is to dodge the black circles and to stay alive for as long as possible. The agent can shoot and it can move by rotating itself on the z axis and accelerating. The circles are spawned outside an area where the agent is and move through that area at random directions and velocities.
Yesterday I finally managed to get it working! The agent was routinely achieving very high episode lengths.
In the end, what worked were these observations to know his own position and velocity and a RayPerceptionSensor2D to know the circles’ positions.
sensor.AddObservation(localVelocity.x);
sensor.AddObservation(localVelocity.y);
sensor.AddObservation(transform.localPosition.x / (MapSetup.dimensions.x / 2));
sensor.AddObservation(transform.localPosition.y / (MapSetup.dimensions.y / 2));
sensor.AddObservation(transform.rotation.z);```
However I think I that the RayPerceptionSensor2D is not the correct tool for this job. For example, what if there is a circle (enemy), behind another circle? As in this image. I think that in this case, the agent sees only 1 circle on his left and another on his right, instead of the 3 circles that actually exist, so he would shoot the first one, and then rotate to the other side, leaving him exposed to circle nr 2. Because of this, I think the agent cannot form optimal strategy.
![](https://i.imgur.com/B6ooiYP.png)
Also, when a circle is detected with a RayCast, there is a SphereCast, if I understand correcly, that means that the agent knows a vector towards the center of the sphere. So for example in the below situation, it would be missing its shots.
![](https://i.imgur.com/wI0kn5P.png)
I have also tried a CameraSensor, it looks like the agent learns to dodge, somewhat, but shooting completely fails. I wasn't able to get a solution with that. This is my least preferred method as well, because if I understand correctly I have to retrain the model if I change sprites of the game objects.
I also tried to pool all the circles, as in object pooling, and add their positions, velocities and if they're active in the scene or not to the observations. I have tried with as little as 6 circles, which would put the total observations at somewhere around ~40-50, can't remember. But it didn't work at all. Agent would learn to dodge very quickly, probably less than 100 000 steps, but it wouldn't aim at all and even dodging would start deteriorating eventually.
``` foreach (GameObject asteroid in map.asteroids.Values)
{
sensor.AddObservation(asteroid.activeSelf);
Rigidbody2D arBody = asteroid.GetComponent<Rigidbody2D>();
Vector2 alocalVelocity = arBody.transform.InverseTransformDirection(arBody.velocity);
sensor.AddObservation(alocalVelocity.x);
sensor.AddObservation(alocalVelocity.y);
sensor.AddObservation(asteroid.transform.localPosition.x / (MapSetup.dimensions.x / 2));
sensor.AddObservation(asteroid.transform.localPosition.y / (MapSetup.dimensions.y / 2));
sensor.AddObservation(asteroid.transform.localScale);
}```
I've also though about splitting the agent into 2 tasks, one for movement, and the other for shooting, but since both of these tasks require z axis rotation, I think that they would be at odds with each other.
Can anyone recommend a better approach for vision? And can anyone comment if it's even plausible to make a perfect AI for this task, or should I just stick with my suboptimal solution I have right now?