- Home /
2D Top Down Shooter: AI Ally twitching
Hi, and thanks for reading,
I've encountered a problem with an AI ally (armed with a gun) twitching (rotating rapidly side to side on the Y axis) when enemies get close. I think it's either caused by the ally and enemy rigidbodies bumping off one another, or the ally trying to keep its weapon pointed at an up close enemy.
I tried changing some of the properties of the rigidbody (mass, drag, angular) to no avail. Also commented out the code which rotates the ally toward the enemy. This prevents the twitching, but the ally isn't much use if it doesn't aim at enemies.
Update 1: Increasing the radius of the ally's capsule collider from 0.3 to 0.6 seems to have solved the problem. The enemies can't get so close now. This might suggest that the targetting/rotation code for the ally doesn't handle close up calculations very well, rather than it being a problem with collisions between rigidbodies. Using a oversize collider isn't a very good solution though, so an alternate one would be nice.
I've included the code the ally uses to rotate/track targets. If you need any more info, please ask. Thanks!
public void RotateToTarget()
{
// Predict time it will take a bullet to reach enemy
float secsFlightTime = (targetPosition - centreBulletSpawn.transform.position).magnitude / bulletSpeed;
// Get current velocity of target
Vector3 targetMovePerSec = target.rigidbody.velocity;
targetMovePerSec.y=0;
// Predict the future position of the target
Vector3 estHitPos = targetPosition + targetMovePerSec * secsFlightTime;
// Get the rotation needed to hit the enemy
Vector3 aimDirection = estHitPos - centreBulletSpawn.transform.position;
// Rotate turret to face that position
Quaternion neededRotation = Quaternion.LookRotation(aimDirection);
transform.rotation = Quaternion.Slerp(transform.rotation, neededRotation, rotationSpeed * Time.deltaTime);
//transform.rotation = neededRotation;
}
Answer by DMCH · Aug 22, 2013 at 12:41 PM
Sorry to answer my own question, but I just figured it out. Maybe it might be useful to the next guy. I think the problem had to do with estimating the future position of a target that is really close. Solved by adding a distance check, and only predicting future position if the target was over 2 units away. Code below:
// Estimates the target's position when the bullet will hit, and rotates toward it
public void RotateToTarget()
{
// Do a distance check to see how far away the enemy is
float distToEnemy = Vector3.Distance(position, targetPosition);
// If the enemy is more than 2 units away
if(distToEnemy > 2)
{
// Predict time it will take a bullet to reach enemy
float secsFlightTime = (targetPosition - centreBulletSpawn.transform.position).magnitude / bulletSpeed;
// Get current velocity of target
Vector3 targetMovePerSec = target.rigidbody.velocity;
targetMovePerSec.y=0;
// Predict the future position of the target
Vector3 estHitPos = targetPosition + targetMovePerSec * secsFlightTime;
// Get the rotation needed to hit the enemy
Vector3 aimDirection = (estHitPos - centreBulletSpawn.transform.position).normalized;
// Rotate turret to face that position
Quaternion neededRotation = Quaternion.LookRotation(aimDirection);
transform.rotation = Quaternion.Slerp(transform.rotation, neededRotation, rotationSpeed * Time.deltaTime);
}
// Else, the enemy is less than 2 units away
else
{
// Get the rotation needed to hit the enemy
Vector3 aimDirection = (targetPosition - position).normalized;
// Rotate turret to face that position
Quaternion neededRotation = Quaternion.LookRotation(aimDirection);
transform.rotation = Quaternion.Slerp(transform.rotation, neededRotation, rotationSpeed * Time.deltaTime);
}
}
Answering your own question (especially the way you have) is totally fine, as this is a knowledge base (all answers are meant to help future readers as well as the OP). upvoted =]
Answer by reppiz01 · Aug 22, 2013 at 09:50 AM
Vector3 aimDirection = estHitPos - centreBulletSpawn.transform.position;
try:
Vector3 aimDirection = (estHitPos - centreBulletSpawn.transform.position).normalized;
instead.
Thanks, but the character is still twitching. Almost certain it has to do with enemies being very close, as opposed to rigidbodies bumping into one another.
i thought of that, so my idea was to normalize, to "make" the distance bigger.
but nice that you solved it on your own.
Your answer
Follow this Question
Related Questions
how to make an object move towards it's rotation a set amount as a child in 2d 0 Answers
Having Issues Rotating 2d Sprites to face another 2d Object 3 Answers
Help with rotating a sprite with mouse. 2 Answers
How do i rotate my player in moving direction in 2d? 0 Answers
Rotating my character only while moving in a 2D plane 3 Answers