# Add parabola curve to straight MoveTowards() movement

I have some units shooting arrows, right now they move in a straight line to the target. I want them to move like a real arrow, i.e using a parabola curve. However I don't want to use physics.

The math I need to do seems to be beyond me, I've tried to convert 2d solution I found online and other semi-similar solution with no luck.

My current straight movement:

private void Update()
{
var nextPos = Vector3.MoveTowards(transform.position, target, speed * Time.deltaTime);
transform.LookAt(nextPos, transform.forward);
transform.position = nextPos;

if (Vector3.Distance(nextPos, target) < .1f)
Arrived();
}


An example of a 2d version I tried to replicate: Here.

• You can use Quadratic Bezier curves to add a parabolic path to your projectiles. They are really easy to understand. You can find a really good tutorial here. The tutorial also provides the link to all the source code in the description. Jun 14, 2020 at 12:09

public float speed;
public Vector3 target;
public float arcHeight;

Vector3 _startPosition;
float _stepScale;
float _progress;

void Start() {
_startPosition = transform.position;

float distance = Vector3.Distance(_startPosition, target);

// This is one divided by the total flight duration, to help convert it to 0-1 progress.
_stepScale = speed / distance;
}

void Update() {
// Increment our progress from 0 at the start, to 1 when we arrive.
_progress = Mathf.Min(_progress + Time.deltaTime * _stepSize, 1.0f);

// Turn this 0-1 value into a parabola that goes from 0 to 1, then back to 0.
float parabola = 1.0f - 4.0f * (_progress - 0.5f) * (_progress - 0.5f);

// Travel in a straight line from our start position to the target.
Vector3 nextPos = Vector3.Lerp(_startPosition, target, progress);

// Then add a vertical arc in excess of this.
nextPos.y += parabola * arcHeight;

// Continue as before.
transform.LookAt(nextPos, transform.forward);
transform.position = nextPos;

// I presume you disable/destroy the arrow in Arrived so it doesn't keep arriving.
if(progress == 1.0f)
Arrived();
}

• Works perfectly, thank you, learned a lot from the comments!
– Majs
Jun 14, 2020 at 14:31
• For anyone coming back here in the future, in order to alter the arc height depending on distance (longer distance = higher arc) I simply add arcHeight = arcHeight * distance; where arcHeight has a value between 0 and 1.
– Majs
Jun 14, 2020 at 15:10