Hey folks!
I have a question regarding the Virtual Joystick and GUI buttons. As mentioned in the docs and in this post, you can set the z-index for for the canvas elements, so that buttons can be triggered.
I’m basically trying to replicate the the button as in this playground. I don’t need the function to reset the z-index of the joystick, basically just want the buttons to sit on top of the joystick canvas.
I tried to set the z index for the button but it does not seem to work. Any ideas on what I might be doing wrong?
Here is how I create the buttons:
export class ActionButtons {
private ui: AdvancedDynamicTexture;
// Button press states
public isSprintPressed: boolean = false;
public isJetpackPressed: boolean = false;
public isKickPressed: boolean = false;
constructor() {
this.ui = AdvancedDynamicTexture.CreateFullscreenUI("UI");
// Only create action buttons if the device is a mobile device
if (isMobileDevice()) {
this.createActionButtons();
}
}
private createActionButtons() {
const buttonSize = "60px";
const buttonSpacing = "10px";
// Create sprint button
const sprintButton = Button.CreateImageOnlyButton("sprintButton", "sprinting.png");
sprintButton.width = buttonSize;
sprintButton.height = buttonSize;
sprintButton.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_RIGHT;
sprintButton.verticalAlignment = Control.VERTICAL_ALIGNMENT_BOTTOM;
sprintButton.left = `-${buttonSpacing}`;
sprintButton.top = `-${buttonSpacing}`;
sprintButton.isPointerBlocker = true; // Prevents propagation to joystick
sprintButton.zIndex = 10; // Set a higher z-index for the button
this.ui.addControl(sprintButton);
// Create jetpack button
const jetpackButton = Button.CreateImageOnlyButton("jetpackButton", "jetpacking.png");
jetpackButton.width = buttonSize;
jetpackButton.height = buttonSize;
jetpackButton.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_RIGHT;
jetpackButton.verticalAlignment = Control.VERTICAL_ALIGNMENT_BOTTOM;
jetpackButton.left = `-${parseInt(buttonSpacing) + parseInt(buttonSize) * 2}px`; // Adjust position to not overlap with sprint button
jetpackButton.top = `-${buttonSpacing}`;
jetpackButton.isPointerBlocker = true; // Prevents propagation to joystick
jetpackButton.zIndex = 10; // Set a higher z-index for the button
this.ui.addControl(jetpackButton);
// Create kick button
const kickButton = Button.CreateImageOnlyButton("kickButton", "kicking.png");
kickButton.width = buttonSize;
kickButton.height = buttonSize;
kickButton.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_RIGHT;
kickButton.verticalAlignment = Control.VERTICAL_ALIGNMENT_BOTTOM;
kickButton.left = `-${parseInt(buttonSpacing) + parseInt(buttonSize) * 4}px`; // Adjust position to not overlap with other buttons
kickButton.top = `-${buttonSpacing}`;
kickButton.isPointerBlocker = true; // Prevents propagation to joystick
kickButton.zIndex = 10; // Set a higher z-index for the button
this.ui.addControl(kickButton);
// Add event listeners for the buttons
sprintButton.onPointerDownObservable.add(() => {
console.log("Sprint Button Pressed");
this.isSprintPressed = true;
});
sprintButton.onPointerUpObservable.add(() => {
this.isSprintPressed = false;
});
jetpackButton.onPointerDownObservable.add(() => {
this.isJetpackPressed = true;
});
jetpackButton.onPointerUpObservable.add(() => {
this.isJetpackPressed = false;
});
kickButton.onPointerDownObservable.add(() => {
this.isKickPressed = true;
});
kickButton.onPointerUpObservable.add(() => {
this.isKickPressed = false;
});
}
}
export default ActionButtons;
And this is how I create the the joystick:
import { Vector3, VirtualJoystick } from '@babylonjs/core';
class CustomTouchStick extends VirtualJoystick {
direction: Vector3 = Vector3.Zero();
private directionMaxLength: number = 3;
private directionSensitivity: number = 350;
constructor(isLeftStick: boolean) {
super(isLeftStick);
this.setJoystickSensibility(1);
this.setupListener();
}
private setupListener() {
this.detect();
this.direction = this.getDirection(this.deltaPosition.x, this.deltaPosition.y);
requestAnimationFrame(() => this.setupListener());
}
private detect() {
const { pressed, deltaPosition } = this;
if (pressed) {
this.direction = this.getDirection(deltaPosition.x, deltaPosition.y);
} else {
this.reset();
}
}
private getDirection(deltaX: number, deltaY: number): Vector3 {
const joystickVector = new Vector3(deltaX, 0, deltaY);
if (joystickVector.length() === 0) {
return Vector3.Zero();
}
const scaleFactor = 3;
const scaledLength = Math.pow(joystickVector.length(), scaleFactor) * this.directionSensitivity;
const cappedLength = Math.min(scaledLength, this.directionMaxLength);
return joystickVector.normalize().scale(cappedLength);
}
private reset() {
this.direction = Vector3.Zero();
this.deltaPosition.x = 0;
this.deltaPosition.y = 0;
}
}
export default CustomTouchStick;
Thanks for all the help in advance