- Home /
How to make bullets moving proportionally faster than player?
I have ship and instantiated bullets by poolManager, my ship is able to rotate and fly around freely, and shoot bullets of course. Everything in Top-Down perspective
The Bullet have components:
Kinematic RigidBody2D
Capsule Trigger Collider 2D
When player stays still and shoots, bullets speed looks fine, but moving forward and shooting makes bullets head backward due to ship speed, also rotating, flying and shooting at same time makes it very odd, bullets don't move straight I think it's also due to speed difference.
My player ship's components:
Dynamic RigidBody2D
Box Collider 2D
I was trying to add
player.body.velocity
To bullet speed Translate, but the final bullet speed, it was way too fast. What i want are plasma projectiles flying with medium speed.
Here is my Bullet Class
public class Bullet : Pool_Object {
public float bulletSpeed = 5;
public Vector2 ownerVelocity;
public int duration = 2;
private float counter;
private Player owner;
private void Awake()
{
owner = FindObjectOfType();
ownerVelocity = new Vector2(0, 0);
}
private void OnEnable()
{
ownerVelocity=owner.Body.velocity;
if (owner != null)
{
Debug.Log("Player Velocity: "+ownerVelocity);
}
}
void Update ()
{
if (gameObject.activeInHierarchy)
{
transform.Translate(Vector2.up * bulletSpeed * Time.deltaTime +> ownerVelocity);
counter += Time.deltaTime;
}
if (duration <= counter )
{
gameObject.SetActive(false);
counter = 0;
}
}
In this case i actually looking for a way to make bullets move proportionally to the ship movement, cause they're too fast, no matter what i do they just blinking thru the view field.
UPDATE TO ABOVE CLASS:
private void OnEnable()
{
ownerVelocity = ownerBody.velocity.magnitude;
}
void Update ()
{
if (gameObject.activeInHierarchy)
{
transform.Translate(Vector3.up* Time.deltaTime* (ownerVelocity+bulletSpeed));
counter += Time.deltaTime;
}
if (duration <= counter )
{
gameObject.SetActive(false);
counter = 0;
}
}
It does look way better now, but still isn't a solution
I already tried:
Normalizing ownerVelocity;
Scalling down bulletSpeed;
Using RigidBody.AddForce with dynamic RigidBody2D;
Assing speed directly by bullet.velocity += owner.velocity;
Using transform.up instead of Vector2.up;
Using space.world;
Dividing owner.velocity;
Tried Answers:
Using transform.forward instead of Vector2.up
Removed bullet instances from player parentship
Reuse bullets at muzzle of weapon:
public class Barrel : MonoBehaviour
{
Transform firePoint;
private GameObject bulletType;
void Awake ()
{
bulletType = GetComponentInParent<Weapon>().bulletType;
firePoint = transform.GetChild(0);
if (firePoint == null)
{
Debug.LogError("No FirePoint? WHAT?!");
}
}
public void Shoot()
{
Pool_Manager.Instance.ReuseObject(bulletType, firePoint.position,firePoint.rotation);
}
Some methods that actually are setting my bullets to positions, rotations etc
public ObjectInstance(GameObject objectInstance)
{
gameObject = objectInstance;
transform = gameObject.transform;
gameObject.SetActive(false);
if (gameObject.GetComponent<Pool_Object>())
{
hasPoolObjectComponent = true;
poolObjectScript = gameObject.GetComponent<Pool_Object>();
}
}
public void Reuse(Vector3 position, Quaternion rotation)
{
gameObject.SetActive(true);
transform.position = position;
transform.rotation = rotation;
if (hasPoolObjectComponent)
{
poolObjectScript.OnObjectReuse();
}
}
I appreciate any answer, if you think about anything please, let me know. Thank you!
Answer by Chris_Payne_QS · Apr 03, 2018 at 10:46 PM
Hard to tell without seeing your bullet spawning code, but it sounds like your bullets are still parented to the ship. Make sure they're all parented to a stationary dummy object when you create your bullet pool.
You also probably want your bullets to fire at a fixed speed rather than adding your ship speed to it - not physically accurate, but more intuitively "correct" than bullets which overtake each other depending on how the ship was moving at launch time. They just need to move faster than your ship's top speed.
Yes, bullets are instantiated in to one of my player childrens, with position and rotation set in Instantiate method.
Also how do you mean by using fixed speed?
Everything in the hierarchy below your player will move when your player moves. You need the bullets to detach from the player hierarchy so they will fly straight.
By fixed speed I mean that you probably want all your bullets to fly at bulletSpeed regardless of how fast the player was moving. For example, in Space Invaders your bullets always fly straight upwards even if the ship was moving left when firing.
So you shouldn't need to add the player speed - just spawn the bullet at the gun barrel, facing the correct direction, parented to some stationary object (eg. an invisible "bulletParent") and let it travel forwards at bulletSpeed.
Answer by Cornelis-de-Jager · Apr 03, 2018 at 10:22 PM
Try the following:
// Replace this
transform.Translate(Vector2.up * bulletSpeed * Time.deltaTime +> ownerVelocity);
// With this
transform.Translate(transform.forward * bulletSpeed * Time.deltaTime + ownerVelocity);
Thank you for your reply!
Unfortunately this doesn't work :/
See @Chris_Payne_QS 's answer. It does sound like your bullet is still a child of your player object. can you post the code
Well my bullet instances are not directly under player, but in few objects under each other,
I will try to paste some code
Answer by Atticus052 · Feb 04, 2021 at 05:22 PM
this code fires a projectile from the players reference frame, so if you're moving 100 units in +x and you fire a shot backwards at -50 x units, the shot will still be traveling at +50 units
public class newFireController : MonoBehaviour { public Transform PlayerShip; //supplies projectile velocity at spawn public Transform firePoint; //location where projectile will spawn public GameObject ammoType; //sprite of ammo plus collision checking public float fireDelay = 0.2f; //time btn shots public float bulletLifespan = 2.0f; //how long bullet survives public float bulletSpeed = 10.0f; //speed of projectile public int damage = 25; //damage public GameObject hitEffect; //sprite/animation played at impact
private Rigidbody2D rb;
float cooldownTimer = 0;
void Update()
{
cooldownTimer -= Time.deltaTime;
if (Input.GetButton("Fire1") && cooldownTimer <= 0)
{
cooldownTimer = fireDelay;
//Get parent ship velocity
Vector3 velocity = PlayerShip.GetComponent<Rigidbody2D>().velocity;
//spawn projectile
GameObject shot = Instantiate(ammoType, firePoint.position, firePoint.rotation);
//get RB component of bullet
rb = shot.GetComponent<Rigidbody2D>();
rb.velocity = velocity;
//add shot force, point in direction of the firepoint
rb.AddForce(firePoint.up* bulletSpeed, ForceMode2D.Impulse);
Destroy(shot, bulletLifespan);
}
}
}
Answer by mephistoII666 · Feb 04, 2021 at 06:22 PM
I don't know if I can give you a full answer but I just want to warn you of a huge potential bug in your code:
ownerVelocity = ownerBody.velocity.magnitude;
[...]
transform.Translate(Vector3.up* Time.deltaTime* (ownerVelocity+bulletSpeed));
You are increasing the bullet's forwards movement by the MAGNITUDE of the owner's velocity.
A Vector3's magnitude is its length expressed as a float, so velocity.magnitude represents an object's speed independently of direction. This means quoted code will result in:
Shoot stationary: bullet advances normally.
Shoot while moving forward: bullet advances faster. (good)
Shoot while moving backward: bullet moves faster. (bad, as the bullet will now seem to ZOOM forward)
Shoot while moving laterally: bullet moves as straight as ever, but still faster (bad)
What you probably want instead is the bullet to inherit the paren'ts velocity:
Shoot stationary: bullet advances normally
Shoot while moving forward: bullet moves faster
Shoot while moving backward: bullet moves slower
Shoot while moving laterally: bullet moves sideways algongside the parent
To do this you simply need to add together your bullet's velocity and the parent's velocity at the moment of launch.
Vector3 ownerVelocity = ownerBody.velocity; //store parent's vector3 velocity
[...]
//this vector3 is your bullet's velocity if it didn't inherit any movement
Vector3 baseBulletVelocity = (Vector3.up * bulletSpeed)
transform.Translate((baseBulletVelocity + ownerVelocity) * Time.deltaTime);
I wouldn't be surprised if this quirk was the only source of all of your headaches.