Possible to do teleport arc for VR?

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 :sweat_smile:

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 :confounded:

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