Ok so, I've tried many Models to make cutscenes but they don't work or aren't that smooth. Does anyone know how to make smooth cutscenes or find good cutscene plugins? And what I mean by "smooth", is some plugins like for example, CloneTrooper1019's "Cutscene Plugin" don't have smooth transitioning throughout your cutscene.
If you want a smooth, flowing camera, you'll have to use a bit of math.
The simplest way to do it is to use polynomial interpolation. The polynomial means that it's between multiple points, not just two.
Polynomial interpolation will allow you to generate a curve that goes through each coordinate point you want. As for rotation..? You'll have to use something else.
Here is a Lua Catmull-Rom script made by pr0digy. You can modify it in ROBLOX to move the camera between points.
This right here calculates the main part. The interpolation:
x = 0.5 * ( ( 2 * p1.x ) + ( p2.x - p0.x ) * t + ( 2 * p0.x - 5 * p1.x + 4 * p2.x - p3.x ) * t * t + ( 3 * p1.x - p0.x - 3 * p2.x + p3.x ) * t * t * t ) y = 0.5 * ( ( 2 * p1.y ) + ( p2.y - p0.y ) * t + ( 2 * p0.y - 5 * p1.y + 4 * p2.y - p3.y ) * t * t + ( 3 * p1.y - p0.y - 3 * p2.y + p3.y ) * t * t * t )
Instead of creating a spline, you can use it similar to :lerp()
, where you can use a value between 0 and 1 (start and end).
Instead of creating a circle (which isn't ROBLOX), like so:
function draw( points ) for i = 1, #points do local point = points[i] display.newCircle(point.x, point.y, 2) end end
You'll want to set the camera to the point where the new circle would have been created.
Even then, that won't be smooth.
You'll have to incorporate a RenderStepped loop and possibly :lerp()
between the points generated by the script.
Here's a very simple code which will do what you want, but won't return to the player after. It is inside a LocalScript inside of StarterGUI:
-- The following is by pr0digy. (Added Z-axis) function smooth( points, steps ) if #points < 3 then return points end local steps = steps or 5 local spline = {} local count = #points - 1 local p0, p1, p2, p3, x, y, z for i = 1, count do if i == 1 then p0, p1, p2, p3 = points[i], points[i], points[i + 1], points[i + 2] elseif i == count then p0, p1, p2, p3 = points[#points - 2], points[#points - 1], points[#points], points[#points] else p0, p1, p2, p3 = points[i - 1], points[i], points[i + 1], points[i + 2] end for t = 0, 1, 1 / steps do x = 0.5 * ( ( 2 * p1.X ) + ( p2.X - p0.X ) * t + ( 2 * p0.X - 5 * p1.X + 4 * p2.X - p3.X ) * t * t + ( 3 * p1.X - p0.X - 3 * p2.X + p3.X ) * t * t * t ) y = 0.5 * ( ( 2 * p1.Y ) + ( p2.Y - p0.Y ) * t + ( 2 * p0.Y - 5 * p1.Y + 4 * p2.Y - p3.Y ) * t * t + ( 3 * p1.Y - p0.Y - 3 * p2.Y + p3.Y ) * t * t * t ) z = 0.5 * ( ( 2 * p1.Z ) + ( p2.Z - p0.Z ) * t + ( 2 * p0.Z - 5 * p1.Z + 4 * p2.Z - p3.Z ) * t * t + ( 3 * p1.Z - p0.Z - 3 * p2.Z + p3.Z ) * t * t * t ) if not(#spline > 0 and spline[#spline].X == x and spline[#spline].Y == y and spline[#spline].Z == y) then table.insert(spline, Vector3.new(x, y, z)) end end end return spline end -- The following is by Futureprompt -- each value of points is a Vector3. Add as many as you need. local points = {game.Workspace.Points.P1.Position, game.Workspace.Points.P2.Position, game.Workspace.Points.P3.Position, game.Workspace.Points.P4.Position} -- the more steps you have, the smoother the movement will be. local spline = smooth(points, 100) repeat wait() until game.Players.LocalPlayer.Character local cam = game.Workspace.CurrentCamera cam.CameraType = Enum.CameraType.Scriptable -- iterator, since we're using a RenderStepped 'loop' i = 1 game:GetService("RunService").RenderStepped:Connect(function() if i < #spline then cam.CoordinateFrame = CFrame.new(spline[i], game.Workspace.Points.LookAt.Position) i = i + 1 end end)