From 2928e74036541fd2b24f83f73074f162614487d5 Mon Sep 17 00:00:00 2001 From: oahc09 Date: Tue, 26 Sep 2023 14:32:23 +0800 Subject: [PATCH] feat:support xr controller a/b/x/y/trigger/thumbstick touch event (#16293) * feat:support xr controller a/b/x/y/trigger/thumbstick touch event * fix:eslint problem * refactor:add new enum/struct for touch event info --- @types/jsb.d.ts | 6 + .../cocos/bindings/event/EventDispatcher.cpp | 12 ++ native/cocos/engine/EngineEvents.h | 19 +- .../platform/interfaces/modules/XRCommon.h | 34 +++ .../platform/java/modules/XRInterface.cpp | 197 ++++++++++-------- native/cocos/xr/XRRemotePreviewManager.cpp | 27 +++ native/cocos/xr/XRRemotePreviewManager.h | 6 +- pal/input/input-source.ts | 24 ++- pal/input/minigame/handle-input.ts | 35 +++- pal/input/native/handle-input.ts | 177 +++++++++++++--- pal/input/web/handle-input.ts | 109 +++++++++- 11 files changed, 513 insertions(+), 133 deletions(-) diff --git a/@types/jsb.d.ts b/@types/jsb.d.ts index 2c6347e1994..f39aae1ecf2 100644 --- a/@types/jsb.d.ts +++ b/@types/jsb.d.ts @@ -80,6 +80,7 @@ declare namespace jsb { id: number; axisInfoList: AxisInfo[], buttonInfoList: ButtonInfo[], + touchInfoList: TouchInfo[], } export interface AxisInfo { @@ -92,6 +93,11 @@ declare namespace jsb { isPressed: boolean, } + export interface TouchInfo { + code: number, + value: number, + } + export let onControllerInput: (infoList: ControllerInfo[]) => void | undefined; export let onHandleInput: (infoList: ControllerInfo[]) => void | undefined; export let onControllerChange: (controllerIds: number[]) => void | undefined; diff --git a/native/cocos/bindings/event/EventDispatcher.cpp b/native/cocos/bindings/event/EventDispatcher.cpp index dc7f82c4934..9ebc32a28bc 100644 --- a/native/cocos/bindings/event/EventDispatcher.cpp +++ b/native/cocos/bindings/event/EventDispatcher.cpp @@ -332,8 +332,20 @@ void EventDispatcher::dispatchControllerEvent(const ControllerEvent &controllerE jsAxisInfoList->setArrayElement(axisIndex, se::Value(jsAxisInfo)); axisIndex++; } + + se::HandleObject jsTouchInfoList{se::Object::createArrayObject(static_cast(controller->touchInfos.size()))}; + + uint32_t touchIndex = 0; + for (const auto &touchInfo : controller->touchInfos) { + se::HandleObject jsTouchInfo{se::Object::createPlainObject()}; + jsTouchInfo->setProperty("code", se::Value(static_cast(touchInfo.key))); + jsTouchInfo->setProperty("value", se::Value(touchInfo.value)); + jsTouchInfoList->setArrayElement(touchIndex, se::Value(jsTouchInfo)); + touchIndex++; + } jsController->setProperty("axisInfoList", se::Value(jsAxisInfoList)); jsController->setProperty("buttonInfoList", se::Value(jsButtonInfoList)); + jsController->setProperty("touchInfoList", se::Value(jsTouchInfoList)); jsControllerEventArray->setArrayElement(controllerIndex, se::Value(jsController)); controllerIndex++; diff --git a/native/cocos/engine/EngineEvents.h b/native/cocos/engine/EngineEvents.h index e73cbaf4a0b..5e3e7e8e769 100644 --- a/native/cocos/engine/EngineEvents.h +++ b/native/cocos/engine/EngineEvents.h @@ -126,6 +126,18 @@ enum class StickAxisCode { RIGHT_GRIP, }; +enum class StickTouchCode { + UNDEFINE = 0, + A, + B, + X, + Y, + LEFT_TRIGGER, + RIGHT_TRIGGER, + LEFT_THUMBSTICK, + RIGHT_THUMBSTICK, +}; + struct ControllerInfo { struct AxisInfo { StickAxisCode axis{StickAxisCode::UNDEFINE}; @@ -137,10 +149,15 @@ struct ControllerInfo { bool isPress{false}; ButtonInfo(StickKeyCode key, bool isPress) : key(key), isPress(isPress) {} }; - + struct TouchInfo { + StickTouchCode key{StickTouchCode::UNDEFINE}; + float value{0.F}; + TouchInfo(StickTouchCode key, float value) : key(key), value(value) {} + }; int napdId{0}; std::vector axisInfos; std::vector buttonInfos; + std::vector touchInfos; }; struct ControllerEvent { diff --git a/native/cocos/platform/interfaces/modules/XRCommon.h b/native/cocos/platform/interfaces/modules/XRCommon.h index 35a128ae191..682c448c005 100644 --- a/native/cocos/platform/interfaces/modules/XRCommon.h +++ b/native/cocos/platform/interfaces/modules/XRCommon.h @@ -118,6 +118,8 @@ enum class XRConfigKey { EYE_RENDER_JS_CALLBACK = 54, ASYNC_LOAD_ASSETS_IMAGE = 55, ASYNC_LOAD_ASSETS_IMAGE_RESULTS = 56, + LEFT_CONTROLLER_ACTIVE = 57, + RIGHT_CONTROLLER_ACTIVE= 58, MAX_COUNT }; @@ -211,6 +213,7 @@ enum class XREventType { STICK, GRAB, POSE, + TOUCH, UNKNOWN }; @@ -308,6 +311,37 @@ struct XRGrab : public XRControllerInfo { } }; +struct XRTouch : public XRControllerInfo { + enum class Type { + TOUCH_A, + TOUCH_B, + TOUCH_X, + TOUCH_Y, + TOUCH_TRIGGER_LEFT, + TOUCH_TRIGGER_RIGHT, + TOUCH_THUMBSTICK_LEFT, + TOUCH_THUMBSTICK_RIGHT, + UNKNOWN + }; + + bool isActive = false; + float value = 0.F; + Type type = Type::UNKNOWN; + + XRTouch(Type type, bool isActive) + : type(type), + isActive(isActive) {} + + XRTouch(Type type, float value) + : type(type), + isActive(true), + value(value) {} + + XREventType getXREventType() const override { + return XREventType::TOUCH; + } +}; + struct XRPose : public XRControllerInfo { enum class Type { VIEW_LEFT, diff --git a/native/cocos/platform/java/modules/XRInterface.cpp b/native/cocos/platform/java/modules/XRInterface.cpp index cc9981801a0..b6224a9f137 100644 --- a/native/cocos/platform/java/modules/XRInterface.cpp +++ b/native/cocos/platform/java/modules/XRInterface.cpp @@ -87,6 +87,17 @@ const static ccstd::unordered_map GRAB_TYPE_TO_ {xr::XRGrab::Type::GRIP_RIGHT, StickAxisCode::RIGHT_GRIP}, }; +const static ccstd::unordered_map TOUCH_TYPE_TO_AXIS_CODE = { + {xr::XRTouch::Type::TOUCH_A, StickTouchCode::A}, + {xr::XRTouch::Type::TOUCH_B, StickTouchCode::B}, + {xr::XRTouch::Type::TOUCH_X, StickTouchCode::X}, + {xr::XRTouch::Type::TOUCH_Y, StickTouchCode::Y}, + {xr::XRTouch::Type::TOUCH_TRIGGER_LEFT, StickTouchCode::LEFT_TRIGGER}, + {xr::XRTouch::Type::TOUCH_TRIGGER_RIGHT, StickTouchCode::RIGHT_TRIGGER}, + {xr::XRTouch::Type::TOUCH_THUMBSTICK_LEFT, StickTouchCode::LEFT_THUMBSTICK}, + {xr::XRTouch::Type::TOUCH_THUMBSTICK_RIGHT, StickTouchCode::RIGHT_THUMBSTICK}, +}; + void XRInterface::dispatchGamepadEventInternal(const xr::XRControllerEvent &xrControllerEvent) { if (xrControllerEvent.xrControllerInfos.empty()) { return; @@ -102,48 +113,50 @@ void XRInterface::dispatchGamepadEventInternal(const xr::XRControllerEvent &xrCo switch (xrControllerEvent.xrControllerInfos.at(i)->getXREventType()) { case xr::XREventType::CLICK: { auto *xrClick = static_cast(xrControllerEvent.xrControllerInfos.at(i).get()); - StickKeyCode stickKeyCode = CLICK_TYPE_TO_KEY_CODE.at(xrClick->type); - - switch (xrClick->type) { - case xr::XRClick::Type::MENU: - case xr::XRClick::Type::TRIGGER_LEFT: - case xr::XRClick::Type::SHOULDER_LEFT: - case xr::XRClick::Type::THUMBSTICK_LEFT: - case xr::XRClick::Type::X: - case xr::XRClick::Type::Y: - case xr::XRClick::Type::TRIGGER_RIGHT: - case xr::XRClick::Type::SHOULDER_RIGHT: - case xr::XRClick::Type::THUMBSTICK_RIGHT: - case xr::XRClick::Type::A: - case xr::XRClick::Type::B: - case xr::XRClick::Type::START: { - controllerInfo->buttonInfos.emplace_back(ControllerInfo::ButtonInfo(stickKeyCode, xrClick->isPress)); - break; - } - case xr::XRClick::Type::HOME: { - CC_LOG_INFO("[XRInterface] dispatchGamepadEventInternal exit when home click in rokid."); + if(CLICK_TYPE_TO_KEY_CODE.count(xrClick->type) > 0) { + StickKeyCode stickKeyCode = CLICK_TYPE_TO_KEY_CODE.at(xrClick->type); + + switch (xrClick->type) { + case xr::XRClick::Type::MENU: + case xr::XRClick::Type::TRIGGER_LEFT: + case xr::XRClick::Type::SHOULDER_LEFT: + case xr::XRClick::Type::THUMBSTICK_LEFT: + case xr::XRClick::Type::X: + case xr::XRClick::Type::Y: + case xr::XRClick::Type::TRIGGER_RIGHT: + case xr::XRClick::Type::SHOULDER_RIGHT: + case xr::XRClick::Type::THUMBSTICK_RIGHT: + case xr::XRClick::Type::A: + case xr::XRClick::Type::B: + case xr::XRClick::Type::START: { + controllerInfo->buttonInfos.emplace_back(ControllerInfo::ButtonInfo(stickKeyCode, xrClick->isPress)); + break; + } + case xr::XRClick::Type::HOME: { + CC_LOG_INFO("[XRInterface] dispatchGamepadEventInternal exit when home click in rokid."); #if CC_USE_XR - xr::XrEntry::getInstance()->destroyXrInstance(); - xr::XrEntry::destroyInstance(); - _isXrEntryInstanceValid = false; + xr::XrEntry::getInstance()->destroyXrInstance(); + xr::XrEntry::destroyInstance(); + _isXrEntryInstanceValid = false; #endif - CC_CURRENT_APPLICATION_SAFE()->close(); - break; + CC_CURRENT_APPLICATION_SAFE()->close(); + break; + } + case xr::XRClick::Type::DPAD_UP: + controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(StickAxisCode::Y, xrClick->isPress ? 1.F : 0.F)); + break; + case xr::XRClick::Type::DPAD_DOWN: + controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(StickAxisCode::Y, xrClick->isPress ? -1.F : 0.F)); + break; + case xr::XRClick::Type::DPAD_LEFT: + controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(StickAxisCode::X, xrClick->isPress ? -1.F : 0.F)); + break; + case xr::XRClick::Type::DPAD_RIGHT: + controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(StickAxisCode::X, xrClick->isPress ? 1.F : 0.F)); + break; + default: + break; } - case xr::XRClick::Type::DPAD_UP: - controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(StickAxisCode::Y, xrClick->isPress ? 1.F : 0.F)); - break; - case xr::XRClick::Type::DPAD_DOWN: - controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(StickAxisCode::Y, xrClick->isPress ? -1.F : 0.F)); - break; - case xr::XRClick::Type::DPAD_LEFT: - controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(StickAxisCode::X, xrClick->isPress ? -1.F : 0.F)); - break; - case xr::XRClick::Type::DPAD_RIGHT: - controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(StickAxisCode::X, xrClick->isPress ? 1.F : 0.F)); - break; - default: - break; } } break; case xr::XREventType::STICK: { @@ -163,15 +176,17 @@ void XRInterface::dispatchGamepadEventInternal(const xr::XRControllerEvent &xrCo } break; case xr::XREventType::GRAB: { auto *xrGrab = static_cast(xrControllerEvent.xrControllerInfos.at(i).get()); - StickAxisCode stickAxisCode = GRAB_TYPE_TO_AXIS_CODE.at(xrGrab->type); - switch (xrGrab->type) { - case xr::XRGrab::Type::TRIGGER_LEFT: - case xr::XRGrab::Type::TRIGGER_RIGHT: { - controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(stickAxisCode, xrGrab->value)); - break; + if(GRAB_TYPE_TO_AXIS_CODE.count(xrGrab->type) > 0) { + StickAxisCode stickAxisCode = GRAB_TYPE_TO_AXIS_CODE.at(xrGrab->type); + switch (xrGrab->type) { + case xr::XRGrab::Type::TRIGGER_LEFT: + case xr::XRGrab::Type::TRIGGER_RIGHT: { + controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(stickAxisCode, xrGrab->value)); + break; + } + default: + break; } - default: - break; } } break; default: @@ -219,41 +234,43 @@ void XRInterface::dispatchHandleEventInternal(const xr::XRControllerEvent &xrCon switch (xrControllerEvent.xrControllerInfos.at(i)->getXREventType()) { case xr::XREventType::CLICK: { auto *xrClick = static_cast(xrControllerEvent.xrControllerInfos.at(i).get()); - StickKeyCode stickKeyCode = CLICK_TYPE_TO_KEY_CODE.at(xrClick->type); - switch (xrClick->type) { - case xr::XRClick::Type::MENU: { + if(CLICK_TYPE_TO_KEY_CODE.count(xrClick->type) > 0) { + StickKeyCode stickKeyCode = CLICK_TYPE_TO_KEY_CODE.at(xrClick->type); + switch (xrClick->type) { + case xr::XRClick::Type::MENU: { #if !XR_OEM_SEED - controllerInfo->buttonInfos.emplace_back(ControllerInfo::ButtonInfo(StickKeyCode::MENU, xrClick->isPress)); + controllerInfo->buttonInfos.emplace_back(ControllerInfo::ButtonInfo(StickKeyCode::MENU, xrClick->isPress)); #else - CC_LOG_INFO("[XRInterface] exit when menu click in seed."); + CC_LOG_INFO("[XRInterface] exit when menu click in seed."); CC_CURRENT_APPLICATION_SAFE()->close(); #endif - break; - } - case xr::XRClick::Type::TRIGGER_LEFT: - case xr::XRClick::Type::THUMBSTICK_LEFT: - case xr::XRClick::Type::X: - case xr::XRClick::Type::Y: - case xr::XRClick::Type::TRIGGER_RIGHT: - case xr::XRClick::Type::THUMBSTICK_RIGHT: - case xr::XRClick::Type::A: - case xr::XRClick::Type::B: - case xr::XRClick::Type::START: { - controllerInfo->buttonInfos.emplace_back(ControllerInfo::ButtonInfo(stickKeyCode, xrClick->isPress)); - break; - } - case xr::XRClick::Type::HOME: { - CC_LOG_INFO("[XRInterface] dispatchHandleEventInternal exit when home click in rokid."); + break; + } + case xr::XRClick::Type::TRIGGER_LEFT: + case xr::XRClick::Type::THUMBSTICK_LEFT: + case xr::XRClick::Type::X: + case xr::XRClick::Type::Y: + case xr::XRClick::Type::TRIGGER_RIGHT: + case xr::XRClick::Type::THUMBSTICK_RIGHT: + case xr::XRClick::Type::A: + case xr::XRClick::Type::B: + case xr::XRClick::Type::START: { + controllerInfo->buttonInfos.emplace_back(ControllerInfo::ButtonInfo(stickKeyCode, xrClick->isPress)); + break; + } + case xr::XRClick::Type::HOME: { + CC_LOG_INFO("[XRInterface] dispatchHandleEventInternal exit when home click in rokid."); #if CC_USE_XR - xr::XrEntry::getInstance()->destroyXrInstance(); - xr::XrEntry::destroyInstance(); - _isXrEntryInstanceValid = false; + xr::XrEntry::getInstance()->destroyXrInstance(); + xr::XrEntry::destroyInstance(); + _isXrEntryInstanceValid = false; #endif - CC_CURRENT_APPLICATION_SAFE()->close(); - break; + CC_CURRENT_APPLICATION_SAFE()->close(); + break; + } + default: + break; } - default: - break; } } break; case xr::XREventType::STICK: { @@ -273,19 +290,19 @@ void XRInterface::dispatchHandleEventInternal(const xr::XRControllerEvent &xrCon } break; case xr::XREventType::GRAB: { auto *xrGrab = static_cast(xrControllerEvent.xrControllerInfos.at(i).get()); - StickAxisCode stickAxisCode = GRAB_TYPE_TO_AXIS_CODE.at(xrGrab->type); - switch (xrGrab->type) { - case xr::XRGrab::Type::TRIGGER_LEFT: - case xr::XRGrab::Type::TRIGGER_RIGHT: - case xr::XRGrab::Type::GRIP_LEFT: - case xr::XRGrab::Type::GRIP_RIGHT: { - controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(stickAxisCode, xrGrab->value)); - break; - } - default: - break; + if(GRAB_TYPE_TO_AXIS_CODE.count(xrGrab->type) > 0) { + StickAxisCode stickAxisCode = GRAB_TYPE_TO_AXIS_CODE.at(xrGrab->type); + controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(stickAxisCode, xrGrab->value)); } } break; + case xr::XREventType::TOUCH: { + auto *xrTouch = static_cast(xrControllerEvent.xrControllerInfos.at(i).get()); + if(TOUCH_TYPE_TO_AXIS_CODE.count(xrTouch->type) > 0) { + StickTouchCode stickTouchCode = TOUCH_TYPE_TO_AXIS_CODE.at(xrTouch->type); + controllerInfo->touchInfos.emplace_back(ControllerInfo::TouchInfo(stickTouchCode, xrTouch->value)); + } + break; + } case xr::XREventType::POSE: { auto *xrPose = static_cast(xrControllerEvent.xrControllerInfos.at(i).get()); switch (xrPose->type) { @@ -325,7 +342,7 @@ void XRInterface::dispatchHandleEventInternal(const xr::XRControllerEvent &xrCon EventDispatcher::doDispatchJsEvent("onHandlePoseInput", args); } - if (!controllerInfo->buttonInfos.empty() || !controllerInfo->axisInfos.empty()) { + if (!controllerInfo->buttonInfos.empty() || !controllerInfo->axisInfos.empty() || !controllerInfo->touchInfos.empty()) { controllerInfo->napdId = 0; // xr only one handle connection _controllerEvent.controllerInfos.emplace_back(controllerInfo); _controllerEvent.type = ControllerEvent::Type::HANDLE; @@ -342,6 +359,12 @@ void XRInterface::dispatchHandleEventInternal(const xr::XRControllerEvent &xrCon _xrRemotePreviewManager->sendControllerKeyInfo(axisInfo); } } + + if (!controllerInfo->touchInfos.empty()) { + for (const auto &touchInfo : controllerInfo->touchInfos) { + _xrRemotePreviewManager->sendControllerKeyInfo(touchInfo); + } + } } #endif events::Controller::broadcast(_controllerEvent); diff --git a/native/cocos/xr/XRRemotePreviewManager.cpp b/native/cocos/xr/XRRemotePreviewManager.cpp index a2f598872cf..228fd44d461 100644 --- a/native/cocos/xr/XRRemotePreviewManager.cpp +++ b/native/cocos/xr/XRRemotePreviewManager.cpp @@ -316,6 +316,33 @@ void XRRemotePreviewManager::sendControllerKeyInfo(const ControllerInfo::AxisInf #endif } +void XRRemotePreviewManager::sendControllerKeyInfo(const ControllerInfo::TouchInfo &info) { +#if CC_USE_WEBSOCKET_SERVER + if (_webSocketServer && _isConnectionChanged) { + _isConnectionChanged = false; + _wssConnections = _webSocketServer->getConnections(); + } + + if (_webSocketServer && !_wssConnections.empty()) { + for (auto &wssConn : _wssConnections) { + if (wssConn->getReadyState() == WebSocketServerConnection::ReadyState::OPEN) { + XRControllerKeyInfo ctrlKeyInfo; + ctrlKeyInfo.type = static_cast(XRDataPackageType::DPT_MSG_CONTROLLER_KEY); + ctrlKeyInfo.stickTouchValue = info.value; + ctrlKeyInfo.stickTouchCode = static_cast(info.key); + ctrlKeyInfo.keyEventType = static_cast(XRKeyEventType::KET_TOUCH); + size_t dataLen = 8 + sizeof(ctrlKeyInfo); + char data[dataLen]; + packControllerKeyData(ctrlKeyInfo, data); + wssConn->sendBinaryAsync(data, dataLen, nullptr); + } else { + CC_LOG_ERROR("[XRRemotePreviewManager] sendControllerTouchInfo failed !!!"); + } + } + } +#endif +} + void XRRemotePreviewManager::resume() { CC_LOG_INFO("[XRRemotePreviewManager] resume"); sendMessage("resume"); diff --git a/native/cocos/xr/XRRemotePreviewManager.h b/native/cocos/xr/XRRemotePreviewManager.h index 02ba00b0c40..185c2dfd9a8 100644 --- a/native/cocos/xr/XRRemotePreviewManager.h +++ b/native/cocos/xr/XRRemotePreviewManager.h @@ -47,7 +47,8 @@ enum class XRDataPackageType { enum class XRKeyEventType { KET_CLICK, KET_STICK, - KET_GRAB + KET_GRAB, + KET_TOUCH, }; #pragma pack(1) @@ -88,6 +89,8 @@ struct XRControllerKeyInfo { float stickAxisValue{0}; int16_t stickKeyCode{0}; bool isButtonPressed{false}; + int16_t stickTouchCode{0}; + float stickTouchValue{0}; }; #pragma pack() @@ -100,6 +103,7 @@ class XRRemotePreviewManager : public RefCounted { void sendPoseInfo(const XRPoseInfo &info); void sendControllerKeyInfo(const ControllerInfo::ButtonInfo &info); void sendControllerKeyInfo(const ControllerInfo::AxisInfo &info); + void sendControllerKeyInfo(const ControllerInfo::TouchInfo &info); void tick(); void resume(); void pause(); diff --git a/pal/input/input-source.ts b/pal/input/input-source.ts index 408396d6ecd..aada2c3a017 100644 --- a/pal/input/input-source.ts +++ b/pal/input/input-source.ts @@ -83,7 +83,7 @@ export class InputSourceAxis3D extends InputSource { * @en The class for input source of Quaternion, which is used to control the input signal of a mono input source * @zh 四元数的 InputSource 类,该类用于控制单一输入源的输入信号 */ - export class InputSourceQuat extends InputSource { +export class InputSourceQuat extends InputSource { /** * @en Get the signal value of the input source, which returns a Quat object. * @zh 获取输入源的信号值,该方法返回一个 Quat 对象 @@ -288,12 +288,12 @@ export class InputSourceStick extends CompositeInputSourceAxis2D { * @en The class for input source of orientation, whose input signal value a Quat object * @zh 方向输入源类, 输入信号源的取值是一个 Quat 对象 */ - export class InputSourceOrientation extends InputSourceQuat { +export class InputSourceOrientation extends InputSourceQuat { /** * @en Get the signal value of the input source, which returns a Quat object. * @zh 获取输入源的信号值,该方法返回一个 Quat 对象 */ - getValue (): Quat { + getValue (): Quat { return super.getValue(); } } @@ -302,12 +302,26 @@ export class InputSourceStick extends CompositeInputSourceAxis2D { * @en The class for input source of position, whose input signal value a Vec3 object * @zh 坐标输入源类, 输入信号源的取值是一个 Vec3 对象 */ - export class InputSourcePosition extends InputSourceAxis3D { +export class InputSourcePosition extends InputSourceAxis3D { /** * @en Get the signal value of the input source, which returns a Vec3 object. * @zh 获取输入源的信号值,该方法返回一个 Vec3 对象 */ - getValue (): Vec3 { + getValue (): Vec3 { + return super.getValue(); + } +} + +/** + * @en The class for input source of mono button touch, whose input signal value is ranged from 0 or 1 + * @zh 单一按键触摸输入源类, 输入信号源的取值范围是 0 或 1 + */ +export class InputSourceTouch extends InputSourceAxis1D { + /** + * @en Get the signal value of the input source, ranged from 0 or 1 + * @zh 获取输入源的信号值,取值范围从 0 或 1 + */ + getValue (): number { return super.getValue(); } } diff --git a/pal/input/minigame/handle-input.ts b/pal/input/minigame/handle-input.ts index d154220753a..6de6ea3259e 100644 --- a/pal/input/minigame/handle-input.ts +++ b/pal/input/minigame/handle-input.ts @@ -25,7 +25,7 @@ import { HandleCallback } from 'pal/input'; import { InputEventType } from '../../../cocos/input/types/event-enum'; import { EventTarget } from '../../../cocos/core/event'; -import { InputSourceButton, InputSourceStick, InputSourcePosition, InputSourceOrientation } from '../input-source'; +import { InputSourceButton, InputSourceStick, InputSourcePosition, InputSourceOrientation, InputSourceTouch } from '../input-source'; import { Vec3, Quat } from '../../../cocos/core/math'; export class HandleInputDevice { @@ -53,6 +53,14 @@ export class HandleInputDevice { public get aimLeftOrientation (): InputSourceOrientation { return this._aimLeftOrientation; } public get aimRightPosition (): InputSourcePosition { return this._aimRightPosition; } public get aimRightOrientation (): InputSourceOrientation { return this._aimRightOrientation; } + public get touchButtonA (): InputSourceTouch { return this._touchButtonA; } + public get touchButtonB (): InputSourceTouch { return this._touchButtonB; } + public get touchButtonX (): InputSourceTouch { return this._touchButtonX; } + public get touchButtonY (): InputSourceTouch { return this._touchButtonY; } + public get touchButtonTriggerLeft (): InputSourceTouch { return this._touchButtonTriggerLeft; } + public get touchButtonTriggerRight (): InputSourceTouch { return this._touchButtonTriggerRight; } + public get touchButtonThumbStickLeft (): InputSourceTouch { return this._touchButtonThumbStickLeft; } + public get touchButtonThumbStickRight (): InputSourceTouch { return this._touchButtonThumbStickRight; } private _eventTarget: EventTarget = new EventTarget(); @@ -80,6 +88,14 @@ export class HandleInputDevice { private _aimLeftOrientation!: InputSourceOrientation; private _aimRightPosition!: InputSourcePosition; private _aimRightOrientation!: InputSourceOrientation; + private _touchButtonA!: InputSourceTouch; + private _touchButtonB!: InputSourceTouch; + private _touchButtonX!: InputSourceTouch; + private _touchButtonY!: InputSourceTouch; + private _touchButtonTriggerLeft!: InputSourceTouch; + private _touchButtonTriggerRight!: InputSourceTouch; + private _touchButtonThumbStickLeft!: InputSourceTouch; + private _touchButtonThumbStickRight!: InputSourceTouch; constructor () { this._initInputSource(); @@ -163,5 +179,22 @@ export class HandleInputDevice { this._aimRightPosition.getValue = (): Readonly => Vec3.ZERO; this._aimRightOrientation = new InputSourceOrientation(); this._aimRightOrientation.getValue = (): Readonly => Quat.IDENTITY; + + this._touchButtonA = new InputSourceTouch(); + this._touchButtonA.getValue = (): number => 0; + this._touchButtonB = new InputSourceTouch(); + this._touchButtonB.getValue = (): number => 0; + this._touchButtonX = new InputSourceTouch(); + this._touchButtonX.getValue = (): number => 0; + this._touchButtonY = new InputSourceTouch(); + this._touchButtonY.getValue = (): number => 0; + this._touchButtonTriggerLeft = new InputSourceTouch(); + this._touchButtonTriggerLeft.getValue = (): number => 0; + this._touchButtonTriggerRight = new InputSourceTouch(); + this._touchButtonTriggerRight.getValue = (): number => 0; + this._touchButtonThumbStickLeft = new InputSourceTouch(); + this._touchButtonThumbStickLeft.getValue = (): number => 0; + this._touchButtonThumbStickRight = new InputSourceTouch(); + this._touchButtonThumbStickRight.getValue = (): number => 0; } } diff --git a/pal/input/native/handle-input.ts b/pal/input/native/handle-input.ts index ebca8523ead..c5f9f043f42 100644 --- a/pal/input/native/handle-input.ts +++ b/pal/input/native/handle-input.ts @@ -25,7 +25,7 @@ import { InputEventType } from '../../../cocos/input/types/event-enum'; import { EventTarget } from '../../../cocos/core/event/event-target'; import { EventHandle } from '../../../cocos/input/types'; -import { InputSourceButton, InputSourceStick, InputSourcePosition, InputSourceOrientation } from '../input-source'; +import { InputSourceButton, InputSourceStick, InputSourcePosition, InputSourceOrientation, InputSourceTouch } from '../input-source'; import { Vec3, Quat } from '../../../cocos/core/math'; export type HandleCallback = (res: EventHandle) => void; @@ -62,12 +62,57 @@ enum Pose { AIM_RIGHT, } +enum StickKeyCode { + UNDEFINE = 0, + A, + B, + X, + Y, + L1, + R1, + MINUS, + PLUS, + L3, + R3, + MENU, + START, + TRIGGER_LEFT, + TRIGGER_RIGHT, +} + +enum StickAxisCode { + UNDEFINE = 0, + X, + Y, + LEFT_STICK_X, + LEFT_STICK_Y, + RIGHT_STICK_X, + RIGHT_STICK_Y, + L2, + R2, + LEFT_GRIP, + RIGHT_GRIP, +} + +enum StickTouchCode { + UNDEFINE = 0, + A, + B, + X, + Y, + LEFT_TRIGGER, + RIGHT_TRIGGER, + LEFT_THUMBSTICK, + RIGHT_THUMBSTICK, +} + interface IPoseValue { position: Vec3; orientation: Quat; } type NativeButtonState = Record +type NativeTouchState = Record type NativePoseState = Record const _nativeButtonMap = { @@ -113,6 +158,14 @@ export class HandleInputDevice { public get aimLeftOrientation (): InputSourceOrientation { return this._aimLeftOrientation; } public get aimRightPosition (): InputSourcePosition { return this._aimRightPosition; } public get aimRightOrientation (): InputSourceOrientation { return this._aimRightOrientation; } + public get touchButtonA (): InputSourceTouch { return this._touchButtonA; } + public get touchButtonB (): InputSourceTouch { return this._touchButtonB; } + public get touchButtonX (): InputSourceTouch { return this._touchButtonX; } + public get touchButtonY (): InputSourceTouch { return this._touchButtonY; } + public get touchButtonTriggerLeft (): InputSourceTouch { return this._touchButtonTriggerLeft; } + public get touchButtonTriggerRight (): InputSourceTouch { return this._touchButtonTriggerRight; } + public get touchButtonThumbStickLeft (): InputSourceTouch { return this._touchButtonThumbStickLeft; } + public get touchButtonThumbStickRight (): InputSourceTouch { return this._touchButtonThumbStickRight; } private _eventTarget: EventTarget = new EventTarget(); @@ -140,6 +193,14 @@ export class HandleInputDevice { private _aimLeftOrientation!: InputSourceOrientation; private _aimRightPosition!: InputSourcePosition; private _aimRightOrientation!: InputSourceOrientation; + private _touchButtonA!: InputSourceTouch; + private _touchButtonB!: InputSourceTouch; + private _touchButtonX!: InputSourceTouch; + private _touchButtonY!: InputSourceTouch; + private _touchButtonTriggerLeft!: InputSourceTouch; + private _touchButtonTriggerRight!: InputSourceTouch; + private _touchButtonThumbStickLeft!: InputSourceTouch; + private _touchButtonThumbStickRight!: InputSourceTouch; private _nativeButtonState: NativeButtonState = { [Button.BUTTON_SOUTH]: 0, @@ -166,12 +227,24 @@ export class HandleInputDevice { [Button.ROKID_START]: 0, }; + private _nativeTouchState: NativeTouchState = { + [StickTouchCode.UNDEFINE]: 0, + [StickTouchCode.A]: 0, + [StickTouchCode.B]: 0, + [StickTouchCode.X]: 0, + [StickTouchCode.Y]: 0, + [StickTouchCode.LEFT_TRIGGER]: 0, + [StickTouchCode.RIGHT_TRIGGER]: 0, + [StickTouchCode.LEFT_THUMBSTICK]: 0, + [StickTouchCode.RIGHT_THUMBSTICK]: 0, + }; + private _nativePoseState: NativePoseState = { [Pose.HAND_LEFT]: { position: Vec3.ZERO, orientation: Quat.IDENTITY }, [Pose.HAND_RIGHT]: { position: Vec3.ZERO, orientation: Quat.IDENTITY }, [Pose.AIM_LEFT]: { position: Vec3.ZERO, orientation: Quat.IDENTITY }, [Pose.AIM_RIGHT]: { position: Vec3.ZERO, orientation: Quat.IDENTITY }, - } + }; constructor () { this._initInputSource(); @@ -215,7 +288,7 @@ export class HandleInputDevice { } private _updateNativeButtonState (info: jsb.ControllerInfo): void { - const { buttonInfoList, axisInfoList } = info; + const { buttonInfoList, axisInfoList, touchInfoList } = info; for (let i = 0; i < buttonInfoList.length; ++i) { const buttonInfo = buttonInfoList[i]; const button = _nativeButtonMap[buttonInfo.code]; @@ -228,36 +301,39 @@ export class HandleInputDevice { let positiveButton: Button | undefined; let axisValue: IAxisValue | undefined; switch (code) { - case 3: + case StickAxisCode.LEFT_STICK_X: negativeButton = Button.LEFT_STICK_LEFT; positiveButton = Button.LEFT_STICK_RIGHT; axisValue = this._axisToButtons(value); break; - case 4: + case StickAxisCode.LEFT_STICK_Y: negativeButton = Button.LEFT_STICK_DOWN; positiveButton = Button.LEFT_STICK_UP; axisValue = this._axisToButtons(value); break; - case 5: + case StickAxisCode.RIGHT_STICK_X: negativeButton = Button.RIGHT_STICK_LEFT; positiveButton = Button.RIGHT_STICK_RIGHT; axisValue = this._axisToButtons(value); break; - case 6: + case StickAxisCode.RIGHT_STICK_Y: negativeButton = Button.RIGHT_STICK_DOWN; positiveButton = Button.RIGHT_STICK_UP; axisValue = this._axisToButtons(value); break; + case StickAxisCode.L2: + this._nativeButtonState[Button.TRIGGER_LEFT] = value; + break; + case StickAxisCode.R2: + this._nativeButtonState[Button.TRIGGER_RIGHT] = value; + break; + case StickAxisCode.LEFT_GRIP: + this._nativeButtonState[Button.GRIP_LEFT] = value; + break; + case StickAxisCode.RIGHT_GRIP: + this._nativeButtonState[Button.GRIP_RIGHT] = value; + break; default: - if (code === 7) { - this._nativeButtonState[Button.TRIGGER_LEFT] = value; - } else if (code === 8) { - this._nativeButtonState[Button.TRIGGER_RIGHT] = value; - } else if (code === 9) { - this._nativeButtonState[Button.GRIP_LEFT] = value; - } else if (code === 10) { - this._nativeButtonState[Button.GRIP_RIGHT] = value; - } break; } if (negativeButton && positiveButton && axisValue) { @@ -265,24 +341,49 @@ export class HandleInputDevice { this._nativeButtonState[positiveButton] = axisValue.positive; } } + + if (touchInfoList) { + for (let i = 0; i < touchInfoList.length; ++i) { + const touchInfo = touchInfoList[i]; + const { code, value } = touchInfo; + switch (code) { + case StickTouchCode.A: + case StickTouchCode.B: + case StickTouchCode.X: + case StickTouchCode.Y: + case StickTouchCode.LEFT_TRIGGER: + case StickTouchCode.RIGHT_TRIGGER: + case StickTouchCode.LEFT_THUMBSTICK: + case StickTouchCode.RIGHT_THUMBSTICK: + this._nativeTouchState[code] = value; + break; + default: + break; + } + } + } } private _updateNativePoseState (info: jsb.PoseInfo): void { switch (info.code) { - case 1: - this._nativePoseState[Pose.HAND_LEFT] = { position: new Vec3(info.x, info.y, info.z), orientation: new Quat(info.quaternionX, info.quaternionY, info.quaternionZ, info.quaternionW) }; - break; - case 2: - this._nativePoseState[Pose.AIM_LEFT] = { position: new Vec3(info.x, info.y, info.z), orientation: new Quat(info.quaternionX, info.quaternionY, info.quaternionZ, info.quaternionW) }; - break; - case 4: - this._nativePoseState[Pose.HAND_RIGHT] = { position: new Vec3(info.x, info.y, info.z), orientation: new Quat(info.quaternionX, info.quaternionY, info.quaternionZ, info.quaternionW) }; - break; - case 5: - this._nativePoseState[Pose.AIM_RIGHT] = { position: new Vec3(info.x, info.y, info.z), orientation: new Quat(info.quaternionX, info.quaternionY, info.quaternionZ, info.quaternionW) }; - break; - default: - break; + case 1: + this._nativePoseState[Pose.HAND_LEFT] = { position: new Vec3(info.x, info.y, info.z), + orientation: new Quat(info.quaternionX, info.quaternionY, info.quaternionZ, info.quaternionW) }; + break; + case 2: + this._nativePoseState[Pose.AIM_LEFT] = { position: new Vec3(info.x, info.y, info.z), + orientation: new Quat(info.quaternionX, info.quaternionY, info.quaternionZ, info.quaternionW) }; + break; + case 4: + this._nativePoseState[Pose.HAND_RIGHT] = { position: new Vec3(info.x, info.y, info.z), + orientation: new Quat(info.quaternionX, info.quaternionY, info.quaternionZ, info.quaternionW) }; + break; + case 5: + this._nativePoseState[Pose.AIM_RIGHT] = { position: new Vec3(info.x, info.y, info.z), + orientation: new Quat(info.quaternionX, info.quaternionY, info.quaternionZ, info.quaternionW) }; + break; + default: + break; } } @@ -357,5 +458,21 @@ export class HandleInputDevice { this._aimRightPosition.getValue = (): Vec3 => this._nativePoseState[Pose.AIM_RIGHT].position; this._aimRightOrientation = new InputSourceOrientation(); this._aimRightOrientation.getValue = (): Quat => this._nativePoseState[Pose.AIM_RIGHT].orientation; + this._touchButtonA = new InputSourceTouch(); + this._touchButtonA.getValue = (): number => this._nativeTouchState[StickTouchCode.A]; + this._touchButtonB = new InputSourceTouch(); + this._touchButtonB.getValue = (): number => this._nativeTouchState[StickTouchCode.B]; + this._touchButtonX = new InputSourceTouch(); + this._touchButtonX.getValue = (): number => this._nativeTouchState[StickTouchCode.X]; + this._touchButtonY = new InputSourceTouch(); + this._touchButtonY.getValue = (): number => this._nativeTouchState[StickTouchCode.Y]; + this._touchButtonTriggerLeft = new InputSourceTouch(); + this._touchButtonTriggerLeft.getValue = (): number => this._nativeTouchState[StickTouchCode.LEFT_TRIGGER]; + this._touchButtonTriggerRight = new InputSourceTouch(); + this._touchButtonTriggerRight.getValue = (): number => this._nativeTouchState[StickTouchCode.RIGHT_TRIGGER]; + this._touchButtonThumbStickLeft = new InputSourceTouch(); + this._touchButtonThumbStickLeft.getValue = (): number => this._nativeTouchState[StickTouchCode.LEFT_THUMBSTICK]; + this._touchButtonThumbStickRight = new InputSourceTouch(); + this._touchButtonThumbStickRight.getValue = (): number => this._nativeTouchState[StickTouchCode.RIGHT_THUMBSTICK]; } } diff --git a/pal/input/web/handle-input.ts b/pal/input/web/handle-input.ts index d89608c3498..b5e8ae13f67 100644 --- a/pal/input/web/handle-input.ts +++ b/pal/input/web/handle-input.ts @@ -26,7 +26,7 @@ import { HandleCallback } from 'pal/input'; import { InputEventType } from '../../../cocos/input/types/event-enum'; import { EventTarget } from '../../../cocos/core/event'; import { EventHandle } from '../../../cocos/input/types'; -import { InputSourceButton, InputSourceStick, InputSourcePosition, InputSourceOrientation } from '../input-source'; +import { InputSourceButton, InputSourceStick, InputSourcePosition, InputSourceOrientation, InputSourceTouch } from '../input-source'; import { Vec3, Quat } from '../../../cocos/core/math'; enum Button { @@ -57,7 +57,26 @@ enum Button { export enum KeyEventType { KET_CLICK, KET_STICK, - KET_GRAB + KET_GRAB, + KET_TOUCH, +} + +enum StickKeyCode { + UNDEFINE = 0, + A, + B, + X, + Y, + L1, + R1, + MINUS, + PLUS, + L3, + R3, + MENU, + START, + TRIGGER_LEFT, + TRIGGER_RIGHT, } enum StickAxisCode { @@ -68,12 +87,24 @@ enum StickAxisCode { LEFT_STICK_Y, RIGHT_STICK_X, RIGHT_STICK_Y, - LEFT_TRIGGER, - RIGHT_TIRGGER, + L2, + R2, LEFT_GRIP, RIGHT_GRIP, } +enum StickTouchCode { + UNDEFINE = 0, + A, + B, + X, + Y, + LEFT_TRIGGER, + RIGHT_TRIGGER, + LEFT_THUMBSTICK, + RIGHT_THUMBSTICK, +} + const _nativeButtonMap = { 1: Button.BUTTON_EAST, 2: Button.BUTTON_SOUTH, @@ -93,6 +124,7 @@ interface IAxisValue { } type NativeButtonState = Record +type NativeTouchState = Record export class HandleInputDevice { public get buttonNorth (): InputSourceButton { return this._buttonNorth; } @@ -119,6 +151,14 @@ export class HandleInputDevice { public get aimLeftOrientation (): InputSourceOrientation { return this._aimLeftOrientation; } public get aimRightPosition (): InputSourcePosition { return this._aimRightPosition; } public get aimRightOrientation (): InputSourceOrientation { return this._aimRightOrientation; } + public get touchButtonA (): InputSourceTouch { return this._touchButtonA; } + public get touchButtonB (): InputSourceTouch { return this._touchButtonB; } + public get touchButtonX (): InputSourceTouch { return this._touchButtonX; } + public get touchButtonY (): InputSourceTouch { return this._touchButtonY; } + public get touchButtonTriggerLeft (): InputSourceTouch { return this._touchButtonTriggerLeft; } + public get touchButtonTriggerRight (): InputSourceTouch { return this._touchButtonTriggerRight; } + public get touchButtonThumbStickLeft (): InputSourceTouch { return this._touchButtonThumbStickLeft; } + public get touchButtonThumbStickRight (): InputSourceTouch { return this._touchButtonThumbStickRight; } private _eventTarget: EventTarget = new EventTarget(); @@ -146,6 +186,14 @@ export class HandleInputDevice { private _aimLeftOrientation!: InputSourceOrientation; private _aimRightPosition!: InputSourcePosition; private _aimRightOrientation!: InputSourceOrientation; + private _touchButtonA!: InputSourceTouch; + private _touchButtonB!: InputSourceTouch; + private _touchButtonX!: InputSourceTouch; + private _touchButtonY!: InputSourceTouch; + private _touchButtonTriggerLeft!: InputSourceTouch; + private _touchButtonTriggerRight!: InputSourceTouch; + private _touchButtonThumbStickLeft!: InputSourceTouch; + private _touchButtonThumbStickRight!: InputSourceTouch; private _nativeButtonState: NativeButtonState = { [Button.BUTTON_SOUTH]: 0, @@ -172,15 +220,29 @@ export class HandleInputDevice { [Button.ROKID_START]: 0, }; + private _nativeTouchState: NativeTouchState = { + [StickTouchCode.UNDEFINE]: 0, + [StickTouchCode.A]: 0, + [StickTouchCode.B]: 0, + [StickTouchCode.X]: 0, + [StickTouchCode.Y]: 0, + [StickTouchCode.LEFT_TRIGGER]: 0, + [StickTouchCode.RIGHT_TRIGGER]: 0, + [StickTouchCode.LEFT_THUMBSTICK]: 0, + [StickTouchCode.RIGHT_THUMBSTICK]: 0, + }; + constructor () { this._initInputSource(); window.addEventListener('xr-remote-input', (evt: Event): void => { const remoteInputEvent: CustomEvent = evt as CustomEvent; const keyEventType: KeyEventType = remoteInputEvent.detail.keyEventType; - const stickAxisCode = remoteInputEvent.detail.stickAxisCode; - const stickAxisValue = remoteInputEvent.detail.stickAxisValue; + const stickAxisCode = remoteInputEvent.detail.stickAxisCode as StickAxisCode; + const stickAxisValue = remoteInputEvent.detail.stickAxisValue as number; const stickKeyCode = remoteInputEvent.detail.stickKeyCode; const isButtonPressed = remoteInputEvent.detail.isButtonPressed; + const touchCode = remoteInputEvent.detail.touchCode as StickTouchCode; + const touchValue = remoteInputEvent.detail.touchValue as number; if (keyEventType === KeyEventType.KET_CLICK) { const button = _nativeButtonMap[stickKeyCode]; @@ -211,10 +273,10 @@ export class HandleInputDevice { positiveButton = Button.RIGHT_STICK_UP; axisValue = this._axisToButtons(stickAxisValue); break; - case StickAxisCode.LEFT_TRIGGER: + case StickAxisCode.L2: this._nativeButtonState[Button.TRIGGER_LEFT] = stickAxisValue; break; - case StickAxisCode.RIGHT_TIRGGER: + case StickAxisCode.R2: this._nativeButtonState[Button.TRIGGER_RIGHT] = stickAxisValue; break; case StickAxisCode.LEFT_GRIP: @@ -231,6 +293,21 @@ export class HandleInputDevice { this._nativeButtonState[negativeButton] = axisValue.negative; this._nativeButtonState[positiveButton] = axisValue.positive; } + } else if (keyEventType === KeyEventType.KET_TOUCH) { + switch (touchCode) { + case StickTouchCode.A: + case StickTouchCode.B: + case StickTouchCode.X: + case StickTouchCode.Y: + case StickTouchCode.LEFT_TRIGGER: + case StickTouchCode.RIGHT_TRIGGER: + case StickTouchCode.LEFT_THUMBSTICK: + case StickTouchCode.RIGHT_THUMBSTICK: + this._nativeTouchState[touchCode] = touchValue; + break; + default: + break; + } } this._eventTarget.emit(InputEventType.HANDLE_INPUT, new EventHandle(InputEventType.HANDLE_INPUT, this)); @@ -336,5 +413,21 @@ export class HandleInputDevice { this._aimRightPosition.getValue = (): Readonly => Vec3.ZERO; this._aimRightOrientation = new InputSourceOrientation(); this._aimRightOrientation.getValue = (): Readonly => Quat.IDENTITY; + this._touchButtonA = new InputSourceTouch(); + this._touchButtonA.getValue = (): number => this._nativeTouchState[StickTouchCode.A]; + this._touchButtonB = new InputSourceTouch(); + this._touchButtonB.getValue = (): number => this._nativeTouchState[StickTouchCode.B]; + this._touchButtonX = new InputSourceTouch(); + this._touchButtonX.getValue = (): number => this._nativeTouchState[StickTouchCode.X]; + this._touchButtonY = new InputSourceTouch(); + this._touchButtonY.getValue = (): number => this._nativeTouchState[StickTouchCode.Y]; + this._touchButtonTriggerLeft = new InputSourceTouch(); + this._touchButtonTriggerLeft.getValue = (): number => this._nativeTouchState[StickTouchCode.LEFT_TRIGGER]; + this._touchButtonTriggerRight = new InputSourceTouch(); + this._touchButtonTriggerRight.getValue = (): number => this._nativeTouchState[StickTouchCode.RIGHT_TRIGGER]; + this._touchButtonThumbStickLeft = new InputSourceTouch(); + this._touchButtonThumbStickLeft.getValue = (): number => this._nativeTouchState[StickTouchCode.LEFT_THUMBSTICK]; + this._touchButtonThumbStickRight = new InputSourceTouch(); + this._touchButtonThumbStickRight.getValue = (): number => this._nativeTouchState[StickTouchCode.RIGHT_THUMBSTICK]; } }