Playcanvas uses an different method for the gamepads, if you look into my game I made with PC & Xbox (Gamepad) controls you’ll kinda understand it
var ControllerAlpha = pc.createScript('ControllerAlpha');
// Attributes
ControllerAlpha.attributes.add('boost_EXP', { type: 'entity' });
ControllerAlpha.attributes.add('boost_EXP2', { type: 'entity' });
ControllerAlpha.attributes.add('bersekBoom', { type: 'entity' });
ControllerAlpha.attributes.add('Forward_EXP', { type: 'entity' });
ControllerAlpha.attributes.add('base', { type: 'entity' });
ControllerAlpha.attributes.add('airsp', { type: 'entity' });
ControllerAlpha.attributes.add('playerCam', { type: 'entity' });
ControllerAlpha.attributes.add('txtas', { type: 'entity' });
ControllerAlpha.attributes.add('hit', { type: 'entity' });
ControllerAlpha.attributes.add("doubleClickSpeed", { type: "number", default: 0.5 });
ControllerAlpha.attributes.add("speed", { type: "number", default: 1 });
ControllerAlpha.attributes.add("deadzone", { type: "number", default: 0.5 });
ControllerAlpha.attributes.add("focusMode", { type: "number", default: 0.2 });
ControllerAlpha.attributes.add("darkness", { type: "number", default: 0.3 });
ControllerAlpha.attributes.add("offset", { type: "number", default: 0.3 });
ControllerAlpha.attributes.add("hue", { type: "number", default: 0.165 });
ControllerAlpha.attributes.add("sat", { type: "number", default: 0.25 });
ControllerAlpha.attributes.add("chromaticAberrationIntensity", { type: "number", default: 1 });
ControllerAlpha.attributes.add("highlightThreshold", { type: "number", default: 0.3 });
ControllerAlpha.attributes.add("MaxEventMotionPercent", { type: "number", default: 0.7 });
ControllerAlpha.attributes.add("NormalMotionPercent", { type: "number", default: 0.93 });
ControllerAlpha.attributes.add("EventMotionPercent", { type: "number", default: 0.45 });
ControllerAlpha.attributes.add("EventBokehPercent", { type: "number", default: 0.0008 });
ControllerAlpha.attributes.add("EventBokehFOCUSPercent", { type: "number", default: 0.0008 });
ControllerAlpha.attributes.add("NormalBokehPercent", { type: "number", default: 0.0002 });
// Initialization bersekBoom darkness offset
ControllerAlpha.prototype.initialize = function () {
this.resetFlags();
this.setupInputListeners();
this.prevGamepadState = {};
this.boostDisabled = false;
this.boostDisabledOP = false;
this.boostDisabledOPbersek = false;
this.updateBoostDisabledOP();
this.updateBerserker();
this.leftShift = false;
this.rightShift = false;
window.addEventListener('keydown', (e) => {
if (e.key === "Shift" && e.location === 1) this.leftShift = true;
if (e.key === "Shift" && e.location === 2) this.rightShift = true;
});
window.addEventListener('keyup', (e) => {
if (e.key === "Shift" && e.location === 1) this.leftShift = false;
if (e.key === "Shift" && e.location === 2) this.rightShift = false;
});
this.entity.collision.on('contact', this.onContact, this);
};
ControllerAlpha.prototype.onContact = function (result) {
if (this.entity.sound) {
this.entity.sound.play("hitBox");
}
this.hit.particlesystem.reset();
this.hit.particlesystem.play();
this.app.fire('boostDisabledOP:active');
// Restore camera after delay
setTimeout(() => {
this.app.fire('boostDisabledOP:end');
}, 700);
};
ControllerAlpha.prototype.resetFlags = function () {
this.velocityX = this.velocityY = this.velocityZ = 0;
this.speed = 0;
this.engineOn = true;
this.can = true;
this.ControllerAlphas = true;
this.force_gravity = 0;
this.force_lift = 2.5;
this.k = false;
this.temp = false;
this.isonfire = false;
this.timeSinceLastClick = this.doubleClickSpeed;
};
ControllerAlpha.prototype.setupInputListeners = function () {
if (this.app.mouse) {
this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this);
this.app.mouse.on(pc.EVENT_MOUSEUP, this.onMouseUp, this);
}
if (this.app.touch) {
this.app.touch.on(pc.EVENT_TOUCHSTART, this.onTouchStart, this);
this.app.touch.on(pc.EVENT_TOUCHEND, this.onTouchEndCancel, this);
this.app.touch.on(pc.EVENT_TOUCHCANCEL, this.onTouchEndCancel, this);
}
};
ControllerAlpha.prototype.update = function (dt) {
this.updateGamepadState();
this.handleInput(dt);
this.handleSoundEffects();
this.handleFlightPhysics(dt);
this.updateUI();
};
ControllerAlpha.prototype.updateGamepadState = function () {
this.gamepad = navigator.getGamepads()[0];
this.usingGamepad = this.gamepad && this.gamepad.connected;
};
ControllerAlpha.prototype.handleInput = function (dt) {
const deadZone = this.deadzone;
const axisLX = this.usingGamepad ? this.gamepad.axes[0] : 0;
const axisLY = this.usingGamepad ? this.gamepad.axes[1] : 0;
const axisRX = this.usingGamepad ? this.gamepad.axes[2] : 0;
const btn = (index) => this.usingGamepad && this.gamepad.buttons[index]?.pressed;
this.isWDown = this.app.keyboard.isPressed(pc.KEY_W) || (axisLY < -deadZone);
this.isSDown = this.app.keyboard.isPressed(pc.KEY_S) || (axisLY > deadZone);
this.isADown = this.app.keyboard.isPressed(pc.KEY_A) || (axisLX < -deadZone);
this.isDDown = this.app.keyboard.isPressed(pc.KEY_D) || (axisLX > deadZone);
this.isqdown = this.app.keyboard.isPressed(pc.KEY_Q) || (axisRX < -deadZone);
this.isedown = this.app.keyboard.isPressed(pc.KEY_E) || (axisRX > deadZone);
this.isSpaceDown = this.app.keyboard.isPressed(pc.KEY_SPACE) || btn(0);
this.isXDown = this.app.keyboard.isPressed(pc.KEY_X) || btn(4);
if (!this.boostDisabled) {
const boostNow = (this.shiftDown && this.app.keyboard.isPressed(pc.KEY_UP)) || (btn(9) && btn(8));
if (boostNow && !this.shiftDownBoost) {
this.app.fire('boost:active');
// this.entity.script.fireballAttack.enabled = false; // 🔥 disable fireball
}
if (!boostNow && this.shiftDownBoost) {
this.app.fire('boost:end');
//this.entity.script.fireballAttack.enabled = true; // 🔥 enable fireball
}
this.shiftDownBoost = boostNow;
} else {
this.app.fire('boost:end');
//his.entity.script.fireballAttack.enabled = true; // 🔥 enable fireball
this.shiftDownBoost = false;
}
if (!this.boostDisabledOP) {
this.shiftDown = this.app.keyboard.isPressed(pc.KEY_SHIFT) || btn(9);
} else {
this.shiftDown = false;
}
if (!this.boostDisabledOPbersek) {
const bersekbreak = (this.app.keyboard.isPressed(pc.KEY_SHIFT) && this.app.keyboard.isPressed(pc.KEY_CONTROL) && this.app.keyboard.isPressed(pc.KEY_UP)) || (btn(9) && btn(8) && btn(7));
if (bersekbreak && !this.bersekbooster) {
this.app.fire('bersekboost:active');
this.entity.sound.play('bersekrer');
this.entity.script.thermalVison.enabled = false;
// this.entity.script.fireballAttack.enabled = false; // 🔥 disable fireball
}
if (!bersekbreak && this.bersekbooster) {
this.app.fire('bersekboost:end');
this.entity.sound.play('laugh');
this.entity.script.thermalVison.enabled = true;
// this.entity.script.fireballAttack.enabled = true; // 🔥 enable fireball
}
this.bersekbooster = bersekbreak;
} else {
if (this.bersekbooster) {
this.app.fire('bersekboost:end');
// this.entity.script.fireballAttack.enabled = true; // 🔥 enable fireball
}
this.bersekbooster = false;
}
};
// Audio logic// Audio logic
ControllerAlpha.prototype.handleSoundEffects = function () {
const btn = (index) => this.usingGamepad && this.gamepad.buttons[index]?.pressed;
const deadZone = this.deadzone;
// this.originalAmount = this.playerCam.script.movementBlur.amount;
const axisLX = this.usingGamepad ? this.gamepad.axes[0] : 0;
const axisLY = this.usingGamepad ? this.gamepad.axes[1] : 0;
const axisRX = this.usingGamepad ? this.gamepad.axes[2] : 0;
// const axisRY = this.usingGamepad ? this.gamepad.axes[3] : 0;
if (this.app.keyboard.wasPressed(pc.KEY_W) || (axisLY < -deadZone)) this.entity.sound.play('boost');
if (this.app.keyboard.isPressed(pc.KEY_W) || (axisLY < -deadZone)) this.entity.sound.play('boost');
if (this.app.keyboard.isPressed(pc.KEY_W) || (axisLY < -deadZone)) this.entity.sound.play('boost');
if (this.app.keyboard.wasPressed(pc.KEY_W) || (axisLY < -deadZone)) this.entity.sound.play('up');
if (this.app.keyboard.isPressed(pc.KEY_W) || (axisLY < -deadZone)) this.entity.sound.play('up');
if (this.app.keyboard.wasPressed(pc.KEY_S) || (axisLY > deadZone)) this.entity.sound.play('up');
if (this.app.keyboard.isPressed(pc.KEY_S) || (axisLY > deadZone)) this.entity.sound.play('up');
if (this.leftShift && this.rightShift && this.app.keyboard.isPressed(pc.KEY_UP) || (btn(9) && btn(8) && btn(7))) this.entity.sound.play('bersekrer');
if (this.app.keyboard.wasPressed(pc.KEY_Q) || (axisRX < -deadZone)) this.entity.sound.play('zoom');
if (this.app.keyboard.isPressed(pc.KEY_Q) || (axisRX < -deadZone)) this.entity.sound.play('zoom');
if (this.app.keyboard.isPressed(pc.KEY_E) || (axisRX > deadZone)) this.entity.sound.play('zoom');
if (this.app.keyboard.wasPressed(pc.KEY_E) || (axisRX > deadZone)) this.entity.sound.play('zoom');
if (this.app.keyboard.wasPressed(pc.KEY_SPACE) || btn(0)) this.entity.sound.play('up');
if (this.app.keyboard.isPressed(pc.KEY_SPACE) || btn(0)) this.entity.sound.play('up');
if (this.app.keyboard.wasPressed(pc.KEY_X) || btn(4)) this.entity.sound.play('zoom');
if (this.app.keyboard.isPressed(pc.KEY_X) || btn(4)) this.entity.sound.play('zoom');
// this.playerCam.script.movementBlur.amount = this.originalAmount; // = Start + Select
// this.entity.sound.play('laugh');
};
// Physics & movement logic
ControllerAlpha.prototype.handleFlightPhysics = function (dt) {
const entity = this.entity;
if (!this.can) {
this.resetMotion();
return;
}
if (this.shiftDown && this.engineOn) {
entity.rigidbody.teleport(entity.getPosition(this.entity.translateLocal(0, 0, this.speed / 3)));
this.boost_EXP.particlesystem.reset();
this.boost_EXP.particlesystem.play();
if (this.speed < 23) this.speed += 0.05;
// this.entity.sound.play('boost');
// this.entity.script.fireballAttack.enabled = false; // 🔥 disable fireball
if (this.playerCam && this.playerCam.script && this.playerCam.script.movementBlur) {
this.playerCam.script.movementBlur.amount = this.EventMotionPercent;
}
// this.entity.script.fireballAttack.enabled = true; // 🔥 disable fireball
if (this.playerCam && this.playerCam.script && this.playerCam.script.bokeh) {
this.playerCam.script.bokeh.maxBlur = this.EventBokehPercent;
this.playerCam.script.bokeh.focus = this.EventBokehFOCUSPercent;
this.playerCam.script.bokeh.aperture = 0.5;
}
// this.entity.script.fireballAttack.enabled = false; // 🔥 disable fireball
} else {
// this.entity.sound.stop('boost-ultra');
// 🔥 Reset camera effect when not boosting
if (this.playerCam && this.playerCam.script && this.playerCam.script.movementBlur) {
this.playerCam.script.movementBlur.amount = this.NormalMotionPercent;
}
if (this.playerCam && this.playerCam.script && this.playerCam.script.bokeh) {
this.playerCam.script.bokeh.maxBlur = this.NormalBokehPercent;
this.playerCam.script.bokeh.aperture = 1;
this.playerCam.script.bokeh.focus = 1;
}
// this.entity.script.fireballAttack.enabled = true; // 🔥 disable fireball
}
if (this.shiftDownBoost && this.engineOn) {
entity.rigidbody.teleport(entity.getPosition(this.entity.translateLocal(0, 0, this.speed)));
this.boost_EXP2.particlesystem.reset();
this.boost_EXP2.particlesystem.play();
if (this.speed < 35) this.speed += 0.2;
// this.entity.sound.play('boost-ultra');
// 🔥 Camera effect ON while boosting
if (this.playerCam && this.playerCam.script && this.playerCam.script.movementBlur) {
this.playerCam.script.movementBlur.amount = this.MaxEventMotionPercent;
}
// this.entity.script.fireballAttack.enabled = false; // 🔥 disable fireball
} else {
// this.entity.sound.stop('boost-ultra');
// 🔥 Reset camera effect when not boosting
if (this.playerCam && this.playerCam.script && this.playerCam.script.movementBlur) {
this.playerCam.script.movementBlur.amount = this.NormalMotionPercent;
}
// this.entity.script.fireballAttack.enabled = true; // 🔥 disable fireball
}
if (!this.shiftDown && !this.shiftDownBoost && this.engineOn) {
if (this.speed > 4) this.speed -= 0.1;
if (this.speed < 4) this.speed += 0.15;
// this.entity.sound.play('boost-ultra');
// this.entity.script.fireballAttack.enabled = false; // 🔥 disable fireball
this.app.fire('boost:activeHalf');
} else {
// this.entity.sound.stop('boost-ultra');
this.app.fire('boost:endHalf');
// this.entity.script.fireballAttack.enabled = true; // 🔥 disable fireball
}
if (!this.engineOn && this.speed > 0) {
this.speed -= 0.05;
}
if (this.bersekbooster && this.engineOn) {
entity.rigidbody.teleport(entity.getPosition(this.entity.translateLocal(0, 0, this.speed * 4.2)));
this.bersekBoom.particlesystem.reset();
this.bersekBoom.particlesystem.play();
this.bersekBoom.particlesystem.reset();
this.boost_EXP2.enabled = false;
this.entity.script.thermalVison.enabled = false;
// this.entity.script.fireballAttack.enabled = false; // 🔥 disable fireball
if (this.speed < 50) this.speed += 0.3;
if (this.playerCam && this.playerCam.script && this.playerCam.script.movementBlur) {
this.playerCam.script.movementBlur.amount = this.EventMotionPercent - 0.263;
}
if (this.playerCam && this.playerCam.script && this.playerCam.script.cameraDepthOfField) {
this.playerCam.script.cameraDepthOfField.focusMode = 1.4;
this.playerCam.script.cameraDepthOfField.highlightThreshold = 0.35;
this.playerCam.script.cameraDepthOfField.chromaticAberrationIntensity = 4;
}
if (this.playerCam && this.playerCam.script && this.playerCam.script.postEffectOutline) {
this.playerCam.script.postEffectOutline.enabled = true;
}
if (this.playerCam && this.playerCam.script && this.playerCam.script.hueSaturation) {
this.playerCam.script.hueSaturation.hue = 0;
this.playerCam.script.hueSaturation.saturation = 0.8937;
}
if (this.playerCam && this.playerCam.script && this.playerCam.script.vignette) {
this.playerCam.script.vignette.offset = 1.45;
this.playerCam.script.vignette.darkness = 1;
}
} else {
// 🔥 Reset camera effect when not boosting
if (this.playerCam && this.playerCam.script && this.playerCam.script.movementBlur) {
this.playerCam.script.movementBlur.amount = this.NormalMotionPercent;
}
if (this.playerCam && this.playerCam.script && this.playerCam.script.cameraDepthOfField) {
this.playerCam.script.cameraDepthOfField.focusMode = this.focusMode;
this.playerCam.script.cameraDepthOfField.highlightThreshold = this.highlightThreshold;
this.playerCam.script.cameraDepthOfField.chromaticAberrationIntensity = this.chromaticAberrationIntensity;
}
if (this.playerCam && this.playerCam.script && this.playerCam.script.hueSaturation) {
this.playerCam.script.hueSaturation.hue = this.hue;
this.playerCam.script.hueSaturation.saturation = this.sat;
}
if (this.playerCam && this.playerCam.script && this.playerCam.script.postEffectOutline) {
this.playerCam.script.postEffectOutline.enabled = false;
}
if (this.playerCam && this.playerCam.script && this.playerCam.script.vignette) {
this.playerCam.script.vignette.offset = this.offset;
this.playerCam.script.vignette.darkness = this.darkness;
}
this.entity.script.thermalVison.enabled = true;
// this.entity.script.fireballAttack.enabled = true; // 🔥 disable fireball
this.boost_EXP2.enabled = true;
}
this.applyDirectionalVelocity(dt);
this.applyRotation(dt);
};
// Reset movement
ControllerAlpha.prototype.resetMotion = function () {
this.shiftDown = false;
this.velocityX = this.velocityY = this.velocityZ = 0;
this.speed = 0.0435;
};
// Fire event when boostDisabledOP changes
ControllerAlpha.prototype.updateBoostDisabledOP = function () {
if (this.boostDisabledOPPrev === undefined) this.boostDisabledOPPrev = this.boostDisabledOP;
if (this.boostDisabledOP !== this.boostDisabledOPPrev) {
if (this.boostDisabledOP) {
this.app.fire('boostDisabledOP:active');
} else {
this.app.fire('boostDisabledOP:end');
}
this.boostDisabledOPPrev = this.boostDisabledOP;
}
};
ControllerAlpha.prototype.updateBerserker = function () {
if (this.berserkerOPPrev === undefined) this.berserkerOPPrev = this.bersekbooster;
if (this.bersekbooster !== this.berserkerOPPrev) {
if (this.bersekbooster) {
this.app.fire('bersekboost:active');
} else {
this.app.fire('bersekboost:end');
}
this.berserkerOPPrev = this.bersekbooster;
}
};
// Apply directional velocity
ControllerAlpha.prototype.applyDirectionalVelocity = function () {
if (this.isWDown && !this.isSDown) {
this.Forward_EXP.particlesystem.reset();
this.Forward_EXP.particlesystem.play();
// this.entity.sound.play('up');
this.velocityX = Math.max(this.velocityX - 0.01, -1);
} else if (this.isSDown && !this.isWDown) {
this.velocityX = Math.min(this.velocityX + 0.01, 1);
// this.entity.sound.play('up');
} else {
this.velocityX *= 0.935;
// this.entity.sound.stop('up');
}
if (this.isDDown && !this.isADown) {
// this.entity.sound.play('zoom');
this.velocityZ = Math.min(this.velocityZ + 0.1, 3);
} else if (this.isADown && !this.isDDown) {
// this.entity.sound.play('zoom');
this.velocityZ = Math.max(this.velocityZ - 0.1, -3);
} else {
this.velocityZ *= 0.935;
// this.entity.sound.stop('zoom');
}
if (this.isqdown && !this.isedown) {
// this.entity.sound.play('zoom');
this.velocityY = Math.min(this.velocityY + 0.3, 0.3);
} else if (this.isedown && !this.isqdown) {
// this.entity.sound.play('zoom');
this.velocityY = Math.max(this.velocityY - 0.3, -0.3);
} else {
this.velocityY *= 0.935;
// this.entity.sound.stop('zoom');
}
};
// Apply pitch/roll rotation
ControllerAlpha.prototype.applyRotation = function () {
const entity = this.entity;
if (this.isSpaceDown && !this.isXDown) {
entity.rigidbody.teleport(entity.getPosition(), entity.rotateLocal(-1.45, 0, 0));
// this.entity.sound.play('zoom');
} else if (this.isXDown && !this.isSpaceDown) {
entity.rigidbody.teleport(entity.getPosition(), entity.rotateLocal(1.65, 0, 0));
// this.entity.sound.play('zoom');
} else {
// this.entity.sound.stop('zoom');
}
entity.rigidbody.teleport(entity.getPosition(this.entity.rotateLocal(this.velocityX, this.velocityY, this.velocityZ)));
this.entity.rigidbody.teleport(entity.getPosition(), entity.translateLocal(0, this.force_gravity, 0));
entity.rigidbody.teleport(entity.getPosition(this.entity.translateLocal(0, 0, this.speed / 7)));
};
// UI feedback
ControllerAlpha.prototype.updateUI = function (io) {
this.txtas.element.text = 'SPATIAL METER: ' + Math.floor(this.speed * 50000);
this.txtas.element.color = (this.speed < 1) ? new pc.Color(1, 0, 0) : new pc.Color(0, 1, 0);
if (this.entity.getPosition().y > 100000 || this.entity.getPosition().x > 100000 || this.entity.getPosition().z > 100000) {
this.airsp.element.text = 'LIMIT_BREAKER';
} else {
this.airsp.element.text = 'IN-BOUND';
}
};