· 6 years ago · May 27, 2019, 04:42 AM
1-- V.3
2
3--[[Created by SteadyOn, FIXED ENTIRELY BY JUNIORJFUCKINGFIVE: trash module, wont recommend 0/10 -ign
4 THIS MODULE MUST BE IN REPLICATEDSTORAGE - YOU NEED TO REQUIRE THIS MODULE SOMEWHERE ON THE CLIENT:
5 require(game.ReplicatedStorage.ReplicatedTweening)
6 Documentation:
7 :GetTweenObject(instance [Instance], TweenInfo [TweenInfo Object], PropertyTable [Table]) [Tween]
8 Parameters are exactly the same as TweenService:Create(), it returns a fake Tween object with Play,
9 Pause and Stop functions.
10 Tween:Play(Yield [Boolean, optional], Player [Player Object, optional])
11 Runs the tween. The player parameter will only play the tween for that specific player.
12 The Yield parameter specifies whether the function should yield until the tween has completed or not.
13
14 Tween:QueuePlay(Yield [Boolean, optional], Player [Player Object, optional]) - Add the tween to a tween queue which will start
15 playing the queue automatically immediately after the previous tween on that instance completes. Behaves exactly the same way as
16 Tween:Play() once started, except the initial firing of the tween is managed on the client. For this reason, best practice is to
17 fire this event as close to when you would like it to be played on the client to maintain alignment between tweens. If fired
18 multiple times in a short time frame, this may result in clients becoming out of sync over time.
19 Tween:Stop(Player [Player Object, optional])
20 Stops the tween. The player parameter will only stop the tween for that specific player.
21 Tween:Pause(Player [Player Object, optional])
22 Pauses the tween. The player parameter will only pause the tween for that specific player.
23
24 Tutorial:
25 To set up, you just need to put 'require(game.ReplicatedStorage.ReplicatedTweening)' somewhere in
26 a LocalScript, if you don't have one yet, just create a new one. Also make sure to put this module
27 into ReplicatedStorage.
28 To use this module, first require it (e.g. require(game.ReplicatedStorage.ReplicatedTweening)).
29 To get the tween object you must first call :GetTweenObject(), this returns a fake Tween object.
30 Use this object to play, stop and pause the tween by using Play(), Stop(), Pause()
31 as functions of the Tween object (e.g. Tween:Play()).
32 You can also enter a player as the first parameter of each of these functions
33 to stop, play or pause the tween only for that specific player.
34 Example code:
35 local CustomTweenService = require(game.ReplicatedStorage.ReplicatedTweening)
36 local tweenInfo = TweenInfo.new(2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
37 local tween = CustomTweenService:GetTweenObject(game.Workspace.Part, tweenInfo, {CFrame = CFrame.new(Vector3.new(0,0,0))})
38 tween:Play()
39--]]
40
41local module = {}
42local tService = game:GetService("TweenService")
43local rService = game:GetService("RunService")
44local tEvent
45
46if tEvent == nil and rService:IsServer() then
47 tEvent = Instance.new("RemoteEvent", script)
48 tEvent.Name = "TweenEvent"
49else
50 tEvent = script:WaitForChild("TweenEvent")
51end
52
53local function TweenInfo_To_Table(tInfo)
54 local info = {}
55 info[1] = tInfo.Time or 1
56 info[2] = tInfo.EasingStyle or Enum.EasingStyle.Quad
57 info[3] = tInfo.EasingDirection or Enum.EasingDirection.Out
58 info[4] = tInfo.RepeatCount or 0
59 info[5] = tInfo.Reverses or false
60 info[6] = tInfo.DelayTime or 0
61 return info
62end
63
64local function Table_To_TweenInfo(tbl)
65 return TweenInfo.new(unpack(tbl))
66end
67
68local function serverAssignProperties(instance, properties)
69 --print("Assigning properties")
70 for property, value in pairs (properties) do
71 --print("Assigned", property, "to", value)
72 instance[property] = value
73 end
74end
75
76local latestFinish = {} -- this table operates on both the client and the server, server side it only stores GLOBAL tweens, local side it stores every local tween.
77
78function module:GetTweenObject(instance, tInfo, propertyTable)
79 local eventObject = Instance.new("BindableEvent")
80 local completed = false
81
82 local tweenMaster = {}
83 tweenMaster.Completed = eventObject.Event
84 tweenMaster.DontUpdate = {} -- table of specific players that it stopped for part way.
85 tInfo = TweenInfo_To_Table(tInfo)
86
87 local function Play(Yield, SpecificClient, Queue) -- this is on it's own as it needs to be called by both QueuePlay and Play
88 local now = tick()
89
90 local finishTime = now+tInfo[1]
91 local waitTime = tInfo[1]
92
93 latestFinish[instance] = latestFinish[instance] or now -- cannot be nil.
94 Queue = Queue or false
95 tweenMaster.Paused = false
96
97 if SpecificClient == nil and not Queue then
98 latestFinish[instance] = finishTime -- adds an entry to array with finish time of this tween (used for queueing)
99 tEvent:FireAllClients("RunTween", instance, tInfo, propertyTable)
100 elseif Queue and SpecificClient == nil then -- deal with queued tweens
101 waitTime = waitTime + (latestFinish[instance] - now)
102 latestFinish[instance] = finishTime + (latestFinish[instance] - now) -- adds an entry to array with finish time of this tween (used for queueing)
103 tEvent:FireAllClients("QueueTween", instance, tInfo, propertyTable)
104 elseif Queue then
105 tEvent:FireClient("QueueTween", instance, tInfo, propertyTable) -- queue tween for specific player
106 else
107 tEvent:FireClient("RunTween", instance, tInfo, propertyTable) -- play tween for specific player
108 end
109
110 if Yield and SpecificClient == nil then
111 local i, existingFinish = 0, latestFinish[instance]
112 --repeat wait(1/30) i = i + 1/30 until i >= waitTime or tweenMaster.Stopped
113 local pausedOffset, pausedTick = 0
114
115 while (tick() - now) < waitTime+pausedOffset do
116 if tweenMaster.Paused then
117 if not pausedTick then
118 pausedTick = tick()
119 end
120 pausedOffset = (tick() - pausedTick)
121 else
122 pausedTick = nil
123 end
124 if tweenMaster.Stopped then break end
125 i = (tick()-now) + pausedOffset
126 wait(0)
127 end
128 --print("a", i)
129
130 if not completed and not tweenMaster.Stopped then
131 eventObject:Fire()
132 completed = true
133 end
134 if latestFinish[instance] == existingFinish then
135 latestFinish[instance] = nil -- clear memory if this instance hasn't already been retweened.
136 end
137 if tweenMaster.Paused == nil or tweenMaster.Paused == false then
138 serverAssignProperties(instance, propertyTable) -- assign the properties server side
139 end
140 return
141 elseif SpecificClient == nil then
142 spawn(function()
143 local i, existingFinish = 0, latestFinish[instance]
144 --repeat wait(1/30) i = i + 1/30 until i >= waitTime or tweenMaster.Stopped
145 local pausedOffset, pausedTick = 0
146
147 while (tick() - now) < waitTime+pausedOffset do
148 if tweenMaster.Paused then
149 if not pausedTick then
150 pausedTick = tick()
151 end
152 pausedOffset = (tick() - pausedTick)
153 else
154 pausedTick = nil
155 end
156 if tweenMaster.Stopped then break end
157 i = (tick()-now) + pausedOffset
158 wait(0)
159 end
160 --print("b", i)
161
162 if not completed and not tweenMaster.Stopped then
163 eventObject:Fire()
164 completed = true
165 end
166 if latestFinish[instance] == existingFinish then
167 latestFinish[instance] = nil -- clear memory if this instance hasn't already been retweened.
168 end
169 if tweenMaster.Paused == nil or tweenMaster.Paused == false then
170 serverAssignProperties(instance, propertyTable) -- assign the properties server side
171 end
172 end)
173 end
174 end
175
176 function tweenMaster:Play(Yield, SpecificClient)
177 Play(Yield, SpecificClient)
178 end
179
180 function tweenMaster:QueuePlay(Yield, SpecificClient)
181 Play(Yield, SpecificClient, true)
182 end
183
184 function tweenMaster:Pause(SpecificClient)
185 if SpecificClient == nil then
186 tweenMaster.Paused = true
187 tEvent:FireAllClients("PauseTween", instance)
188 else
189 table.insert(tweenMaster.DontUpdate, SpecificClient)
190 tEvent:FireClient("PauseTween", instance)
191 end
192 end
193
194 function tweenMaster:Resume(SpecificClient)
195 if not SpecificClient then
196 tweenMaster.Paused = false
197 tEvent:FireAllClients("ResumeTween", instance)
198 else
199 for i, v in next, tweenMaster.DontUpdate do
200 if v == SpecificClient then
201 tweenMaster.DontUpdate[i] = nil
202 end
203 end
204 tEvent:FireClient("ResumeTween", instance)
205 end
206 end
207
208 function tweenMaster:Stop(SpecificClient)
209 if SpecificClient == nil then
210 tweenMaster.Stopped = true
211 tEvent:FireAllClients("StopTween", instance)
212 else
213 tEvent:FireClient("StopTween", instance)
214 end
215 end
216 return tweenMaster
217end
218
219
220if rService:IsClient() then -- OnClientEvent only works clientside
221 local runningTweens = {}
222
223 tEvent.OnClientEvent:Connect(function(purpose, instance, tInfo, propertyTable)
224 if tInfo ~= nil then
225 tInfo = Table_To_TweenInfo(tInfo)
226 end
227
228 local function runTween(queued)
229
230 local now = tick()
231 local finishTime = now+tInfo.Time
232 latestFinish[instance] = latestFinish[instance] or now -- cannot be nil.
233
234 local existingFinish = latestFinish[instance]
235 if queued and latestFinish[instance] >= now then
236 local waitTime = (latestFinish[instance] - now)
237 latestFinish[instance] = finishTime + waitTime
238 existingFinish = latestFinish[instance]
239 wait(waitTime)
240 else
241 latestFinish[instance] = finishTime
242 end
243
244 if runningTweens[instance] ~= nil then -- im aware this will pick up paused tweens, however it doesn't matter
245 runningTweens[instance]:Cancel() -- stop previously running tween to run this one
246 warn("Canceled a previously running tween to run requested tween")
247 end
248
249 local tween = tService:Create(instance, tInfo, propertyTable)
250 runningTweens[instance] = tween
251 tween:Play()
252 --print("TweenStarted",tick(),existingFinish)
253 --wait(tInfo.Time or 1)
254 --print("TweenComplete",tick(),existingFinish)
255 tween.Completed:Connect(function()
256 --print("client completed")
257 if latestFinish[instance] == existingFinish then
258 latestFinish[instance] = nil -- clear memory if this instance hasn't already been retweened.
259 end
260 if runningTweens[instance] == tween then -- make sure it hasn't changed to a different tween
261 runningTweens[instance] = nil -- remove to save memory
262 end
263 end)
264 end
265
266 if purpose == "RunTween" then
267 runTween()
268 elseif purpose == "QueueTween" then
269 runTween(true) -- run as a queued tween
270 elseif purpose == "StopTween" then
271 if runningTweens[instance] ~= nil then -- check that the tween exists
272 runningTweens[instance]:Cancel()--:Stop() -- stop the tween
273 runningTweens[instance] = nil -- delete from table
274 else
275 warn("Tween being stopped does not exist.")
276 end
277 elseif purpose == "ResumeTween" then
278 if runningTweens[instance] ~= nil then
279 runningTweens[instance]:Play()
280 else
281 warn("Tween being resumed does not exist.")
282 end
283 elseif purpose == "PauseTween" then
284 if runningTweens[instance] ~= nil then -- check that the tween exists
285 runningTweens[instance]:Pause() -- pause the tween
286 else
287 warn("Tween being paused does not exist.")
288 end
289 end
290 end)
291end
292
293return module