@quenty/camera 14.20.3 → 14.20.4-canary.11a5dcf.0
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 +16 -0
- package/package.json +17 -17
- package/src/Client/CameraStack.lua +27 -20
- package/src/Client/CameraStackService.lua +53 -35
- package/src/Client/CameraState.lua +8 -8
- package/src/Client/CameraUtils.lua +1 -1
- package/src/Client/CameraUtils.story.lua +5 -4
- package/src/Client/Controls/CameraControls.lua +107 -60
- package/src/Client/Controls/CameraGamepadInputUtils.lua +36 -21
- package/src/Client/Controls/GamepadRotateModel.lua +22 -12
- package/src/Client/Effects/CameraEffectUtils.lua +10 -1
- package/src/Client/Effects/CustomCameraEffect.lua +21 -5
- package/src/Client/Effects/DefaultCamera.lua +50 -32
- package/src/Client/Effects/FadeBetween/FadeBetweenCamera.lua +7 -7
- package/src/Client/Effects/FadeBetween/FadeBetweenCamera2.lua +11 -11
- package/src/Client/Effects/FadeBetween/FadeBetweenCamera3.lua +57 -21
- package/src/Client/Effects/FadeBetween/FadeBetweenCamera4.lua +17 -9
- package/src/Client/Effects/FadingCamera.lua +21 -5
- package/src/Client/Effects/HeartbeatCamera.lua +22 -9
- package/src/Client/Effects/ImpulseCamera.lua +44 -28
- package/src/Client/Effects/ImpulseCamera.story.lua +6 -6
- package/src/Client/Effects/InverseFader.lua +22 -6
- package/src/Client/Effects/LagPointCamera.lua +27 -8
- package/src/Client/Effects/OverrideDefaultCameraToo.lua +26 -4
- package/src/Client/Effects/PointCamera.lua +22 -6
- package/src/Client/Effects/PushCamera.lua +35 -14
- package/src/Client/Effects/RotatedCamera.lua +23 -9
- package/src/Client/Effects/SmoothPositionCamera.lua +22 -10
- package/src/Client/Effects/SmoothRotatedCamera.lua +52 -24
- package/src/Client/Effects/SmoothZoomedCamera.lua +31 -12
- package/src/Client/Effects/SummedCamera.lua +38 -16
- package/src/Client/Effects/TrackCamera.lua +24 -11
- package/src/Client/Effects/XZPlaneLockCamera.lua +21 -8
- package/src/Client/Effects/ZoomedCamera.lua +24 -7
- package/src/Client/Input/CameraInputUtils.lua +49 -13
- package/src/Client/Input/CameraTouchInputUtils.lua +17 -16
- package/src/Client/Utility/CameraFrame.lua +2 -2
- package/src/Client/Utility/CameraFrame.story.lua +21 -12
- package/src/Client/Utility/CameraStateTweener.lua +39 -19
- package/src/Client/Utility/FieldOfViewUtils.lua +1 -1
- package/test/scripts/Client/ClientMain.client.lua +1 -1
- package/test/scripts/Server/ServerMain.server.lua +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Lags the camera smoothly behind the position maintaining other components
|
|
3
4
|
@class SmoothPositionCamera
|
|
@@ -5,17 +6,28 @@
|
|
|
5
6
|
|
|
6
7
|
local require = require(script.Parent.loader).load(script)
|
|
7
8
|
|
|
8
|
-
local
|
|
9
|
-
local SummedCamera = require("SummedCamera")
|
|
10
|
-
local Spring = require("Spring")
|
|
9
|
+
local CameraEffectUtils = require("CameraEffectUtils")
|
|
11
10
|
local CameraFrame = require("CameraFrame")
|
|
11
|
+
local CameraState = require("CameraState")
|
|
12
12
|
local QFrame = require("QFrame")
|
|
13
|
+
local Spring = require("Spring")
|
|
14
|
+
local SummedCamera = require("SummedCamera")
|
|
13
15
|
|
|
14
16
|
local SmoothPositionCamera = {}
|
|
15
17
|
SmoothPositionCamera.ClassName = "SmoothPositionCamera"
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
export type SmoothPositionCamera = typeof(setmetatable(
|
|
20
|
+
{} :: {
|
|
21
|
+
CameraState: CameraState.CameraState,
|
|
22
|
+
Spring: Spring.Spring<Vector3>,
|
|
23
|
+
BaseCamera: CameraEffectUtils.CameraEffect,
|
|
24
|
+
Speed: number,
|
|
25
|
+
},
|
|
26
|
+
{} :: typeof({ __index = SmoothPositionCamera })
|
|
27
|
+
)) & CameraEffectUtils.CameraEffect
|
|
28
|
+
|
|
29
|
+
function SmoothPositionCamera.new(baseCamera): SmoothPositionCamera
|
|
30
|
+
local self: SmoothPositionCamera = setmetatable({} :: any, SmoothPositionCamera)
|
|
19
31
|
|
|
20
32
|
self.Spring = Spring.new(Vector3.zero)
|
|
21
33
|
self.BaseCamera = baseCamera or error("Must have BaseCamera")
|
|
@@ -50,12 +62,12 @@ function SmoothPositionCamera:__index(index)
|
|
|
50
62
|
local baseCameraFrame = baseCameraState.CameraFrame
|
|
51
63
|
local baseCameraFrameDerivative = baseCameraState.CameraFrameDerivative
|
|
52
64
|
|
|
53
|
-
local cameraFrame =
|
|
54
|
-
QFrame.fromVector3(self.Position, baseCameraFrame.QFrame),
|
|
55
|
-
baseCameraFrame.FieldOfView)
|
|
65
|
+
local cameraFrame =
|
|
66
|
+
CameraFrame.new(QFrame.fromVector3(self.Position, baseCameraFrame.QFrame), baseCameraFrame.FieldOfView)
|
|
56
67
|
local cameraFrameDerivative = CameraFrame.new(
|
|
57
68
|
QFrame.fromVector3(self.Velocity, baseCameraFrameDerivative.QFrame),
|
|
58
|
-
baseCameraFrameDerivative.FieldOfView
|
|
69
|
+
baseCameraFrameDerivative.FieldOfView
|
|
70
|
+
)
|
|
59
71
|
|
|
60
72
|
return CameraState.new(cameraFrame, cameraFrameDerivative)
|
|
61
73
|
elseif index == "Position" then
|
|
@@ -86,4 +98,4 @@ function SmoothPositionCamera:_internalUpdate()
|
|
|
86
98
|
end
|
|
87
99
|
end
|
|
88
100
|
|
|
89
|
-
return SmoothPositionCamera
|
|
101
|
+
return SmoothPositionCamera
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Allow freedom of movement around a current place, much like the classic script works now.
|
|
3
4
|
Not intended to be use with the current character script. This is the rotation component.
|
|
@@ -8,21 +9,48 @@
|
|
|
8
9
|
|
|
9
10
|
local require = require(script.Parent.loader).load(script)
|
|
10
11
|
|
|
12
|
+
local CameraEffectUtils = require("CameraEffectUtils")
|
|
11
13
|
local CameraState = require("CameraState")
|
|
12
|
-
local getRotationInXZPlane = require("getRotationInXZPlane")
|
|
13
14
|
local Spring = require("Spring")
|
|
14
15
|
local SummedCamera = require("SummedCamera")
|
|
16
|
+
local getRotationInXZPlane = require("getRotationInXZPlane")
|
|
15
17
|
|
|
16
18
|
local SmoothRotatedCamera = {}
|
|
17
19
|
SmoothRotatedCamera.ClassName = "SmoothRotatedCamera"
|
|
18
20
|
|
|
21
|
+
export type SmoothRotatedCamera = typeof(setmetatable(
|
|
22
|
+
{} :: {
|
|
23
|
+
AngleX: number,
|
|
24
|
+
AngleXZ: number,
|
|
25
|
+
RenderAngleXZ: number,
|
|
26
|
+
AngleY: number,
|
|
27
|
+
CFrame: CFrame,
|
|
28
|
+
RenderAngleY: number,
|
|
29
|
+
CameraState: CameraState.CameraState,
|
|
30
|
+
MaxY: number,
|
|
31
|
+
MinY: number,
|
|
32
|
+
Rotation: CFrame,
|
|
33
|
+
Speed: number,
|
|
34
|
+
ZoomGiveY: number,
|
|
35
|
+
SpeedAngleX: number,
|
|
36
|
+
SpeedAngleY: number,
|
|
37
|
+
SpringX: Spring.Spring<number>,
|
|
38
|
+
SpringY: Spring.Spring<number>,
|
|
39
|
+
TargetAngleX: number,
|
|
40
|
+
TargetAngleXZ: number,
|
|
41
|
+
TargetAngleY: number,
|
|
42
|
+
TargetXZ: number,
|
|
43
|
+
},
|
|
44
|
+
{} :: typeof({ __index = SmoothRotatedCamera })
|
|
45
|
+
)) & CameraEffectUtils.CameraEffect
|
|
46
|
+
|
|
19
47
|
-- Max/Min aim up and down
|
|
20
48
|
SmoothRotatedCamera._maxY = math.rad(80)
|
|
21
49
|
SmoothRotatedCamera._minY = math.rad(-80)
|
|
22
50
|
SmoothRotatedCamera._zoomGiveY = math.rad(5) -- Only on th
|
|
23
51
|
|
|
24
|
-
function SmoothRotatedCamera.new()
|
|
25
|
-
local self = setmetatable({}, SmoothRotatedCamera)
|
|
52
|
+
function SmoothRotatedCamera.new(): SmoothRotatedCamera
|
|
53
|
+
local self: SmoothRotatedCamera = setmetatable({} :: any, SmoothRotatedCamera)
|
|
26
54
|
|
|
27
55
|
self.SpringX = Spring.new(0)
|
|
28
56
|
self.SpringY = Spring.new(0)
|
|
@@ -31,37 +59,37 @@ function SmoothRotatedCamera.new()
|
|
|
31
59
|
return self
|
|
32
60
|
end
|
|
33
61
|
|
|
34
|
-
function SmoothRotatedCamera
|
|
62
|
+
function SmoothRotatedCamera.__add(self: SmoothRotatedCamera, other)
|
|
35
63
|
return SummedCamera.new(self, other)
|
|
36
64
|
end
|
|
37
65
|
|
|
38
66
|
--[=[
|
|
39
67
|
@param xyRotateVector Vector2 -- The delta rotation to apply
|
|
40
68
|
]=]
|
|
41
|
-
function SmoothRotatedCamera
|
|
42
|
-
self.AngleX = self.AngleX + xyRotateVector.
|
|
43
|
-
self.AngleY = self.AngleY + xyRotateVector.
|
|
69
|
+
function SmoothRotatedCamera.RotateXY(self: SmoothRotatedCamera, xyRotateVector: Vector2)
|
|
70
|
+
self.AngleX = self.AngleX + xyRotateVector.X
|
|
71
|
+
self.AngleY = self.AngleY + xyRotateVector.Y
|
|
44
72
|
self.TargetAngleX = self.AngleX
|
|
45
73
|
self.TargetAngleY = self.AngleY
|
|
46
74
|
end
|
|
47
75
|
|
|
48
|
-
function SmoothRotatedCamera
|
|
76
|
+
function SmoothRotatedCamera.__newindex(self: SmoothRotatedCamera, index, value)
|
|
49
77
|
if index == "CFrame" then
|
|
50
78
|
local xzrot = getRotationInXZPlane(value)
|
|
51
|
-
self.AngleXZ = math.atan2(xzrot.
|
|
79
|
+
self.AngleXZ = math.atan2(xzrot.LookVector.X, xzrot.LookVector.Z) + math.pi
|
|
52
80
|
|
|
53
|
-
local yrot = xzrot:
|
|
81
|
+
local yrot = xzrot:ToObjectSpace(value).LookVector.Y
|
|
54
82
|
self.AngleY = math.asin(yrot)
|
|
55
83
|
elseif index == "TargetCFrame" then
|
|
56
84
|
local xzrot = getRotationInXZPlane(value)
|
|
57
|
-
self.TargetAngleXZ = math.atan2(xzrot.
|
|
85
|
+
self.TargetAngleXZ = math.atan2(xzrot.LookVector.X, xzrot.LookVector.Z) + math.pi
|
|
58
86
|
|
|
59
|
-
local yrot = xzrot:
|
|
87
|
+
local yrot = xzrot:ToObjectSpace(value).LookVector.Y
|
|
60
88
|
self.TargetAngleY = math.asin(yrot)
|
|
61
89
|
elseif index == "AngleY" then
|
|
62
|
-
self.SpringY.
|
|
90
|
+
self.SpringY.Position = value
|
|
63
91
|
elseif index == "AngleX" or index == "AngleXZ" then
|
|
64
|
-
self.SpringX.
|
|
92
|
+
self.SpringX.Position = value
|
|
65
93
|
elseif index == "TargetAngleY" then
|
|
66
94
|
self.SpringY.Target = value
|
|
67
95
|
elseif index == "TargetAngleX" or index == "TargetAngleXZ" then
|
|
@@ -84,15 +112,15 @@ function SmoothRotatedCamera:__newindex(index, value)
|
|
|
84
112
|
elseif SmoothRotatedCamera[index] ~= nil or index == "SpringX" or index == "SpringY" then
|
|
85
113
|
rawset(self, index, value)
|
|
86
114
|
else
|
|
87
|
-
error(index .. " is not a valid member or SmoothRotatedCamera")
|
|
115
|
+
error(tostring(index) .. " is not a valid member or SmoothRotatedCamera")
|
|
88
116
|
end
|
|
89
117
|
end
|
|
90
118
|
|
|
91
|
-
function SmoothRotatedCamera
|
|
119
|
+
function SmoothRotatedCamera.SnapIntoBounds(self: SmoothRotatedCamera)
|
|
92
120
|
self.TargetAngleY = math.clamp(self.TargetAngleY, self.MinY, self.MaxY)
|
|
93
121
|
end
|
|
94
122
|
|
|
95
|
-
function SmoothRotatedCamera
|
|
123
|
+
function SmoothRotatedCamera.GetPastBounds(self: SmoothRotatedCamera, angle)
|
|
96
124
|
if angle < self.MinY then
|
|
97
125
|
return angle - self.MinY
|
|
98
126
|
elseif angle > self.MaxY then
|
|
@@ -102,13 +130,13 @@ function SmoothRotatedCamera:GetPastBounds(angle)
|
|
|
102
130
|
end
|
|
103
131
|
end
|
|
104
132
|
|
|
105
|
-
function SmoothRotatedCamera
|
|
133
|
+
function SmoothRotatedCamera.__index(self: SmoothRotatedCamera, index)
|
|
106
134
|
if index == "CameraState" then
|
|
107
135
|
local state = CameraState.new()
|
|
108
136
|
state.CFrame = self.CFrame
|
|
109
137
|
return state
|
|
110
138
|
elseif index == "LookVector" then
|
|
111
|
-
return self.Rotation.
|
|
139
|
+
return self.Rotation.LookVector
|
|
112
140
|
elseif index == "CFrame" then
|
|
113
141
|
return CFrame.Angles(0, self.RenderAngleXZ, 0) * CFrame.Angles(self.RenderAngleY, 0, 0)
|
|
114
142
|
elseif index == "TargetCFrame" then
|
|
@@ -121,18 +149,18 @@ function SmoothRotatedCamera:__index(index)
|
|
|
121
149
|
local scale = (1 - 0.25 ^ math.abs(timesOverBounds))
|
|
122
150
|
|
|
123
151
|
if past < 0 then
|
|
124
|
-
return self.MinY - self.ZoomGiveY*scale
|
|
152
|
+
return self.MinY - self.ZoomGiveY * scale
|
|
125
153
|
elseif past > 0 then
|
|
126
|
-
return self.MaxY + self.ZoomGiveY*scale
|
|
154
|
+
return self.MaxY + self.ZoomGiveY * scale
|
|
127
155
|
else
|
|
128
156
|
return angle
|
|
129
157
|
end
|
|
130
158
|
elseif index == "RenderAngleX" or index == "RenderAngleXZ" then
|
|
131
159
|
return self.AngleX
|
|
132
160
|
elseif index == "AngleY" then
|
|
133
|
-
return self.SpringY.
|
|
161
|
+
return self.SpringY.Position
|
|
134
162
|
elseif index == "AngleX" or index == "AngleXZ" then
|
|
135
|
-
return self.SpringX.
|
|
163
|
+
return self.SpringX.Position
|
|
136
164
|
elseif index == "TargetAngleY" then
|
|
137
165
|
return self.SpringY.Target
|
|
138
166
|
elseif index == "TargetAngleX" or index == "TargetAngleXZ" then
|
|
@@ -150,4 +178,4 @@ function SmoothRotatedCamera:__index(index)
|
|
|
150
178
|
end
|
|
151
179
|
end
|
|
152
180
|
|
|
153
|
-
return SmoothRotatedCamera
|
|
181
|
+
return SmoothRotatedCamera
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Allow freedom of movement around a current place, much like the classic script works now.
|
|
3
4
|
Not intended to be use with the current character script
|
|
@@ -8,9 +9,10 @@
|
|
|
8
9
|
|
|
9
10
|
local require = require(script.Parent.loader).load(script)
|
|
10
11
|
|
|
12
|
+
local CameraEffectUtils = require("CameraEffectUtils")
|
|
11
13
|
local CameraState = require("CameraState")
|
|
12
|
-
local SummedCamera = require("SummedCamera")
|
|
13
14
|
local Spring = require("Spring")
|
|
15
|
+
local SummedCamera = require("SummedCamera")
|
|
14
16
|
|
|
15
17
|
local SmoothZoomedCamera = {}
|
|
16
18
|
SmoothZoomedCamera.ClassName = "SmoothZoomedCamera"
|
|
@@ -18,8 +20,25 @@ SmoothZoomedCamera._maxZoom = 100
|
|
|
18
20
|
SmoothZoomedCamera._minZoom = 0.5
|
|
19
21
|
SmoothZoomedCamera.BounceAtEnd = true
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
export type SmoothZoomedCamera = typeof(setmetatable(
|
|
24
|
+
{} :: {
|
|
25
|
+
CameraState: CameraState.CameraState,
|
|
26
|
+
Zoom: number,
|
|
27
|
+
Speed: number,
|
|
28
|
+
Range: number,
|
|
29
|
+
MaxZoom: number,
|
|
30
|
+
MinZoom: number,
|
|
31
|
+
Target: number,
|
|
32
|
+
Value: number,
|
|
33
|
+
Velocity: number,
|
|
34
|
+
TargetZoom: number,
|
|
35
|
+
Spring: Spring.Spring<number>,
|
|
36
|
+
},
|
|
37
|
+
{} :: typeof({ __index = SmoothZoomedCamera })
|
|
38
|
+
)) & CameraEffectUtils.CameraEffect
|
|
39
|
+
|
|
40
|
+
function SmoothZoomedCamera.new(): SmoothZoomedCamera
|
|
41
|
+
local self: SmoothZoomedCamera = setmetatable({} :: any, SmoothZoomedCamera)
|
|
23
42
|
|
|
24
43
|
self.Spring = Spring.new(0)
|
|
25
44
|
self.Speed = 15
|
|
@@ -27,11 +46,11 @@ function SmoothZoomedCamera.new()
|
|
|
27
46
|
return self
|
|
28
47
|
end
|
|
29
48
|
|
|
30
|
-
function SmoothZoomedCamera
|
|
49
|
+
function SmoothZoomedCamera.__add(self: SmoothZoomedCamera, other)
|
|
31
50
|
return SummedCamera.new(self, other)
|
|
32
51
|
end
|
|
33
52
|
|
|
34
|
-
function SmoothZoomedCamera
|
|
53
|
+
function SmoothZoomedCamera.ZoomIn(self: SmoothZoomedCamera, value: number, min: number?, max: number?)
|
|
35
54
|
if min or max then
|
|
36
55
|
self.Zoom = self.Zoom - math.clamp(value, min or -math.huge, max or math.huge)
|
|
37
56
|
else
|
|
@@ -39,11 +58,11 @@ function SmoothZoomedCamera:ZoomIn(value, min, max)
|
|
|
39
58
|
end
|
|
40
59
|
end
|
|
41
60
|
|
|
42
|
-
function SmoothZoomedCamera
|
|
61
|
+
function SmoothZoomedCamera.Impulse(self: SmoothZoomedCamera, value)
|
|
43
62
|
self.Spring:Impulse(value)
|
|
44
63
|
end
|
|
45
64
|
|
|
46
|
-
function SmoothZoomedCamera
|
|
65
|
+
function SmoothZoomedCamera.__newindex(self: SmoothZoomedCamera, index, value)
|
|
47
66
|
if index == "TargetZoom" or index == "Target" then
|
|
48
67
|
local target = math.clamp(value, self.MinZoom, self.MaxZoom)
|
|
49
68
|
self.Spring.Target = target
|
|
@@ -56,9 +75,9 @@ function SmoothZoomedCamera:__newindex(index, value)
|
|
|
56
75
|
end
|
|
57
76
|
end
|
|
58
77
|
elseif index == "TargetPercentZoom" then
|
|
59
|
-
self.Target = self.MinZoom + self.Range*value
|
|
78
|
+
self.Target = self.MinZoom + self.Range * value
|
|
60
79
|
elseif index == "PercentZoom" then
|
|
61
|
-
self.Zoom = self.MinZoom + self.Range*value
|
|
80
|
+
self.Zoom = self.MinZoom + self.Range * value
|
|
62
81
|
elseif index == "Damper" then
|
|
63
82
|
self.Spring.Damper = value
|
|
64
83
|
elseif index == "Value" or index == "Zoom" then
|
|
@@ -78,13 +97,13 @@ function SmoothZoomedCamera:__newindex(index, value)
|
|
|
78
97
|
end
|
|
79
98
|
end
|
|
80
99
|
|
|
81
|
-
function SmoothZoomedCamera
|
|
100
|
+
function SmoothZoomedCamera.__index(self: SmoothZoomedCamera, index)
|
|
82
101
|
if index == "CameraState" then
|
|
83
102
|
local state = CameraState.new()
|
|
84
103
|
state.Position = Vector3.new(0, 0, self.Zoom)
|
|
85
104
|
return state
|
|
86
105
|
elseif index == "Zoom" or index == "value" then
|
|
87
|
-
return self.Spring.
|
|
106
|
+
return self.Spring.Position
|
|
88
107
|
elseif index == "TargetPercentZoom" then
|
|
89
108
|
return (self.Target - self.MinZoom) / self.Range
|
|
90
109
|
elseif index == "PercentZoom" then
|
|
@@ -110,4 +129,4 @@ function SmoothZoomedCamera:__index(index)
|
|
|
110
129
|
end
|
|
111
130
|
end
|
|
112
131
|
|
|
113
|
-
return SmoothZoomedCamera
|
|
132
|
+
return SmoothZoomedCamera
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Add two cameras together
|
|
3
4
|
@class SummedCamera
|
|
@@ -5,13 +6,28 @@
|
|
|
5
6
|
|
|
6
7
|
local require = require(script.Parent.loader).load(script)
|
|
7
8
|
|
|
8
|
-
local
|
|
9
|
-
local CameraState = require("CameraState")
|
|
9
|
+
local CameraEffectUtils = require("CameraEffectUtils")
|
|
10
10
|
local CameraFrame = require("CameraFrame")
|
|
11
|
+
local CameraState = require("CameraState")
|
|
12
|
+
local QFrame = require("QFrame")
|
|
11
13
|
|
|
12
14
|
local SummedCamera = {}
|
|
13
15
|
SummedCamera.ClassName = "SummedCamera"
|
|
14
16
|
|
|
17
|
+
export type SummedCameraMode = "World" | "Relative"
|
|
18
|
+
|
|
19
|
+
export type SummedCamera = typeof(setmetatable(
|
|
20
|
+
{} :: {
|
|
21
|
+
CameraState: CameraState.CameraState,
|
|
22
|
+
CameraAState: CameraState.CameraState,
|
|
23
|
+
CameraBState: CameraState.CameraState,
|
|
24
|
+
_cameraA: CameraEffectUtils.CameraEffect,
|
|
25
|
+
_cameraB: CameraEffectUtils.CameraEffect,
|
|
26
|
+
_mode: SummedCameraMode,
|
|
27
|
+
},
|
|
28
|
+
{} :: typeof({ __index = SummedCamera })
|
|
29
|
+
)) & CameraEffectUtils.CameraEffect
|
|
30
|
+
|
|
15
31
|
--[=[
|
|
16
32
|
Construct a new summed camera
|
|
17
33
|
|
|
@@ -19,8 +35,11 @@ SummedCamera.ClassName = "SummedCamera"
|
|
|
19
35
|
@param cameraB CameraEffect -- A CameraState or another CameraEffect to be used
|
|
20
36
|
@return SummedCamera
|
|
21
37
|
]=]
|
|
22
|
-
function SummedCamera.new(
|
|
23
|
-
|
|
38
|
+
function SummedCamera.new(
|
|
39
|
+
cameraA: CameraEffectUtils.CameraEffect,
|
|
40
|
+
cameraB: CameraEffectUtils.CameraEffect
|
|
41
|
+
): SummedCamera
|
|
42
|
+
local self: SummedCamera = setmetatable({} :: any, SummedCamera)
|
|
24
43
|
|
|
25
44
|
self._mode = "World"
|
|
26
45
|
self._cameraA = cameraA or error("No cameraA")
|
|
@@ -36,32 +55,32 @@ end
|
|
|
36
55
|
@param mode "World" | "Relative" -- Mode to set
|
|
37
56
|
@return SummedCamera
|
|
38
57
|
]=]
|
|
39
|
-
function SummedCamera
|
|
58
|
+
function SummedCamera.SetMode(self: SummedCamera, mode: SummedCameraMode): SummedCamera
|
|
40
59
|
assert(mode == "World" or mode == "Relative", "Bad mode")
|
|
41
60
|
self._mode = mode
|
|
42
61
|
|
|
43
62
|
return self
|
|
44
63
|
end
|
|
45
64
|
|
|
46
|
-
function SummedCamera
|
|
65
|
+
function SummedCamera.__addClass(self: SummedCamera, other: CameraEffectUtils.CameraEffect)
|
|
47
66
|
return SummedCamera.new(self, other)
|
|
48
67
|
end
|
|
49
68
|
|
|
50
|
-
function SummedCamera
|
|
69
|
+
function SummedCamera.__add(self: SummedCamera, other: CameraEffectUtils.CameraEffect)
|
|
51
70
|
return SummedCamera.new(self, other):SetMode(self._mode)
|
|
52
71
|
end
|
|
53
72
|
|
|
54
|
-
function SummedCamera
|
|
73
|
+
function SummedCamera.__sub(self: SummedCamera, camera: CameraEffectUtils.CameraEffect): CameraEffectUtils.CameraEffect
|
|
55
74
|
if self._cameraA == camera then
|
|
56
75
|
return self._cameraA
|
|
57
76
|
elseif self._cameraB == camera then
|
|
58
77
|
return self._cameraB
|
|
59
78
|
else
|
|
60
|
-
error("Unable to subtract successfully")
|
|
79
|
+
error("Unable to subtract successfully")
|
|
61
80
|
end
|
|
62
81
|
end
|
|
63
82
|
|
|
64
|
-
function SummedCamera
|
|
83
|
+
function SummedCamera.__index(self: SummedCamera, index)
|
|
65
84
|
if index == "CameraState" then
|
|
66
85
|
if self._mode == "World" then
|
|
67
86
|
-- TODO: fix this
|
|
@@ -71,15 +90,18 @@ function SummedCamera:__index(index)
|
|
|
71
90
|
local a = self.CameraAState
|
|
72
91
|
local b = self.CameraBState
|
|
73
92
|
|
|
74
|
-
local newQFrame = QFrame.fromCFrameClosestTo(a.CFrame*b.CFrame, a.CameraFrame.QFrame)
|
|
93
|
+
local newQFrame = QFrame.fromCFrameClosestTo(a.CFrame * b.CFrame, a.CameraFrame.QFrame)
|
|
75
94
|
local cameraFrame = CameraFrame.new(newQFrame, a.FieldOfView + b.FieldOfView)
|
|
76
95
|
|
|
77
96
|
-- TODO: compute derivative velocity more correctly of this non-linear thing
|
|
78
97
|
local newQFrameVelocity = QFrame.fromCFrameClosestTo(
|
|
79
|
-
a.CameraFrameDerivative.CFrame*b.CameraFrameDerivative.CFrame,
|
|
80
|
-
a.CameraFrameDerivative.QFrame
|
|
81
|
-
|
|
82
|
-
|
|
98
|
+
a.CameraFrameDerivative.CFrame * b.CameraFrameDerivative.CFrame,
|
|
99
|
+
a.CameraFrameDerivative.QFrame
|
|
100
|
+
)
|
|
101
|
+
local cameraFrameVelocity = CameraFrame.new(
|
|
102
|
+
newQFrameVelocity,
|
|
103
|
+
a.CameraFrameDerivative.FieldOfView + b.CameraFrameDerivative.FieldOfView
|
|
104
|
+
)
|
|
83
105
|
|
|
84
106
|
local result = CameraState.new(cameraFrame, cameraFrameVelocity)
|
|
85
107
|
-- result.CFrame =
|
|
@@ -97,4 +119,4 @@ function SummedCamera:__index(index)
|
|
|
97
119
|
end
|
|
98
120
|
end
|
|
99
121
|
|
|
100
|
-
return SummedCamera
|
|
122
|
+
return SummedCamera
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Track a current part, whether it be a model or part
|
|
3
4
|
@class TrackCamera
|
|
@@ -5,6 +6,7 @@
|
|
|
5
6
|
|
|
6
7
|
local require = require(script.Parent.loader).load(script)
|
|
7
8
|
|
|
9
|
+
local CameraEffectUtils = require("CameraEffectUtils")
|
|
8
10
|
local CameraState = require("CameraState")
|
|
9
11
|
local SummedCamera = require("SummedCamera")
|
|
10
12
|
|
|
@@ -12,29 +14,40 @@ local TrackCamera = {}
|
|
|
12
14
|
TrackCamera.ClassName = "TrackCamera"
|
|
13
15
|
TrackCamera.FieldOfView = 0
|
|
14
16
|
|
|
17
|
+
export type TrackCamera = typeof(setmetatable(
|
|
18
|
+
{} :: {
|
|
19
|
+
CameraState: CameraState.CameraState,
|
|
20
|
+
CameraSubject: Instance?,
|
|
21
|
+
},
|
|
22
|
+
{} :: typeof({ __index = TrackCamera })
|
|
23
|
+
)) & CameraEffectUtils.CameraEffect
|
|
24
|
+
|
|
15
25
|
--[=[
|
|
26
|
+
|
|
16
27
|
Constructs a new TrackCamera
|
|
17
28
|
|
|
18
29
|
@param cameraSubject Instance? -- The CameraSubject to look at. A Roblox part of Roblox model
|
|
19
30
|
@return TrackCamera
|
|
20
31
|
]=]
|
|
21
|
-
function TrackCamera.new(cameraSubject)
|
|
22
|
-
local self = setmetatable({}, TrackCamera)
|
|
32
|
+
function TrackCamera.new(cameraSubject: Instance?): TrackCamera
|
|
33
|
+
local self: TrackCamera = setmetatable({} :: any, TrackCamera)
|
|
23
34
|
|
|
24
35
|
self.CameraSubject = cameraSubject
|
|
25
36
|
|
|
26
37
|
return self
|
|
27
38
|
end
|
|
28
39
|
|
|
29
|
-
function TrackCamera
|
|
40
|
+
function TrackCamera.__add(self: TrackCamera, other): SummedCamera.SummedCamera
|
|
30
41
|
return SummedCamera.new(self, other)
|
|
31
42
|
end
|
|
32
43
|
|
|
33
|
-
function TrackCamera
|
|
44
|
+
function TrackCamera.__newindex(self: TrackCamera, index, value)
|
|
34
45
|
if index == "CameraSubject" then
|
|
35
|
-
assert(
|
|
36
|
-
(value
|
|
37
|
-
|
|
46
|
+
assert(
|
|
47
|
+
typeof(value) == "Instance"
|
|
48
|
+
and (value:IsA("BasePart") or value:IsA("Model") or value:IsA("Attachment") or value:IsA("Humanoid")),
|
|
49
|
+
"CameraSubject must be a Roblox Model, Roblox Part, Attachment, Humanoid, or nil"
|
|
50
|
+
)
|
|
38
51
|
|
|
39
52
|
rawset(self, index, value)
|
|
40
53
|
elseif index == "FieldOfView" then
|
|
@@ -61,7 +74,7 @@ end
|
|
|
61
74
|
@within TrackCamera
|
|
62
75
|
]=]
|
|
63
76
|
|
|
64
|
-
function TrackCamera
|
|
77
|
+
function TrackCamera.__index(self: TrackCamera, index)
|
|
65
78
|
if index == "CameraState" then
|
|
66
79
|
local state = CameraState.new()
|
|
67
80
|
state.FieldOfView = self.FieldOfView
|
|
@@ -69,7 +82,7 @@ function TrackCamera:__index(index)
|
|
|
69
82
|
local cameraSubject = self.CameraSubject
|
|
70
83
|
if cameraSubject then
|
|
71
84
|
if cameraSubject:IsA("Model") then
|
|
72
|
-
state.CFrame = cameraSubject:GetPrimaryPartCFrame()
|
|
85
|
+
state.CFrame = (cameraSubject :: any):GetPrimaryPartCFrame()
|
|
73
86
|
elseif cameraSubject:IsA("BasePart") then
|
|
74
87
|
state.CFrame = cameraSubject.CFrame
|
|
75
88
|
elseif cameraSubject:IsA("Attachment") then
|
|
@@ -78,7 +91,7 @@ function TrackCamera:__index(index)
|
|
|
78
91
|
if cameraSubject.RootPart then
|
|
79
92
|
state.CFrame = cameraSubject.RootPart.CFrame
|
|
80
93
|
elseif cameraSubject.Parent and cameraSubject.Parent:IsA("Model") then
|
|
81
|
-
state.CFrame = cameraSubject:GetPrimaryPartCFrame()
|
|
94
|
+
state.CFrame = (cameraSubject :: any):GetPrimaryPartCFrame()
|
|
82
95
|
end
|
|
83
96
|
else
|
|
84
97
|
error("Bad cameraSubject")
|
|
@@ -91,4 +104,4 @@ function TrackCamera:__index(index)
|
|
|
91
104
|
end
|
|
92
105
|
end
|
|
93
106
|
|
|
94
|
-
return TrackCamera
|
|
107
|
+
return TrackCamera
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Lock camera to only XZPlane, preventing TrackerCameras from making players sick.
|
|
3
4
|
@class XZPlaneLockCamera
|
|
@@ -5,6 +6,7 @@
|
|
|
5
6
|
|
|
6
7
|
local require = require(script.Parent.loader).load(script)
|
|
7
8
|
|
|
9
|
+
local CameraEffectUtils = require("CameraEffectUtils")
|
|
8
10
|
local CameraState = require("CameraState")
|
|
9
11
|
local SummedCamera = require("SummedCamera")
|
|
10
12
|
local getRotationInXZPlane = require("getRotationInXZPlane")
|
|
@@ -12,23 +14,34 @@ local getRotationInXZPlane = require("getRotationInXZPlane")
|
|
|
12
14
|
local XZPlaneLockCamera = {}
|
|
13
15
|
XZPlaneLockCamera.ClassName = "XZPlaneLockCamera"
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
export type XZPlaneLockCamera = typeof(setmetatable(
|
|
18
|
+
{} :: {
|
|
19
|
+
CameraState: CameraState.CameraState,
|
|
20
|
+
_camera: CameraEffectUtils.CameraLike,
|
|
21
|
+
},
|
|
22
|
+
{} :: typeof({ __index = XZPlaneLockCamera })
|
|
23
|
+
)) & CameraEffectUtils.CameraEffect
|
|
17
24
|
|
|
18
|
-
|
|
25
|
+
function XZPlaneLockCamera.new(camera: CameraEffectUtils.CameraLike): XZPlaneLockCamera
|
|
26
|
+
local self: XZPlaneLockCamera = setmetatable({} :: any, XZPlaneLockCamera)
|
|
27
|
+
|
|
28
|
+
self._camera = assert(camera, "No camera")
|
|
19
29
|
|
|
20
30
|
return self
|
|
21
31
|
end
|
|
22
32
|
|
|
23
|
-
function XZPlaneLockCamera
|
|
33
|
+
function XZPlaneLockCamera.__add(
|
|
34
|
+
self: XZPlaneLockCamera,
|
|
35
|
+
other: CameraEffectUtils.CameraEffect
|
|
36
|
+
): SummedCamera.SummedCamera
|
|
24
37
|
return SummedCamera.new(self, other)
|
|
25
38
|
end
|
|
26
39
|
|
|
27
|
-
function XZPlaneLockCamera
|
|
40
|
+
function XZPlaneLockCamera.__index(self: XZPlaneLockCamera, index)
|
|
28
41
|
if index == "CameraState" then
|
|
29
|
-
local state = self._camera.CameraState or self._camera
|
|
30
|
-
local xzrot = getRotationInXZPlane(state.CFrame)
|
|
42
|
+
local state: CameraState.CameraState = (self._camera :: any).CameraState or self._camera
|
|
31
43
|
|
|
44
|
+
local xzrot = getRotationInXZPlane(state.CFrame)
|
|
32
45
|
local newState = CameraState.new()
|
|
33
46
|
newState.CFrame = xzrot
|
|
34
47
|
newState.FieldOfView = state.FieldOfView
|
|
@@ -39,4 +52,4 @@ function XZPlaneLockCamera:__index(index)
|
|
|
39
52
|
end
|
|
40
53
|
end
|
|
41
54
|
|
|
42
|
-
return XZPlaneLockCamera
|
|
55
|
+
return XZPlaneLockCamera
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Allow freedom of movement around a current place, much like the classic script works now.
|
|
3
4
|
Not intended to be use with the current character script
|
|
@@ -17,6 +18,7 @@
|
|
|
17
18
|
|
|
18
19
|
local require = require(script.Parent.loader).load(script)
|
|
19
20
|
|
|
21
|
+
local CameraEffectUtils = require("CameraEffectUtils")
|
|
20
22
|
local CameraState = require("CameraState")
|
|
21
23
|
local SummedCamera = require("SummedCamera")
|
|
22
24
|
|
|
@@ -26,17 +28,32 @@ ZoomedCamera._maxZoom = 100
|
|
|
26
28
|
ZoomedCamera._minZoom = 0.5
|
|
27
29
|
ZoomedCamera._zoom = 10
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
export type ZoomedCamera = typeof(setmetatable(
|
|
32
|
+
{} :: {
|
|
33
|
+
CameraState: CameraState.CameraState,
|
|
34
|
+
Zoom: number,
|
|
35
|
+
MaxZoom: number,
|
|
36
|
+
MinZoom: number,
|
|
37
|
+
|
|
38
|
+
-- Private
|
|
39
|
+
_zoom: number,
|
|
40
|
+
_maxZoom: number,
|
|
41
|
+
_minZoom: number,
|
|
42
|
+
},
|
|
43
|
+
{} :: typeof({ __index = ZoomedCamera })
|
|
44
|
+
)) & CameraEffectUtils.CameraEffect
|
|
45
|
+
|
|
46
|
+
function ZoomedCamera.new(): ZoomedCamera
|
|
47
|
+
local self: ZoomedCamera = setmetatable({} :: any, ZoomedCamera)
|
|
31
48
|
|
|
32
49
|
return self
|
|
33
50
|
end
|
|
34
51
|
|
|
35
|
-
function ZoomedCamera
|
|
52
|
+
function ZoomedCamera.__add(self: ZoomedCamera, other: CameraEffectUtils.CameraEffect): SummedCamera.SummedCamera
|
|
36
53
|
return SummedCamera.new(self, other)
|
|
37
54
|
end
|
|
38
55
|
|
|
39
|
-
function ZoomedCamera
|
|
56
|
+
function ZoomedCamera.ZoomIn(self: ZoomedCamera, value: number, min: number?, max: number?)
|
|
40
57
|
if min or max then
|
|
41
58
|
self.Zoom = self.Zoom - math.clamp(value, min or -math.huge, max or math.huge)
|
|
42
59
|
else
|
|
@@ -44,7 +61,7 @@ function ZoomedCamera:ZoomIn(value, min, max)
|
|
|
44
61
|
end
|
|
45
62
|
end
|
|
46
63
|
|
|
47
|
-
function ZoomedCamera
|
|
64
|
+
function ZoomedCamera.__newindex(self: ZoomedCamera, index, value)
|
|
48
65
|
if index == "Zoom" or index == "TargetZoom" then
|
|
49
66
|
self._zoom = math.clamp(value, self.MinZoom, self.MaxZoom)
|
|
50
67
|
elseif index == "MaxZoom" then
|
|
@@ -62,7 +79,7 @@ function ZoomedCamera:__newindex(index, value)
|
|
|
62
79
|
end
|
|
63
80
|
end
|
|
64
81
|
|
|
65
|
-
function ZoomedCamera
|
|
82
|
+
function ZoomedCamera.__index(self: ZoomedCamera, index)
|
|
66
83
|
if index == "CameraState" then
|
|
67
84
|
local state = CameraState.new()
|
|
68
85
|
state.Position = Vector3.new(0, 0, self.Zoom)
|
|
@@ -78,4 +95,4 @@ function ZoomedCamera:__index(index)
|
|
|
78
95
|
end
|
|
79
96
|
end
|
|
80
97
|
|
|
81
|
-
return ZoomedCamera
|
|
98
|
+
return ZoomedCamera
|