Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How do I make good, smooth, epic cutscenes?

Asked by 6 years ago

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.

0
Updated my response with a small example. Futureprompt 55 — 6y

2 answers

Log in to vote
1
Answered by 6 years ago
Edited 6 years ago

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)
0
Thank you for posting this, perhaps I can apply this principle to my water slides own project. penguim2 0 — 3y
Ad
Log in to vote
0
Answered by 6 years ago

QUESTION CLOSED!

Answer this question