This repository has been archived by the owner on Oct 21, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathReplay.lua
178 lines (160 loc) · 4.61 KB
/
Replay.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
--[[
Replay Module V1.0
Author: Hexcede
Docs:
Replay
[description]
The main api
Recording Replay:BeginRecording(recordingSettings)
[description]
Returns a Recording object and starts recording to it
Table recordingSettings
ViewportFrame Frame
[description]
A viewport frame to render the replay and preview (if applicable) to
function GetInstances(recordingSettings)
return listOfInstancesToRecord
end
[default]
workspace:GetDescendants()
[description]
A function which returns a list of instances to record
boolean LiveReplay
[default]
false
[description]
Should a preview of the recording be shown in the ReplayFrame?
Recording
[description]
An api for replaying, stopping, controlling, etc replays
Recording:Stop()
[description]
Stops a recording
Recording:Replay(speed)
[description]
Replay a recording at speed
Float speed
[default]
1.0
[description]
The speed multiplier
Recording:Destroy()
[description]
Delete all replay information and cleanup replay instances
Always call this when you have no need to replay a recording anymore to save memory and improve user performance
--]]
local replay = {}
function replay:BeginRecording(recordingSettings)
recordingSettings = recordingSettings or {}
local frame = recordingSettings.Frame
if not frame then
error("You must provide a ViewportFrame for the replay!")
end
local recording = {}
local data = {}
data.Header = {}
data.BaseParts = {}
data.CFrames = {}
data.Header.RecordingStarted = tick()
data.Header.RecordingStopped = false
local recorderEvent
recorderEvent = game:GetService("RunService").RenderStepped:Connect(function()
local t = tick()
local instances
if recordingSettings.GetInstances then
instances = recordingSettings:GetInstances()
else
instances = workspace:GetDescendants()
end
for _, ch in ipairs(instances) do
pcall(function()
if ch:IsA("BasePart") then
local cl = data.BaseParts[ch] or (function()
local cl = ch:Clone()
for _, ch2 in ipairs(cl:GetChildren()) do
if not ch2:IsA("DataModelMesh") then
ch2:Destroy()
end
end
if recordingSettings.LiveReplay then
cl.Parent = frame
end
return cl
end)()
data.BaseParts[ch] = cl
data.CFrames[cl] = data.CFrames[cl] or {}
data.CFrames[cl][t] = ch.CFrame
cl.CFrame = ch.CFrame
elseif ch:IsA("Camera") then
local cl = data.Camera or (function()
local cam = Instance.new("Camera")
cam.Parent = frame
if recordingSettings.LiveReplay then
frame.CurrentCamera = cam
end
return cam
end)()
data.Camera = cl
data.CFrames[cl] = data.CFrames[cl] or {}
data.CFrames[cl][t] = ch.CFrame
cl.CFrame = ch.CFrame
end
end)
end
end)
function recording:Stop()
if not data.Header.RecordingStopped then
data.Header.RecordingStopped = tick()
recorderEvent:Disconnect()
end
end
function recording:Replay(speed)
local twS = game:GetService("TweenService")
speed = speed or 1
local pointer = data.Header.RecordingStarted
local cache = {}
while pointer < data.Header.RecordingStopped do
pointer = pointer + game:GetService("RunService").RenderStepped:Wait()*speed
coroutine.wrap(function()
local cframes = data.CFrames[data.Camera]
local currentCF = data.Camera.CFrame
for t, cf in pairs(cframes) do
cache[data.Camera] = cache[data.Camera] or {}
if pointer >= t and not cache[data.Camera][cf] then
cache[data.Camera][cf] = true
currentCF = cf
break
end
end
twS:Create(data.Camera, TweenInfo.new(1/60/speed), {CFrame=currentCF}):Play()
end)()
coroutine.wrap(function()
for ch, cl in pairs(data.BaseParts) do
local cframes = data.CFrames[cl]
local currentCF = cl.CFrame
for t, cf in pairs(cframes) do
cache[cl] = cache[cl] or {}
if pointer >= t and not cache[cl][cf] then
cache[cl][cf] = true
currentCF = cf
break
end
end
twS:Create(cl, TweenInfo.new(1/60/speed), {CFrame=currentCF}):Play()
end
end)()
end
end
function recording:Destroy()
data.Camera:Destroy()
data.Camera = nil
for ch, cl in pairs(data.BaseParts) do
cl:Destroy()
end
data.BaseParts = nil
data.CFrames = nil
data.Header = nil
end
return recording
end
return replay