Hi! I’m just wondering if there’s any way within PlayCanvas to do a teleport arc–the kind where the user’s pointer creates a curve down to the ground at wherever they’re pointing. Something like this:

(Image source)

Is that possible? If so, what would be a good way to do this?

Definitely possible. You effectively ‘fire’ a projectile, simulate the timepsteps doing a raycast with each step. Example code off the top of my head (may not compile).

```
var velocity = new pc.Vec3().copy(launchAngle).scale(5); // The 5 can be any number and should be tweaked to suit your needs
var gravity = new pc.Vec3(0, -9.8, 0); // Again can be tweaked
var timeStep = 0.5; // A smaller number means more calculations and raycast but a more accurate curve;
var currentPosition = new pc.Vec3().copy(launchPosition);
var oldPosition = currentPosition.clone();
// What gravity is going to be in each time step)
gravity.scale(timeStep * timeStep).scale(0.5);
do {
// Work out the new position
oldPosition.copy(currentPosition);
velocity.add(gravity);
// Apply velocity to position of the 'projectile'
currentPosition.copy(velocity).scale(timeStep).add(oldPosition);
} while (!doesRaycastHit(oldPosition, newPosition))
// Perform a raycast between the old and new position and keep going until we hit something
```

To render the curve, I think that generating a mesh with lots of divisions and moving the vertices to match the positions calculated above would be the best approach. @max may have a better idea.

1 Like

Just found out my math is slightly wrong

```
var velocity = new pc.Vec3().copy(launchAngle).scale(5); // The 5 can be any number and should be tweaked to suit your needs
var gravity = new pc.Vec3(0, -9.8, 0); // Again can be tweaked
var timeStep = 0.5; // A smaller number means more calculations and raycast but a more accurate curve;
var currentPosition = new pc.Vec3().copy(launchPosition);
var oldPosition = currentPosition.clone();
// What gravity is going to be in each time step)
gravity.scale(timeStep);
do {
// Work out the new position
oldPosition.copy(currentPosition);
velocity.add(gravity);
// Apply velocity to position of the 'projectile'
currentPosition.copy(velocity).scale(timeStep).add(oldPosition);
} while (!doesRaycastHit(oldPosition, newPosition))
// Perform a raycast between the old and new position and keep going until we hit something
```

Thanks so much for following up @yaustar! Super helpful! I’m going to give that a try and see what I come up with!

Err… Just realised that had a typo on top of that

I’ve edited the above reply with the correction of the typo.