@quenty/gamescalingutils 13.18.0 → 13.18.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 +11 -0
- package/package.json +8 -8
- package/src/Client/GameScalingHelper.lua +64 -34
- package/src/Client/GameScalingUtils.lua +49 -38
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
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
|
+
## [13.18.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/gamescalingutils@13.18.0...@quenty/gamescalingutils@13.18.1) (2025-04-05)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Add types to packages ([2374fb2](https://github.com/Quenty/NevermoreEngine/commit/2374fb2b043cfbe0e9b507b3316eec46a4e353a0))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# [13.18.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/gamescalingutils@13.17.2...@quenty/gamescalingutils@13.18.0) (2025-04-02)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @quenty/gamescalingutils
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/gamescalingutils",
|
|
3
|
-
"version": "13.18.
|
|
3
|
+
"version": "13.18.1",
|
|
4
4
|
"description": "Scale ratios for the UI on different devices",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
"access": "public"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@quenty/baseobject": "^10.8.
|
|
32
|
-
"@quenty/blend": "^12.18.
|
|
33
|
-
"@quenty/instanceutils": "^13.17.
|
|
34
|
-
"@quenty/loader": "^10.8.
|
|
35
|
-
"@quenty/rx": "^13.17.
|
|
36
|
-
"@quenty/valueobject": "^13.17.
|
|
31
|
+
"@quenty/baseobject": "^10.8.1",
|
|
32
|
+
"@quenty/blend": "^12.18.1",
|
|
33
|
+
"@quenty/instanceutils": "^13.17.1",
|
|
34
|
+
"@quenty/loader": "^10.8.1",
|
|
35
|
+
"@quenty/rx": "^13.17.1",
|
|
36
|
+
"@quenty/valueobject": "^13.17.1"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "78c3ac0ab08dd18085b6e6e6e4f745e76ed99f68"
|
|
39
39
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
@class GameScalingHelper
|
|
3
4
|
]=]
|
|
@@ -8,42 +9,61 @@ local BaseObject = require("BaseObject")
|
|
|
8
9
|
local Rx = require("Rx")
|
|
9
10
|
local RxInstanceUtils = require("RxInstanceUtils")
|
|
10
11
|
local ValueObject = require("ValueObject")
|
|
12
|
+
local _Maid = require("Maid")
|
|
13
|
+
local _Observable = require("Observable")
|
|
11
14
|
|
|
12
15
|
local GameScalingHelper = setmetatable({}, BaseObject)
|
|
13
16
|
GameScalingHelper.ClassName = "GameScalingHelper"
|
|
14
17
|
GameScalingHelper.__index = GameScalingHelper
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
export type GameScalingHelper = typeof(setmetatable(
|
|
20
|
+
{} :: {
|
|
21
|
+
_maid: _Maid.Maid,
|
|
22
|
+
_absoluteSize: ValueObject.ValueObject<Vector2>,
|
|
23
|
+
_isVertical: ValueObject.ValueObject<boolean>,
|
|
24
|
+
_isSmall: ValueObject.ValueObject<boolean>,
|
|
25
|
+
_screenGui: ScreenGui?,
|
|
26
|
+
},
|
|
27
|
+
{ __index = GameScalingHelper }
|
|
28
|
+
))
|
|
29
|
+
|
|
30
|
+
function GameScalingHelper.new(screenGui: ScreenGui): GameScalingHelper
|
|
31
|
+
local self = setmetatable(BaseObject.new() :: any, GameScalingHelper)
|
|
18
32
|
|
|
19
33
|
self._absoluteSize = self._maid:Add(ValueObject.new(Vector2.zero, "Vector2"))
|
|
20
34
|
self._isVertical = self._maid:Add(ValueObject.new(false, "boolean"))
|
|
21
35
|
self._isSmall = self._maid:Add(ValueObject.new(false, "boolean"))
|
|
22
36
|
|
|
23
|
-
self._maid:GiveTask(self._absoluteSize
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
37
|
+
self._maid:GiveTask(self._absoluteSize
|
|
38
|
+
:Observe()
|
|
39
|
+
:Pipe({
|
|
40
|
+
Rx.map(function(size)
|
|
41
|
+
if size.x <= 0 or size.y <= 0 then
|
|
42
|
+
return false
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
return size.x / size.y <= 1
|
|
46
|
+
end),
|
|
47
|
+
Rx.distinct() :: any,
|
|
48
|
+
})
|
|
49
|
+
:Subscribe(function(isVertical)
|
|
50
|
+
self._isVertical.Value = isVertical
|
|
51
|
+
end))
|
|
52
|
+
|
|
53
|
+
self._maid:GiveTask(self._absoluteSize
|
|
54
|
+
:Observe()
|
|
55
|
+
:Pipe({
|
|
56
|
+
Rx.map(function(size)
|
|
57
|
+
if size.x > 0 and size.y > 0 and math.min(size.x, size.y) < 500 then
|
|
58
|
+
return true
|
|
59
|
+
else
|
|
60
|
+
return false
|
|
61
|
+
end
|
|
62
|
+
end),
|
|
63
|
+
})
|
|
64
|
+
:Subscribe(function(isSmall)
|
|
65
|
+
self._isSmall.Value = isSmall
|
|
66
|
+
end))
|
|
47
67
|
|
|
48
68
|
if screenGui then
|
|
49
69
|
self:SetScreenGui(screenGui)
|
|
@@ -52,26 +72,36 @@ function GameScalingHelper.new(screenGui)
|
|
|
52
72
|
return self
|
|
53
73
|
end
|
|
54
74
|
|
|
55
|
-
function GameScalingHelper
|
|
75
|
+
function GameScalingHelper.ObserveIsSmall(self: GameScalingHelper): _Observable.Observable<boolean>
|
|
56
76
|
return self._isSmall:Observe()
|
|
57
77
|
end
|
|
58
78
|
|
|
59
|
-
function GameScalingHelper
|
|
79
|
+
function GameScalingHelper.ObserveIsVertical(self: GameScalingHelper): _Observable.Observable<boolean>
|
|
60
80
|
return self._isVertical:Observe()
|
|
61
81
|
end
|
|
62
82
|
|
|
63
|
-
function GameScalingHelper
|
|
64
|
-
return function(absoluteSize)
|
|
83
|
+
function GameScalingHelper.GetAbsoluteSizeSetter(self: GameScalingHelper): (absoluteSize: Vector2) -> ()
|
|
84
|
+
return function(absoluteSize: Vector2)
|
|
65
85
|
self:SetAbsoluteSize(absoluteSize)
|
|
66
86
|
end
|
|
67
87
|
end
|
|
68
88
|
|
|
69
|
-
|
|
70
|
-
|
|
89
|
+
--[=[
|
|
90
|
+
Sets the absolute size of the screen
|
|
91
|
+
]=]
|
|
92
|
+
function GameScalingHelper.SetAbsoluteSize(
|
|
93
|
+
self: GameScalingHelper,
|
|
94
|
+
absoluteSize: Vector2 | _Observable.Observable<Vector2>
|
|
95
|
+
): () -> ()
|
|
96
|
+
return self._absoluteSize:Mount(absoluteSize)
|
|
71
97
|
end
|
|
72
98
|
|
|
73
|
-
|
|
74
|
-
|
|
99
|
+
--[=[
|
|
100
|
+
Sets the screenGui to observe the absolute size from
|
|
101
|
+
@param screenGui ScreenGui
|
|
102
|
+
]=]
|
|
103
|
+
function GameScalingHelper.SetScreenGui(self: GameScalingHelper, screenGui: ScreenGui): () -> ()
|
|
104
|
+
return self:SetAbsoluteSize(RxInstanceUtils.observeProperty(screenGui, "AbsoluteSize"))
|
|
75
105
|
end
|
|
76
106
|
|
|
77
107
|
return GameScalingHelper
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Scale ratios for the UI on different devices
|
|
3
4
|
@class GameScalingUtils
|
|
@@ -10,9 +11,15 @@ local GuiService = game:GetService("GuiService")
|
|
|
10
11
|
local Blend = require("Blend")
|
|
11
12
|
local Rx = require("Rx")
|
|
12
13
|
local RxInstanceUtils = require("RxInstanceUtils")
|
|
14
|
+
local _Observable = require("Observable")
|
|
13
15
|
|
|
14
16
|
local GameScalingUtils = {}
|
|
15
17
|
|
|
18
|
+
export type Props = {
|
|
19
|
+
Parent: Instance?,
|
|
20
|
+
ScreenGui: ScreenGui,
|
|
21
|
+
}
|
|
22
|
+
|
|
16
23
|
--[=[
|
|
17
24
|
Given an screenAbsoluteSize, get a good UI scale to use for fixed offset
|
|
18
25
|
assuming general UI scales built for 720p monitors.
|
|
@@ -20,10 +27,10 @@ local GameScalingUtils = {}
|
|
|
20
27
|
@param screenAbsoluteSize Vector2
|
|
21
28
|
@return number
|
|
22
29
|
]=]
|
|
23
|
-
function GameScalingUtils.getUIScale(screenAbsoluteSize)
|
|
30
|
+
function GameScalingUtils.getUIScale(screenAbsoluteSize: Vector2): number
|
|
24
31
|
assert(typeof(screenAbsoluteSize) == "Vector2", "Bad screenAbsoluteSize")
|
|
25
|
-
local smallestAxis = math.min(screenAbsoluteSize.
|
|
26
|
-
local height = screenAbsoluteSize.
|
|
32
|
+
local smallestAxis = math.min(screenAbsoluteSize.X, screenAbsoluteSize.Y)
|
|
33
|
+
local height = screenAbsoluteSize.Y
|
|
27
34
|
|
|
28
35
|
if GuiService:IsTenFootInterface() then
|
|
29
36
|
return 2
|
|
@@ -45,11 +52,13 @@ end
|
|
|
45
52
|
@param screenGui ScreenGui
|
|
46
53
|
@return Observable<number>
|
|
47
54
|
]=]
|
|
48
|
-
function GameScalingUtils.observeUIScale(screenGui)
|
|
49
|
-
return Blend.Spring(
|
|
50
|
-
:Pipe({
|
|
51
|
-
Rx.map(GameScalingUtils.getUIScale)
|
|
52
|
-
}),
|
|
55
|
+
function GameScalingUtils.observeUIScale(screenGui: ScreenGui): _Observable.Observable<number>
|
|
56
|
+
return Blend.Spring(
|
|
57
|
+
RxInstanceUtils.observeProperty(screenGui, "AbsoluteSize"):Pipe({
|
|
58
|
+
Rx.map(GameScalingUtils.getUIScale) :: any,
|
|
59
|
+
}),
|
|
60
|
+
30
|
|
61
|
+
)
|
|
53
62
|
end
|
|
54
63
|
|
|
55
64
|
--[=[
|
|
@@ -57,16 +66,16 @@ end
|
|
|
57
66
|
@param child Instance
|
|
58
67
|
@return Observable<number>
|
|
59
68
|
]=]
|
|
60
|
-
function GameScalingUtils.observeUIScaleForChild(child)
|
|
69
|
+
function GameScalingUtils.observeUIScaleForChild(child: Instance): _Observable.Observable<number>
|
|
61
70
|
return RxInstanceUtils.observeFirstAncestor(child, "ScreenGui"):Pipe({
|
|
62
|
-
Rx.switchMap(function(screenGui)
|
|
71
|
+
Rx.switchMap(function(screenGui: ScreenGui?): any
|
|
63
72
|
if screenGui then
|
|
64
73
|
return GameScalingUtils.observeUIScale(screenGui)
|
|
65
74
|
else
|
|
66
75
|
return Rx.EMPTY
|
|
67
76
|
end
|
|
68
|
-
end)
|
|
69
|
-
})
|
|
77
|
+
end) :: any,
|
|
78
|
+
}) :: any
|
|
70
79
|
end
|
|
71
80
|
|
|
72
81
|
--[=[
|
|
@@ -75,47 +84,49 @@ end
|
|
|
75
84
|
@param props { Parent: Instance?, ScreenGui: ScreenGui }
|
|
76
85
|
@return Observable<number>
|
|
77
86
|
]=]
|
|
78
|
-
function GameScalingUtils.renderUIScale(props)
|
|
87
|
+
function GameScalingUtils.renderUIScale(props: Props): _Observable.Observable<number>
|
|
79
88
|
assert(props.ScreenGui, "No screenGui")
|
|
80
89
|
|
|
81
|
-
return Blend.New
|
|
82
|
-
Parent = props.Parent
|
|
83
|
-
Scale = GameScalingUtils.observeUIScale(props.ScreenGui)
|
|
84
|
-
}
|
|
90
|
+
return Blend.New("UIScale")({
|
|
91
|
+
Parent = props.Parent,
|
|
92
|
+
Scale = GameScalingUtils.observeUIScale(props.ScreenGui),
|
|
93
|
+
})
|
|
85
94
|
end
|
|
86
95
|
|
|
87
96
|
--[=[
|
|
88
97
|
Blend equivalent of rendering the dialog padding
|
|
89
98
|
|
|
90
99
|
@param props { Parent: Instance?, ScreenGui: ScreenGui }
|
|
91
|
-
@return Observable<
|
|
100
|
+
@return Observable<UIPadding>
|
|
92
101
|
]=]
|
|
93
|
-
function GameScalingUtils.renderDialogPadding(props)
|
|
102
|
+
function GameScalingUtils.renderDialogPadding(props: Props): _Observable.Observable<UIPadding>
|
|
94
103
|
assert(props.ScreenGui, "No screenGui")
|
|
95
104
|
|
|
96
|
-
return Blend.New
|
|
97
|
-
Parent = props.Parent
|
|
98
|
-
PaddingTop = GameScalingUtils.observeDialogPadding(props.ScreenGui)
|
|
99
|
-
PaddingBottom = GameScalingUtils.observeDialogPadding(props.ScreenGui)
|
|
100
|
-
PaddingLeft = GameScalingUtils.observeDialogPadding(props.ScreenGui)
|
|
101
|
-
PaddingRight = GameScalingUtils.observeDialogPadding(props.ScreenGui)
|
|
102
|
-
}
|
|
105
|
+
return Blend.New("UIPadding")({
|
|
106
|
+
Parent = props.Parent,
|
|
107
|
+
PaddingTop = GameScalingUtils.observeDialogPadding(props.ScreenGui),
|
|
108
|
+
PaddingBottom = GameScalingUtils.observeDialogPadding(props.ScreenGui),
|
|
109
|
+
PaddingLeft = GameScalingUtils.observeDialogPadding(props.ScreenGui),
|
|
110
|
+
PaddingRight = GameScalingUtils.observeDialogPadding(props.ScreenGui),
|
|
111
|
+
})
|
|
103
112
|
end
|
|
104
113
|
|
|
105
114
|
--[=[
|
|
106
115
|
Observes a smoothed out UI scale for a given screenGui
|
|
107
116
|
@param screenGui ScreenGui
|
|
108
|
-
@return Observable<
|
|
117
|
+
@return Observable<UDim>
|
|
109
118
|
]=]
|
|
110
|
-
function GameScalingUtils.observeDialogPadding(screenGui)
|
|
111
|
-
return Blend.Spring(
|
|
112
|
-
:Pipe({
|
|
113
|
-
Rx.map(GameScalingUtils.getDialogPadding)
|
|
114
|
-
}),
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
function GameScalingUtils.observeDialogPadding(screenGui: ScreenGui): _Observable.Observable<UDim>
|
|
120
|
+
return Blend.Spring(
|
|
121
|
+
RxInstanceUtils.observeProperty(screenGui, "AbsoluteSize"):Pipe({
|
|
122
|
+
Rx.map(GameScalingUtils.getDialogPadding) :: any,
|
|
123
|
+
}),
|
|
124
|
+
30
|
|
125
|
+
):Pipe({
|
|
126
|
+
Rx.map(function(padding)
|
|
127
|
+
return UDim.new(0, padding)
|
|
128
|
+
end),
|
|
129
|
+
})
|
|
119
130
|
end
|
|
120
131
|
|
|
121
132
|
--[=[
|
|
@@ -123,9 +134,9 @@ end
|
|
|
123
134
|
@param screenAbsoluteSize Vector2
|
|
124
135
|
@return number
|
|
125
136
|
]=]
|
|
126
|
-
function GameScalingUtils.getDialogPadding(screenAbsoluteSize)
|
|
137
|
+
function GameScalingUtils.getDialogPadding(screenAbsoluteSize: Vector2): number
|
|
127
138
|
assert(typeof(screenAbsoluteSize) == "Vector2", "Bad screenAbsoluteSize")
|
|
128
|
-
local smallestAxis = math.min(screenAbsoluteSize.
|
|
139
|
+
local smallestAxis = math.min(screenAbsoluteSize.X, screenAbsoluteSize.Y)
|
|
129
140
|
|
|
130
141
|
if smallestAxis <= 300 then
|
|
131
142
|
return 5
|