I have a spaceship with a launcher on it that fires a projectile. When I shoot, the bullet fires fine when staying still. When I move the spaceship and shoot, the bullet can not keep up with the speed of the ship. I need a way for the bullet to take the ship’s velocity into account in addition to its speed. How can I achieve this?
Here is what I have so far:
var projectile : Rigidbody;
var speed = 20.0;
var launcher : Rigidbody;
function Update()
{
if(Input.GetButtonDown("Fire1"))
{
var instantiatedProjectile : Rigidbody = Instantiate (projectile, transform.position, GameObject.Find("rotationspawn").transform.rotation);
instantiatedProjectile.velocity = transform.TransformDirection (new Vector3(0, 0, speed));
}
}
JM’s code is wrong, that’s not how you access variables across objects.
Somewhere you are controlling your ship’s movement. Either by applying force to it or by directly moving it via transform.position or .Translate.
If you’re using force, you can use:
var shipObject : Rigidbody; // set in inspector
instantiatedProjectile.velocity += shipObject.velocity;
If you’re ‘teleporting’ your ship by setting its position directly, then you need to be storing its movement somewhere. For instance you might have in “Ship.js”: (name’s not important)
var speed : Vector3;
function Update() {
transform.position += speed * TIme.deltaTime;
}
In that case you’d use:
var shipObject : Ship; // or whatever your ship script is named - set in inspector
instantiatedProjectile.velocity += shipObject.speed;
HOWEVER
It’s best for your firing code to go in the same script as the rest of your input - spreading input out over multiple scripts can only cause headaches later. Plus, your ship should know about its weaponry; there’s little logical disconnect between them (if any). And if the two scripts are combined then it’s trivial to get the ship’s movement velocity added to its weapons-fire velocity.
Vicenti, thank you for all the help, but I am still having problems.
I created a new script called Ship and entered your code in it
var speed : Vector3;
function Update() {
transform.position += speed * TIme.deltaTime;
}
I then attached this script to my ship object. I then entered the following code into my launcher script.
var shipObject : Ship;
instantiatedProjectile.velocity += shipObject.speed;
I then referenced the ship object in the inspector. I try the game, but now my bullets don’t move anywhere and still don’t move at the same velocity as the ship. Any idea whats wrong?
var forward = transform.TransformDirection(Vector3.forward);
var newBulletSpeed = speed + shipObject.transform.rigidbody.velocity.magnitude * 5; //Modify this multiplier (*5) depending on the mass of your projectile
var instantiatedProjectile : Rigidbody = Instantiate (projectile, rotationspawn, Quaternion.identity);
instantiatedProjectile.rigidbody.AddRelativeForce(transform.forward * newBulletSpeed);
instantiatedProjectile.transform.rotation = rotationspawn.transform.rotation;
No appropriate version of ‘UnityEngine.Object.Instantiate’ for the argument list ‘(UnityEngine.Rigidbody, UnityEngine.Transform, UnityEngine.Quaternion)’ was found.
for this line:
var instantiatedProjectile : Rigidbody = Instantiate (projectile, rotationspawn, Quaternion.identity);
The code on the launcher object. (the launcher is a child of the ship)
var projectile : Rigidbody;
var launchSpeed = 20.0;
var rotationspawn : Transform;
var shipObject : Ship;
function Update()
{
if(Input.GetButtonDown("Fire1"))
{
var forward = transform.TransformDirection(Vector3.forward);
var newBulletSpeed = launchSpeed + shipObject.transform.rigidbody.velocity.magnitude * 5; //Modify this multiplier (*5) depending on the mass of your projectile
var instantiatedProjectile : Rigidbody = Instantiate (projectile, rotationspawn.position, Quaternion.identity);
instantiatedProjectile.rigidbody.AddRelativeForce(transform.forward * newBulletSpeed);
instantiatedProjectile.transform.rotation = rotationspawn.transform.rotation;
}
}
The code on the ship object:
var speed : Vector3;
function Update() {
transform.position += speed * Time.deltaTime;
}
You’re moving your ship every frame directly using transform.position. Thus, the physics engine has no idea what it’s speed is, as far as it’s concerned it’s a stationary object that teleports every frame. So shipObject.transform.rigidbody.velocity.magnitude is probably 0. If you want to calculate the speed of the ship, you’ll need to store it’s position every frame, then use something like (transform.position - oldposition) / Time.deltaTime. You could then pass this value to the launcher so it can use that. If you’re going to go that route, you might as well just move the projectile the same way, using transform.position += speed * Time.deltaTime
If you want to move your ship via physics, then your code might almost work, but I’d recommend using ForceMode.VelocityChange to set the speed of the projectile directly instead or just applying a force.
I’m having the same issue, only I’m making a first person shooter and using the FPS controller.
This is what I have going on right now:
The bullets spawn fine from the barrel of the gun when standing still, moving the mouse does not cause them too lag behind. But when I move around the bullets lag behind. I assume I need to get my velocity from the character motor script, but that script is massive and I can’t even find where the “push this button to move” code is. Can anyone tell me where I should start?
In real life the momentum of a person holding a gun would have such a small affect on the trajectory of the bullet that it would not be noticeable. Bullets travel pretty damned fast. Most games just use “speed of light” instantaneous bullets for machine guns and pistols, and they reserve the physics simulations for rockets and slower moving projectiles.