- Home /
Orbiting Bullets
I have a ship that is orbiting an object, and I need to now make it shoot bullets. I am having trouble getting this to work. I currently have my ship a child of a pivot point (0,0,0) and I have a gun a child of the ship. I also have two on-screen virtual joysticks (one controls the ship movement and the other controls the direction of the gun)...
I want to make it so that when the gun joystick is touched, that it starts shooting bullets in that direction and the bullets would orbit until they hit something, or their lifetime has elapsed.
If you would like a little more information, feel free to ask! Thanks!
Edit:
Here is what I have so far in my hierarchy:
Pivot - Camera - Ship - Gun - BulletSpawnPoint
The pivot point is the center of my planet (0,0,0). The Camera and ship orbit around the planet as one joystick is moved. The gun is controlled by a different joystick. Bullets are spawned at the bullet spawn point when fired.
Here is my code attached to the gun (The gun turns fine until the ship is moved to the other side of the planet and then it seems some signs get swapped):
// If the gun joystick is touched and the bullet interval has elapsed
if (GunJoystick.IsFingerDown() && ((Time.time*1000) - lastBulletTime) > BULLET_INTERVAL)
{
// Rotate the gun according to the joystick angle
currentAngle = (Mathf.Atan2(-GunJoystick.position.y, -GunJoystick.position.x) * (180/Mathf.PI)) + 90;
thisTransform.RotateAroundLocal(Vector3.forward, (Mathf.DeltaAngle(lastAngle, currentAngle)*Mathf.Deg2Rad));
lastAngle = currentAngle;
// Get the next bullet
currentBullet = bullets[nextBullet++];
// Check if we have used the last bullet and wrap around
if (nextBullet >= bullets.Length)
{
nextBullet = 0;
}
// Set the bullet values
currentBullet.bullet.SetActiveRecursively(true);
currentBullet.bullet.transform.position = thisTransform.position;
currentBullet.bullet.transform.rotation = thisTransform.localRotation;
currentBullet.startTime = Time.time * 1000;
currentBullet.bullet.GetComponent<BulletController>().direction.Set(GunJoystick.position.y, -GunJoystick.position.x, 0.0f);
// Set the last time a bullet was shot from the gun
lastBulletTime = currentBullet.startTime;
}
Here is the script attached to the bullet prefab, and it appears that something is wrong with this because the bullets don't orbit correctly:
public class BulletController : MonoBehaviour
{
public Vector3 direction;
private Transform thisTransform;
private const float BULLET_SPEED = 200;
public void Start()
{
thisTransform = transform;
direction = new Vector3();
}
public void Update()
{
if (gameObject.active)
{
//transform.Rotate(Direction.x + 100 * Time.deltaTime, Direction.y + 100 * Time.deltaTime, 0.0f);
thisTransform.RotateAround(Vector3.zero, direction, BULLET_SPEED * Time.deltaTime);
//thisTransform.Rotate(direction.y * BULLET_SPEED * Time.deltaTime, -direction.x * BULLET_SPEED * Time.deltaTime, 0.0f);
}
}
}
Answer by robertbu · Feb 16, 2013 at 05:02 PM
I would make an empty game object a child of the gun and place it just past the end of the gun (with the same rotation). This will be your spawn point. You can use Rigidbody.AddRelativeForce() using Vector3.forward to shoot the bullet.
I'm not sure how you want to handle this. If you want any sort of realism, note that not all trajectories will result in a orbit. For example, imagine the gun point directly toward the planet. What I would start with is a script on the bullet that add a small force every frame towards the planet. You'll have to play to get this force just right (and it will depend on the force you use to shoot your bullets). You have the bullet position and the planet center position, so figuring the direction of that force would be easy. This way bullets pointed down or out into space will behave as expected, and other trajectories will have a chance at an orbit.
In the few cases I tried, I often had trouble using balanced forces to achieve something stable (in my case a hovercraft), so you may have trouble getting a stable orbit. If the lifespan is short for the bullet, then this may not matter, but if it does matter, you can adjust the position of the bullet to keep a stable altitude at each frame. I believe you want to use Rigidbody.MovePosition() to reset the position rather than directly modifying the transform.
Thanks for the help, although I am trying to do this using the Rotate() or RotateAround() methods. See my edits above for what I have so far. $$anonymous$$y bullets seems to shoot in the correct direction (following the joystick) until it orbits to the back side of the planet and then it seems a sign get's flipped and I'm not sure how to handle this. If you see anything that doesn't look correct, please let me know! Thanks!
Are you using the joystick to guide the bullets? In other words is "direction" being updated or changed after the bullet is fired?
No, just when they are fired it grabs the current joystick direction and then applies that one direction to the bullet until it's life has elapsed which then it is set to inactive, until it is reused.
RotateAround() is an angle axis rotation. I don't see how the bullet can "get its sign flipped" unless the axis is changed or the BULLET_SPEED is changed.
It must be something with my hierarchy maybe? As my ship is moving around it applies it's rotations to the gun which in turn applies it to the spawn point set just ahead of the gun. So if I don't move the ship at all and just start shooting, the bullets move exactly how I would expect. But if I start to move the ship then that is when the bullet orbits start to get messed up. When I reset each bullet, it inherits the position and rotation from the gun. Does anything sound wrong about that? Or do you have any suggestions as to what might be causing it?
Your answer
Follow this Question
Related Questions
bullet prefab always come out in wrong direction 2 Answers
Setting bullet instansiate direction? help? 1 Answer
BCE0005: Unknown identifier: 'bulletSpawn'. 2 Answers
Dual-Joystick Controlled 3rd-Person Orbit Camera 1 Answer
gun problems 1 Answer