# Projectile arc velocity changes depending on target x-axis position

I am trying to create an enemy for a 2D platformer that launches a projectile in an arc at the player position (think throwing a grenade, launching an arrow style parabola).

Everything works as expected if the player and enemy are more or less on the same y-axis (or similar, within a few units), but the further the difference on the y axis, the faster the projectile moves. This also happens the closer the target gets on the x-axis (but only if there is a difference in the y-axis).

I've included the code in the script that's attached to the projectile that moves it as everything else (the collision, the actual launching of the projectile, etc) works as it should.


GameObject target; // The player is the target
float velX = 10; // Initial x velocity is known
float velY;

private void Start()
{
// Initialize the target object
target = GameObject.FindGameObjectWithTag("Player");
// Reverse the x velocity depending on player position
velX = target.transform.position.x > transform.position.x ? velX : -velX;
// Calculate the time to impact
float timeToImpact = (target.transform.position.x - transform.position.x) / velX;
// Calculate the initial y velocity
// Add 2 to the target position to aim at the top of the player - it's 2 units tall
velY = (target.transform.position.y + 2f - transform.position.y + 0.5f * -Physics2D.gravity.y * (timeToImpact * timeToImpact)) / timeToImpact;
}

private void Update()
{
// Set the rigidbody velocity
Vector2 vel = new Vector2(velX, velY);
GetComponent<Rigidbody2D>().velocity = vel;
// Gravity alters the y velocity over time
velY += Physics2D.gravity.y * Time.deltaTime;
}


I'm sure that there's just some value that I need to divide or multiply one of the velocities or time by but I can't quite wrap my head around it.

As an aside, your Update() method in this code looks very strange. You should not need to apply gravity yourself - the Rigidbody will integrate that for you. You can use the gravityScale property to adjust the amount of gravity each object gets if you want to apply more or less (or no) gravity to some objects, without extra scripts. If you do find you need to make custom scripted changes to physics behaviour, you should generally do that in FixedUpdate(), not Update() - especially for continuous effects like gravity - this will give you more consistent behaviour even under varying framerates.