Hello,
I programmed a scene for the ClassVR headsets. For this I have implemented code to jump. Everything works fine in the browser, but when you try to jump with the ClassVR headset, you fall through the floor. I also added a cuboid above the player and when the player jumps against that cuboid it doesn’t fall through the floor. Here is the code:
class JumpButton {
private _jumpText: TextItem
private _jumpButton: Ellipsoid
private _update: Disposable
private _isJumping = false
private _canJump = true
private _arc = new Arc()
private _lastCollidingItem: BaseItem
static V3_LERP = (start: Vector3, end: Vector3, percent: number): Vector3 => start.add((end.sub(start).mult(percent)));
static LERP_SPEED = 30;
static JUMP_DISTANCE = 10;
static JUMP_DURATION = 0.65
constructor() {
if (Scene.getProperty('jumpButton_FEATURE') !== 'enabled') {
Scene.setProperty('jumpButton_FEATURE', 'enabled')
this._init()
}
}
private _init() {
//this._createButton()
//this._bindButtonClick()
this._onUpdate()
this._bindCollision()
}
private _dispose() {
if (this._update !== undefined) this._update.dispose()
if (this._jumpButton) {
this._jumpButton.deleteChildren()
this._jumpButton.delete()
}
}
private _createButton() {
this._jumpText = Scene.createText(0, 0, 0, 'JUMP')
this._jumpButton = Scene.createEllipsoid(0, 0, 0)
this._jumpButton.radiusX = 0.4;
this._jumpButton.radiusY = 0.01;
this._jumpButton.radiusZ = 0.4;
this._jumpText.getSlot('Bottom').attachTo(this._jumpButton.getSlot('Front'))
this._jumpText.color = new Color(200,200,0);
this._jumpButton.transform.scale = 0.2
RayCast.addToFilter(this._jumpText)
Camera.addToCollisionFilter(this._jumpButton)
Camera.addToCollisionFilter(this._jumpText)
}
private _bindCollision() {
Camera.focusedItem.onCollisionEnter(item => {
if (this._isJumping) {
if (item !== this._lastCollidingItem) {
this._lastCollidingItem = item
this._canJump = false
}
}
})
}
private _bindButtonClick() {
this._jumpButton.input.onClick(() => {
this._jump()
})
}
private _onUpdate() {
this._update = Time.scheduleRepeating(delta => {
let cameraTarget = Camera.transform.position.add(Camera.transform.forward.mult(0.5));
cameraTarget = new Vector3(cameraTarget.x, cameraTarget.y, Camera.transform.position.z - 0.5)
//this._jumpButton.transform.position = JumpButton.V3_LERP(this._jumpButton.transform.position, cameraTarget, JumpButton.LERP_SPEED * delta)
//this._jumpButton.transform.lookAt(Camera.transform.position)
})
}
public async _jump() {
if (!this._isJumping) {
//this._jumpButton.active = false
this._isJumping = true
let cameraDir = new Vector3(Camera.transform.forward.x, Camera.transform.forward.y, 0)
let cameraPos = Camera.transform.position
let jumpTrajectory = this._arc.calculateArcArray(cameraPos, cameraDir)
/*for (let i = 0; i < jumpTrajectory.length - 1; i++) {
await this._interpolateJump(jumpTrajectory[i], jumpTrajectory[i + 1], JumpButton.JUMP_DURATION / jumpTrajectory.length)
}*/
let time = 0
let curStep = 0;
let curStart = jumpTrajectory[0];
let curEnd = jumpTrajectory[1];
let duration = JumpButton.JUMP_DURATION / jumpTrajectory.length;
let nextStepTime = duration;
let update = Time.scheduleRepeating(d => {
if (!this._canJump) {
update.dispose()
this._endJump();
return;
}
time += d;
Camera.focusedItem.transform.position = JumpButton.V3_LERP(curStart, curEnd, time / duration)
if (time >= nextStepTime) {
if (curStep >= jumpTrajectory.length - 2 ) {
update.dispose();
this._endJump();
return;
}
curStep++;
curStart = jumpTrajectory[curStep];
curEnd = jumpTrajectory[curStep + 1];
nextStepTime += duration;
}
});
}
}
private _endJump() {
this._canJump = true
this._isJumping = false
this._lastCollidingItem = null
//this._jumpButton.active = true
}
}
class Arc {
static Deg2Rad = 0.0174533
static GRAVITY: number = Physics.gravityAcceleration
public velocity: number = 7
public angle: number = 60
public resolution: number = 50
private _radianAngle: number
public calculateArcArray(origin: Vector3, direction: Vector3): Vector3[] {
let arcArray: Vector3[] = []
this._radianAngle = this.angle * Arc.Deg2Rad
let maxDistance = (this.velocity * this.velocity * Math.sin(2 * this._radianAngle)) / Arc.GRAVITY
for (let i = 0; i <= this.resolution; i++) {
let t = i / this.resolution
let arcPoint = this._calculateArcPoint(t, maxDistance, direction)
arcPoint = origin.add(arcPoint)
arcArray[i] = arcPoint
}
return arcArray
}
private _calculateArcPoint(t: number, maxDistance: number, direction: Vector3): Vector3 {
let x = t * maxDistance
let y = t * maxDistance
if(!Application.isMobile){
var z = x * Math.tan(this._radianAngle) - ((Arc.GRAVITY * x * x) / (2 * this.velocity * this.velocity * Math.cos(this._radianAngle) * Math.cos(this._radianAngle)))
}else{
var z = 0.25 * x * Math.tan(this._radianAngle) - ((Arc.GRAVITY * x * x) / (2 * this.velocity * this.velocity * Math.cos(this._radianAngle) * Math.cos(this._radianAngle)))
}
return new Vector3(
x * direction.x,
y * direction.y,
z
)
}
}
var jumpButton = new JumpButton()
jumpButton._jump();