@quenty/camera 9.15.0 → 9.16.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 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
+ # [9.16.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/camera@9.15.0...@quenty/camera@9.16.0) (2023-06-18)
7
+
8
+
9
+ ### Features
10
+
11
+ * Better interopability between Roblox and camera stack system ([1916352](https://github.com/Quenty/NevermoreEngine/commit/1916352394a777ec6ab01e869cc7d0cfe92bae76))
12
+
13
+
14
+
15
+
16
+
6
17
  # [9.15.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/camera@9.14.0...@quenty/camera@9.15.0) (2023-06-17)
7
18
 
8
19
  **Note:** Version bump only for package @quenty/camera
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/camera",
3
- "version": "9.15.0",
3
+ "version": "9.16.0",
4
4
  "description": "Quenty's camera system for Roblox",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -43,5 +43,5 @@
43
43
  "publishConfig": {
44
44
  "access": "public"
45
45
  },
46
- "gitHead": "dc77d6de09e9eb9d3fd6dafd790c052d8393d38f"
46
+ "gitHead": "2e4b57d56175186261d4f80a334816e03d63f80e"
47
47
  }
@@ -48,10 +48,14 @@ function CameraStackService:Init(serviceBag)
48
48
  debug.profilebegin("camerastackservice")
49
49
 
50
50
  local state = self:GetTopState()
51
+
52
+ self._rawDefaultCamera:SetLastSetCameraFrame(state.CameraFrame)
53
+
51
54
  if state then
52
55
  state:Set(Workspace.CurrentCamera)
53
56
  end
54
57
 
58
+
55
59
  debug.profileend()
56
60
  end)
57
61
 
@@ -72,7 +76,7 @@ function CameraStackService:Start()
72
76
  Workspace.CurrentCamera.CameraType = Enum.CameraType.Scriptable
73
77
  end)
74
78
  else
75
- self._rawDefaultCamera:BindToRenderStep()
79
+ self._maid:GiveTask(self._rawDefaultCamera:BindToRenderStep())
76
80
  end
77
81
  end
78
82
 
@@ -54,6 +54,10 @@ function CameraState:__index(index)
54
54
  return self.CameraFrame.CFrame
55
55
  elseif index == "Position" then
56
56
  return self.CameraFrame.Position
57
+ elseif index == "CameraFrame" then
58
+ return rawget(self, "CameraFrame")
59
+ elseif index == "CameraFrameDerivative" then
60
+ return rawget(self, "CameraFrameDerivative")
57
61
  elseif index == "Velocity" then
58
62
  return self.CameraFrameDerivative.Position
59
63
  elseif index == "FieldOfView" then
@@ -14,6 +14,11 @@ local HttpService = game:GetService("HttpService")
14
14
 
15
15
  local CameraState = require("CameraState")
16
16
  local SummedCamera = require("SummedCamera")
17
+ local Maid = require("Maid")
18
+ local CFrameUtils = require("CFrameUtils")
19
+ local CameraFrame = require("CameraFrame")
20
+
21
+ local EPSILON = 0.001
17
22
 
18
23
  local DefaultCamera = {}
19
24
  DefaultCamera.ClassName = "DefaultCamera"
@@ -27,6 +32,7 @@ function DefaultCamera.new()
27
32
  local self = setmetatable({}, DefaultCamera)
28
33
 
29
34
  self._key = HttpService:GenerateGUID(false)
35
+ self._maid = Maid.new()
30
36
  self._cameraState = CameraState.new(Workspace.CurrentCamera)
31
37
 
32
38
  return self
@@ -40,14 +46,52 @@ end
40
46
  Overrides the global field of view in the cached camera state
41
47
  @param fieldOfView number
42
48
  ]=]
43
- function DefaultCamera:OverrideGlobalFieldOfView(fieldOfView)
49
+ function DefaultCamera:SetRobloxFieldOfView(fieldOfView)
44
50
  self._cameraState.FieldOfView = fieldOfView
45
51
  end
46
52
 
47
- function DefaultCamera:OverrideCameraState(cameraState)
53
+ -- Back compat
54
+ DefaultCamera.OverrideGlobalFieldOfView = DefaultCamera.SetRobloxFieldOfView
55
+
56
+ --[=[
57
+ Sets the Roblox camera state to look at things
58
+
59
+ @param cameraState CameraState
60
+ ]=]
61
+ function DefaultCamera:SetRobloxCameraState(cameraState)
48
62
  self._cameraState = cameraState or error("No CameraState")
49
63
  end
50
64
 
65
+ -- Back compat
66
+ DefaultCamera.OverrideCameraState = DefaultCamera.SetRobloxCameraState
67
+
68
+ --[=[
69
+ Sets the CFrame of the Roblox Camera
70
+
71
+ @param cframe CFrame
72
+ ]=]
73
+ function DefaultCamera:SetRobloxCFrame(cframe)
74
+ self._cameraState.CFrame = cframe
75
+ end
76
+
77
+ --[=[
78
+ Gets the current Roblox camera state, free of any influence
79
+
80
+ @return CameraState
81
+ ]=]
82
+ function DefaultCamera:GetRobloxCameraState()
83
+ return self._cameraState
84
+ end
85
+
86
+ --[=[
87
+ Sets the camera state different
88
+
89
+ @param cameraFrame CameraState | nil
90
+ ]=]
91
+ function DefaultCamera:SetLastSetCameraFrame(cameraFrame)
92
+ self._lastCameraFrame = CameraFrame.new(cameraFrame.QFrame, cameraFrame.FieldOfView)
93
+ end
94
+
51
95
  --[=[
52
96
  Binds the camera to RunService RenderStepped event.
53
97
 
@@ -56,30 +100,59 @@ end
56
100
  :::
57
101
  ]=]
58
102
  function DefaultCamera:BindToRenderStep()
103
+ local maid = Maid.new()
104
+
59
105
  RunService:BindToRenderStep("DefaultCamera_Preupdate" .. self._key, Enum.RenderPriority.Camera.Value-2, function()
60
- self._cameraState:Set(Workspace.CurrentCamera)
106
+ local camera = Workspace.CurrentCamera
107
+
108
+ if self._lastCameraFrame then
109
+ -- Assume something wrote these values and so we should
110
+ -- pass these through to Roblox's camera
111
+
112
+ if not CFrameUtils.areClose(self._lastCameraFrame.CFrame, camera.CFrame, EPSILON) then
113
+ self._cameraState.CFrame = camera.CFrame
114
+ end
115
+
116
+ if math.abs(self._lastCameraFrame.FieldOfView - camera.FieldOfView) > EPSILON then
117
+ self._cameraState.FieldOfView = camera.FieldOfView
118
+ end
119
+
120
+ self._lastCameraFrame = nil
121
+ end
122
+
123
+ -- Restore our state
124
+ self._cameraState:Set(camera)
61
125
  end)
62
126
 
63
127
  RunService:BindToRenderStep("DefaultCamera_PostUpdate" .. self._key, Enum.RenderPriority.Camera.Value+2, function()
128
+ -- Capture
64
129
  self._cameraState = CameraState.new(Workspace.CurrentCamera)
65
130
  end)
66
131
 
132
+ maid:GiveTask(function()
133
+ RunService:UnbindFromRenderStep("DefaultCamera_Preupdate" .. self._key)
134
+ RunService:UnbindFromRenderStep("DefaultCamera_PostUpdate" .. self._key)
135
+ end)
136
+
67
137
  self._cameraState = CameraState.new(Workspace.CurrentCamera)
138
+
139
+ self._maid._binding = maid
140
+
141
+ return maid
68
142
  end
69
143
 
70
144
  --[=[
71
145
  Unbinds the camera from the RunService
72
146
  ]=]
73
147
  function DefaultCamera:UnbindFromRenderStep()
74
- RunService:UnbindFromRenderStep("DefaultCamera_Preupdate" .. self._key)
75
- RunService:UnbindFromRenderStep("DefaultCamera_PostUpdate" .. self._key)
148
+ self._maid._binding = nil
76
149
  end
77
150
 
78
151
  --[=[
79
152
  Cleans up the binding
80
153
  ]=]
81
154
  function DefaultCamera:Destroy()
82
- self:UnbindFromRenderStep()
155
+ self._maid:DoCleaning()
83
156
  end
84
157
 
85
158
  --[=[
@@ -91,6 +164,8 @@ end
91
164
  function DefaultCamera:__index(index)
92
165
  if index == "CameraState" then
93
166
  return rawget(self, "_cameraState")
167
+ elseif index == "_maid" or index == "_lastCameraFrame" or index == "_key" then
168
+ return rawget(self, index)
94
169
  else
95
170
  return DefaultCamera[index]
96
171
  end
@@ -45,7 +45,7 @@ end
45
45
  The current state.
46
46
  @readonly
47
47
  @prop CameraState CameraState
48
- @within DefaultCamera
48
+ @within HeartbeatCamera
49
49
  ]=]
50
50
  function HeartbeatCamera:__index(index)
51
51
  if index == "CameraState" then
@@ -55,7 +55,7 @@ end
55
55
  The current state.
56
56
  @readonly
57
57
  @prop CameraState CameraState
58
- @within DefaultCamera
58
+ @within ImpulseCamera
59
59
  ]=]
60
60
  function ImpulseCamera:__index(index)
61
61
  if index == "CameraState" then
@@ -0,0 +1,69 @@
1
+ --[=[
2
+ Allows you to override the default camera with this cameras
3
+ information. Useful for custom camera controls that the user
4
+ controls.
5
+
6
+ ```lua
7
+ local combiner = OverrideDefaultCameraToo.new(effect, self._cameraStackService:GetRawDefaultCamera())
8
+ combiner.Predicate = function()
9
+ return self._cameraStateTweener:IsFinishedShowing()
10
+ end
11
+ ```
12
+
13
+ @class OverrideDefaultCameraToo
14
+ ]=]
15
+
16
+ local require = require(script.Parent.loader).load(script)
17
+
18
+ local SummedCamera = require("SummedCamera")
19
+
20
+ local OverrideDefaultCameraToo = {}
21
+ OverrideDefaultCameraToo.ClassName = "OverrideDefaultCameraToo"
22
+
23
+ --[=[
24
+ Initializes a new OverrideDefaultCameraToo
25
+
26
+ @param baseCamera Camera
27
+ @param defaultCamera DefaultCamera
28
+ @param predicate Filter on whether to override or not
29
+ ]=]
30
+ function OverrideDefaultCameraToo.new(baseCamera, defaultCamera, predicate)
31
+ local self = setmetatable({}, OverrideDefaultCameraToo)
32
+
33
+ self.BaseCamera = assert(baseCamera, "No baseCamera")
34
+ self.DefaultCamera = assert(defaultCamera, "No defaultCamera")
35
+ self.Predicate = predicate
36
+
37
+ return self
38
+ end
39
+
40
+ function OverrideDefaultCameraToo:__add(other)
41
+ return SummedCamera.new(self, other)
42
+ end
43
+
44
+ function OverrideDefaultCameraToo:__newindex(index, value)
45
+ if index == "BaseCamera" or index == "DefaultCamera" or index == "Predicate" then
46
+ rawset(self, index, value)
47
+ else
48
+ error(index .. " is not a valid member of OverrideDefaultCameraToo")
49
+ end
50
+ end
51
+
52
+ function OverrideDefaultCameraToo:__index(index)
53
+ if index == "CameraState" then
54
+ local result = self.BaseCamera.CameraState
55
+
56
+ local predicate = self.Predicate
57
+ if not predicate or predicate(result) then
58
+ self.DefaultCamera:SetRobloxCFrame(result.CFrame)
59
+ end
60
+
61
+ return result
62
+ elseif index == "BaseCamera" or index == "DefaultCamera" or index == "Predicate" then
63
+ return rawget(self, index)
64
+ else
65
+ return OverrideDefaultCameraToo[index]
66
+ end
67
+ end
68
+
69
+ return OverrideDefaultCameraToo
@@ -10,10 +10,10 @@ local require = require(script.Parent.loader).load(script)
10
10
 
11
11
  local CameraStackService = require("CameraStackService")
12
12
  local FadeBetweenCamera3 = require("FadeBetweenCamera3")
13
- local Maid = require("Maid")
14
13
  local ServiceBag = require("ServiceBag")
14
+ local BaseObject = require("BaseObject")
15
15
 
16
- local CameraStateTweener = {}
16
+ local CameraStateTweener = setmetatable({}, BaseObject)
17
17
  CameraStateTweener.ClassName = "CameraStateTweener"
18
18
  CameraStateTweener.__index = CameraStateTweener
19
19
 
@@ -26,13 +26,11 @@ CameraStateTweener.__index = CameraStateTweener
26
26
  @return CameraStateTweener
27
27
  ]=]
28
28
  function CameraStateTweener.new(serviceBag, cameraEffect, speed)
29
- local self = setmetatable({}, CameraStateTweener)
29
+ local self = setmetatable(BaseObject.new(), CameraStateTweener)
30
30
 
31
31
  assert(ServiceBag.isServiceBag(serviceBag), "No serviceBag")
32
32
  assert(cameraEffect, "No cameraEffect")
33
33
 
34
- self._maid = Maid.new()
35
-
36
34
  self._cameraStackService = serviceBag:GetService(CameraStackService)
37
35
  local cameraBelow, assign = self._cameraStackService:GetNewStateBelow()
38
36
 
@@ -86,6 +84,14 @@ function CameraStateTweener:IsFinishedHiding()
86
84
  return self._fadeBetween.HasReachedTarget and self._fadeBetween.Target == 0
87
85
  end
88
86
 
87
+ --[=[
88
+ Returns true if we're done showing
89
+ @return boolean
90
+ ]=]
91
+ function CameraStateTweener:IsFinishedShowing()
92
+ return self._fadeBetween.HasReachedTarget and self._fadeBetween.Target == 1
93
+ end
94
+
89
95
  --[=[
90
96
  Hides the tweener, and invokes the callback once the tweener
91
97
  is finished hiding.
@@ -172,12 +178,4 @@ function CameraStateTweener:GetFader()
172
178
  return self._fadeBetween
173
179
  end
174
180
 
175
- --[=[
176
- Cleans up the fader, preventing any animation at all
177
- ]=]
178
- function CameraStateTweener:Destroy()
179
- self._maid:DoCleaning()
180
- setmetatable(self, nil)
181
- end
182
-
183
181
  return CameraStateTweener