Galacean's touch is based on Pointer, which smooths out the differences between Mouse and Touch, making touch unified in both concept and interface.
In Galacean, whether it's a mouse on a PC, a stylus or a finger on a mobile device, when it performs the corresponding behavior within the touch range (Down, Move, etc.), it will be instantiated as a Pointer. You can get all the currently active touch points in the InputManager.
It should be noted that each touch point is independent of each other, they respond to the corresponding events and callback the corresponding hook functions.
Each touch point will start its life in PointerDown or PointerMove, and leave the stage in PointerLeave or PointerCancel. In Galacean, you can get the real-time status of this touch point through Pointer.phase
.
Referring to the W3C standard and Microsoft related documentation, Galacean defines touch buttons as follows:
Enumeration | Explanation |
---|---|
None | No touch button pressed |
Primary | The primary button of the device, usually the left button (mouse) or the only button on a single-button device (finger) |
Secondary | The secondary button of the device, usually the right button (mouse) |
Auxiliary | The auxiliary button of the device, usually the wheel (mouse) |
XButton1 | The extended button of the device, usually the undo button (mouse) |
XButton2 | The extended button of the device, usually the redo button (mouse) |
XButton3 | Extended button |
XButton4 | Extended button |
…… | …… |
Combining touch buttons can easily detect the behavior of touch points triggered in this frame:
You only need to add touch callbacks to an Entity with a Collider component to enable interaction with rendered objects. Touch callbacks are integrated into the engine's script lifecycle, allowing users to easily add the following events. The hook functions will carry the Pointer instance that triggered the callback.
Interface | Trigger Timing and Frequency |
---|---|
onPointerEnter | Triggered once when the touch point enters the Entity's collider range |
onPointerExit | Triggered once when the touch point leaves the Entity's collider range |
onPointerDown | Triggered once when the touch point is pressed within the Entity's collider range |
onPointerUp | Triggered once when the touch point is released within the Entity's collider range |
onPointerClick | Triggered once when the touch point is pressed and released within the Entity's collider range |
onPointerDrag | Continuously triggered when the touch point is pressed within the Entity's collider range until the touch point is no longer pressed |
⚠️ Touch callbacks depend on the physics engine. Please ensure the physics engine is initialized before using this feature.
Example:
Touch callbacks are implemented based on raycasting. Customizing raycasting is also very simple, just follow these steps.
Refer to Collider Component for adding a collider component. The code logic for implementing the detection part is as follows:
// 假设当前有一个活动的触控点
const pointer = inputManager.pointers[0];
// 通过触控点得到由相机发射的射线
const ray = camera.screenPointToRay(pointer.position, new Ray());
// 射线与场景的碰撞体进行碰撞检测
const hitResult = new HitResult();
if (scene.physics.raycast(ray, 100, hitResult)) {
console.log("Hit entity", hitResult.entity);
}
The following example provides a more intuitive understanding of this process. The main camera is equipped with auxiliary lines, and the side view camera can fully observe the process of the main camera's raycasting detecting the collider.
As of February 2024, the compatibility of PointerEvent across different platforms has reached 96.35%.
Design ideas can be referenced at: https://github.com/galacean/engine/wiki/Input-system-design.
⚠️ If you encounter compatibility issues on a platform, you can raise an issue at https://github.com/galacean/polyfill-pointer-event.
On mobile devices, touch interactions trigger the default behavior of HTML elements. Once the default behavior is triggered, the touch interaction is removed from the element (PointerCancel). This can be resolved by setting the touchAction
of the listening source. If the listening source is the default canvas:
(engine.canvas._webCanvas as HTMLCanvasElement).style.touchAction = "none";
This is caused by the default behavior triggered by the right-click. You can add the following code to prevent it:
document.oncontextmenu = (e) => {
e.preventDefault();
};