@quenty/inputobjectutils 4.29.0-canary.678.24427877603.0 → 4.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
## [4.29.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/inputobjectutils@4.29.0...@quenty/inputobjectutils@4.29.1) (2026-04-29)
|
|
7
7
|
|
|
8
8
|
**Note:** Version bump only for package @quenty/inputobjectutils
|
|
9
9
|
|
|
@@ -11,6 +11,22 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
# [4.29.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/inputobjectutils@4.28.0...@quenty/inputobjectutils@4.29.0) (2026-04-23)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* Fix dependencies list ([776b270](https://github.com/Quenty/NevermoreEngine/commit/776b2700b97d877b70c487d2f47092bacc373e7a))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
|
|
24
|
+
* Additional improvments ([44896ef](https://github.com/Quenty/NevermoreEngine/commit/44896efe8dd9506ad6002bc41f816b9b2b482ebc))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
14
30
|
# [4.28.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/inputobjectutils@4.27.0...@quenty/inputobjectutils@4.28.0) (2026-04-14)
|
|
15
31
|
|
|
16
32
|
**Note:** Version bump only for package @quenty/inputobjectutils
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/inputobjectutils",
|
|
3
|
-
"version": "4.29.
|
|
3
|
+
"version": "4.29.1",
|
|
4
4
|
"description": "Provides utility functions involving input objects",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -31,11 +31,12 @@
|
|
|
31
31
|
"access": "public"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@quenty/baseobject": "10.
|
|
35
|
-
"@quenty/loader": "10.
|
|
36
|
-
"@quenty/maid": "3.
|
|
37
|
-
"@quenty/rx": "13.28.
|
|
38
|
-
"@quenty/rxsignal": "7.28.
|
|
34
|
+
"@quenty/baseobject": "10.13.0",
|
|
35
|
+
"@quenty/loader": "10.11.0",
|
|
36
|
+
"@quenty/maid": "3.9.0",
|
|
37
|
+
"@quenty/rx": "13.28.1",
|
|
38
|
+
"@quenty/rxsignal": "7.28.1",
|
|
39
|
+
"@quenty/uiobjectutils": "6.28.1"
|
|
39
40
|
},
|
|
40
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "6801a02bc7e7de951df4b9f65c0efc27b642db70"
|
|
41
42
|
}
|
|
@@ -31,12 +31,12 @@
|
|
|
31
31
|
|
|
32
32
|
local require = require(script.Parent.loader).load(script)
|
|
33
33
|
|
|
34
|
-
local UserInputService = game:GetService("UserInputService")
|
|
35
34
|
local Workspace = game:GetService("Workspace")
|
|
36
35
|
|
|
37
36
|
local BaseObject = require("BaseObject")
|
|
38
37
|
local InputObjectRayUtils = require("InputObjectRayUtils")
|
|
39
38
|
local InputObjectUtils = require("InputObjectUtils")
|
|
39
|
+
local MousePositionUtils = require("MousePositionUtils")
|
|
40
40
|
local Observable = require("Observable")
|
|
41
41
|
local RxInputObjectUtils = require("RxInputObjectUtils")
|
|
42
42
|
local RxSignal = require("RxSignal")
|
|
@@ -60,10 +60,6 @@ export type InputObjectTracker =
|
|
|
60
60
|
))
|
|
61
61
|
& BaseObject.BaseObject
|
|
62
62
|
|
|
63
|
-
local function toVector2(vector3: Vector3): Vector2
|
|
64
|
-
return Vector2.new(vector3.X, vector3.Y)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
63
|
function InputObjectTracker.new(initialInputObject: InputObject): InputObjectTracker
|
|
68
64
|
assert(typeof(initialInputObject) == "Instance" and initialInputObject:IsA("InputObject"), "Bad initialInputObject")
|
|
69
65
|
|
|
@@ -83,27 +79,15 @@ function InputObjectTracker.new(initialInputObject: InputObject): InputObjectTra
|
|
|
83
79
|
end
|
|
84
80
|
|
|
85
81
|
function InputObjectTracker._setupMouse(self: InputObjectTracker): ()
|
|
86
|
-
self._lastMousePosition =
|
|
82
|
+
self._lastMousePosition = MousePositionUtils.mouseUserInputObjectToMousePosition(self._initialInputObject)
|
|
83
|
+
or error("Failed to retrieve position")
|
|
87
84
|
self._isMouse = true
|
|
88
85
|
|
|
89
|
-
self._maid:GiveTask(
|
|
90
|
-
|
|
91
|
-
self._lastMousePosition = toVector2(inputObject.Position)
|
|
92
|
-
end
|
|
93
|
-
end))
|
|
94
|
-
|
|
95
|
-
self._maid:GiveTask(UserInputService.InputChanged:Connect(function(inputObject)
|
|
96
|
-
if InputObjectUtils.isMouseUserInputType(inputObject.UserInputType) then
|
|
97
|
-
self._lastMousePosition = toVector2(inputObject.Position)
|
|
98
|
-
end
|
|
99
|
-
end))
|
|
100
|
-
|
|
101
|
-
self._maid:GiveTask(UserInputService.InputEnded:Connect(function(inputObject)
|
|
102
|
-
if InputObjectUtils.isMouseUserInputType(inputObject.UserInputType) then
|
|
103
|
-
self._lastMousePosition = toVector2(inputObject.Position)
|
|
104
|
-
end
|
|
86
|
+
self._maid:GiveTask(MousePositionUtils.observeMousePosition(self._initialInputObject):Subscribe(function(position)
|
|
87
|
+
self._lastMousePosition = position
|
|
105
88
|
end))
|
|
106
89
|
end
|
|
90
|
+
|
|
107
91
|
--[=[
|
|
108
92
|
Observes when the input is ended
|
|
109
93
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--[=[
|
|
3
|
+
@class MouseIconTypeUtils
|
|
4
|
+
]=]
|
|
5
|
+
|
|
6
|
+
local require = require(script.Parent.loader).load(script)
|
|
7
|
+
|
|
8
|
+
local PlayerGuiUtils = require("PlayerGuiUtils")
|
|
9
|
+
|
|
10
|
+
local MouseIconTypeUtils = {}
|
|
11
|
+
|
|
12
|
+
export type IconType = "arrow" | "openhand" | "ibeam" | "closedhand"
|
|
13
|
+
|
|
14
|
+
function MouseIconTypeUtils.getIconUnderPosition(position: Vector2): IconType
|
|
15
|
+
local playerGui = PlayerGuiUtils.getPlayerGui()
|
|
16
|
+
if not playerGui then
|
|
17
|
+
return "arrow"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
local guiObjects = playerGui:GetGuiObjectsAtPosition(position.X, position.Y)
|
|
21
|
+
for _, guiObject in guiObjects do
|
|
22
|
+
if guiObject:IsA("TextBox") then
|
|
23
|
+
if guiObject.GuiState == Enum.GuiState.Hover or guiObject.GuiState == Enum.GuiState.Press then
|
|
24
|
+
return "ibeam"
|
|
25
|
+
end
|
|
26
|
+
elseif guiObject:IsA("ImageButton") or guiObject:IsA("TextButton") then
|
|
27
|
+
if guiObject.GuiState == Enum.GuiState.Hover or guiObject.GuiState == Enum.GuiState.Press then
|
|
28
|
+
return "openhand"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
return "arrow"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
function MouseIconTypeUtils.getDefaultIconAssetForType(iconType: IconType): string
|
|
37
|
+
if iconType == "arrow" then
|
|
38
|
+
return "rbxasset://textures/Cursors/KeyboardMouse/ArrowFarCursor.png"
|
|
39
|
+
elseif iconType == "openhand" then
|
|
40
|
+
return "rbxasset://textures/Cursors/KeyboardMouse/ArrowCursor.png"
|
|
41
|
+
elseif iconType == "closedhand" then
|
|
42
|
+
return "rbxasset://textures/Cursors/DragDetector/ActivatedCursor.png"
|
|
43
|
+
elseif iconType == "ibeam" then
|
|
44
|
+
return "rbxasset://textures/Cursors/KeyboardMouse/IBeamCursor.png"
|
|
45
|
+
else
|
|
46
|
+
error("Unknown icon type: " .. tostring(iconType))
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
return MouseIconTypeUtils
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--[=[
|
|
3
|
+
@class MousePositionUtils
|
|
4
|
+
]=]
|
|
5
|
+
|
|
6
|
+
local require = require(script.Parent.loader).load(script)
|
|
7
|
+
|
|
8
|
+
local GuiService = game:GetService("GuiService")
|
|
9
|
+
local Players = game:GetService("Players")
|
|
10
|
+
local UserInputService = game:GetService("UserInputService")
|
|
11
|
+
|
|
12
|
+
local InputObjectUtils = require("InputObjectUtils")
|
|
13
|
+
local Maid = require("Maid")
|
|
14
|
+
local Observable = require("Observable")
|
|
15
|
+
|
|
16
|
+
local MousePositionUtils = {}
|
|
17
|
+
|
|
18
|
+
local function toVector2(vector3: Vector3): Vector2
|
|
19
|
+
return Vector2.new(vector3.X, vector3.Y)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
--[=[
|
|
23
|
+
Converts an InputObject to a mouse position if it's a mouse input, otherwise returns nil.
|
|
24
|
+
]=]
|
|
25
|
+
function MousePositionUtils.mouseUserInputObjectToMousePosition(inputObject: InputObject): Vector2?
|
|
26
|
+
if InputObjectUtils.isMouseUserInputType(inputObject.UserInputType) then
|
|
27
|
+
return toVector2(inputObject.Position)
|
|
28
|
+
else
|
|
29
|
+
return nil
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
--[=[
|
|
34
|
+
Observes the mouse position based on UserInputService events. Optionally takes an initial InputObject to seed the position.
|
|
35
|
+
]=]
|
|
36
|
+
function MousePositionUtils.observeMousePosition(initialInputObject: InputObject?): Observable.Observable<Vector2>
|
|
37
|
+
return Observable.new(function(sub)
|
|
38
|
+
local maid = Maid.new()
|
|
39
|
+
local lastMousePosition: Vector2? = nil
|
|
40
|
+
|
|
41
|
+
local function setMousePosition(position: Vector2)
|
|
42
|
+
if lastMousePosition ~= position then
|
|
43
|
+
lastMousePosition = position
|
|
44
|
+
sub:Fire(position)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
maid:GiveTask(UserInputService.InputBegan:Connect(function(inputObject)
|
|
49
|
+
local position = MousePositionUtils.mouseUserInputObjectToMousePosition(inputObject)
|
|
50
|
+
if position then
|
|
51
|
+
setMousePosition(position)
|
|
52
|
+
end
|
|
53
|
+
end))
|
|
54
|
+
|
|
55
|
+
maid:GiveTask(UserInputService.InputChanged:Connect(function(inputObject)
|
|
56
|
+
local position = MousePositionUtils.mouseUserInputObjectToMousePosition(inputObject)
|
|
57
|
+
if position then
|
|
58
|
+
setMousePosition(position)
|
|
59
|
+
end
|
|
60
|
+
end))
|
|
61
|
+
|
|
62
|
+
maid:GiveTask(UserInputService.InputEnded:Connect(function(inputObject)
|
|
63
|
+
local position = MousePositionUtils.mouseUserInputObjectToMousePosition(inputObject)
|
|
64
|
+
if position then
|
|
65
|
+
setMousePosition(position)
|
|
66
|
+
end
|
|
67
|
+
end))
|
|
68
|
+
|
|
69
|
+
local initial = if initialInputObject
|
|
70
|
+
then MousePositionUtils.mouseUserInputObjectToMousePosition(initialInputObject)
|
|
71
|
+
else nil
|
|
72
|
+
if initial then
|
|
73
|
+
setMousePosition(initial)
|
|
74
|
+
else
|
|
75
|
+
setMousePosition(MousePositionUtils.queryMousePositionFromUserInputService())
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
return function()
|
|
79
|
+
maid:DoCleaning()
|
|
80
|
+
end
|
|
81
|
+
end) :: any
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
--[=[
|
|
85
|
+
Gets the same mouse position as we'd get from :GetMouse() call, with the gui insets accounted for
|
|
86
|
+
]=]
|
|
87
|
+
function MousePositionUtils.queryMousePositionFromUserInputService(): Vector2
|
|
88
|
+
local guiInsetTopLeft = GuiService:GetGuiInset()
|
|
89
|
+
local location = UserInputService:GetMouseLocation()
|
|
90
|
+
return Vector2.new(location.X + guiInsetTopLeft.x, location.Y + guiInsetTopLeft.y)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
function MousePositionUtils._queryMousePositionFromLocalPlayer(): Vector2?
|
|
94
|
+
local localPlayer = Players.LocalPlayer
|
|
95
|
+
if not localPlayer then
|
|
96
|
+
return nil
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
local mouse = localPlayer:GetMouse()
|
|
100
|
+
if not mouse then
|
|
101
|
+
return nil
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
return Vector2.new(mouse.X, mouse.Y)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
return MousePositionUtils
|