spaceship ai
I'm trying to create a very simple spaceship ai in 3d but i have some problems so far. I've found some topics on gamedev but i think they are too complex for my purpose. What i want ai to do is follow player, avoid asteroids and if player is in the shooting range shoot. And spaceships don't have the ability to yaw. So if player is above or below ai should pitch to the player direction and if player is on the right side or the left side ai should first roll than pitch to the player. I think my biggest problem is this part. Is there a simple way to create this kind of ai behaviour? Thanks.
I'm trying to create a very simple spaceship ai in 3d but i have some problems so far. I've found some topics on gamedev but i think they are too complex for my purpose. What i want ai to do is follow player, avoid asteroids and if player is in the shooting range shoot. And spaceships don't have the ability to yaw. So if player is above or below ai should pitch to the player direction and if player is on the right side or the left side ai should first roll than pitch to the player. I think my biggest problem is this part. Is there a simple way to create this kind of ai behaviour? Thanks.
Simple is always relative, take a look at steering behaviour over here, the website contains many examples.
There's a few things you need to do in order to achieve this kind of seemingly simple AI. It's a little late excuse me if I list these in the wrong order but the basic idea is as such.
1) Create 3 bounding spheres or bounding boxes around the enemy ship that you will be using as such...
2) Assuming the player is within chase distance start calculating your rotations towards the target (player)
3) At this point to avoid obstacles you may want to use a ray from the enemy in the forward direction to test for what might be in the way.
4) Assuming you find an object in the way what I would do is then grab the size of said obstruction and apply that to a rotation that would rotate the enemy on a course to not collide. Best practice if possible is back in the direction you started from (so reversing the rotation you applied from step 2).
5) Test if the target is within weapons distance and if so start unloading!
6) Test if the target is within follow distance, if so calculate velocity alterations to keep the desired distance.
Still sounds a bit easier then it really will be, the most complicated part of this of course is using the ray to find obstacles and reversing your rotation to ignore. However this technique will also tend to want to follow the exact path of the player around obstacles. Or in other words even though the human eye may want to turn harder to cut the player off on the right side of the asteroid if your reversing the rotation that is already turning right to catch up you will inevitably follow the player around the asteroid the same way they circled it. However this does give your player a way to actually outrun the enemies, simply make a lot of sharp turns around asteroids. You can avoid this path tracing a bit by only avoiding obstacles that are very close to the enemy ship, just really takes some trial and error to get what you actually want as far as the enemy AI goes.
1) Create 3 bounding spheres or bounding boxes around the enemy ship that you will be using as such...
- Chase distance, this is the longest one. If the target (player) is within this bounding geometry you will further calculate AI.
- Weapons Distance, self explanatory
- Follow Distance, once the target is within this bounding geometry the enemy ship should slow down possibly matching player speed.
2) Assuming the player is within chase distance start calculating your rotations towards the target (player)
3) At this point to avoid obstacles you may want to use a ray from the enemy in the forward direction to test for what might be in the way.
4) Assuming you find an object in the way what I would do is then grab the size of said obstruction and apply that to a rotation that would rotate the enemy on a course to not collide. Best practice if possible is back in the direction you started from (so reversing the rotation you applied from step 2).
5) Test if the target is within weapons distance and if so start unloading!
6) Test if the target is within follow distance, if so calculate velocity alterations to keep the desired distance.
Still sounds a bit easier then it really will be, the most complicated part of this of course is using the ray to find obstacles and reversing your rotation to ignore. However this technique will also tend to want to follow the exact path of the player around obstacles. Or in other words even though the human eye may want to turn harder to cut the player off on the right side of the asteroid if your reversing the rotation that is already turning right to catch up you will inevitably follow the player around the asteroid the same way they circled it. However this does give your player a way to actually outrun the enemies, simply make a lot of sharp turns around asteroids. You can avoid this path tracing a bit by only avoiding obstacles that are very close to the enemy ship, just really takes some trial and error to get what you actually want as far as the enemy AI goes.
Dan Mayor
Professional Programmer & Hobbyist Game Developer
Seeking team for indie development opportunities, see my classifieds post
Thanks Dan Mayor. I'm currently doing something similar to what you said. But my main problem is finding the rotation axis according to player position. Here is my rotation code. I don't know why but it doesn't do anything.
glm::vec3 playerPos = playerShip->position;
glm::vec3 playerDir = playerShip->currentDirection;
if(playerDir == currentDirection)
{
position += currentDirection * speed * elapsedTime;
return;
}
float angle = glm::acos((glm::dot(currentDirection, playerDir)));
glm::vec3 rotationAxis = glm::cross(currentDirection, playerDir);
rotationAxis = glm::normalize(rotationAxis);
transformMatrix = glm::gtc::quaternion::mat4_cast(glm::gtc::quaternion::rotate(glm::quat(), angle, rotationAxis));
glm::vec4 v = transformMatrix * initialDirection;
currentDirection = glm::vec3(v.x, v.y, v.z);
currentDirection = glm::normalize(currentDirection);
position += currentDirection * speed * elapsedTime;
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement