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

Can I do a camera interpolation if I'm already using BindToRenderStep on the camera? (2D)

Asked by 8 years ago

I've made a button that makes the player sidescroll (adds a camera-manipulating localscript and BodyPosition to lock the player on a 2D plane). I've also made a button that reverts you back into "3D" (default Roblox controls/camera), and another button that changes which axis the player is on, as well as adjusting the camera so it's still to the side of the player. So, if I were in "sidescrolling mode" on the Z axis, and I touched the axis button, I would switch to the X axis, and the camera would change position and turn 90 degrees. My current problem is that the camera doesn't transition when in "sidescrolling mode". The scripts "work" at a basic level, but I'd like to add transitions to make it look better. Here's the LocalScript I put into the player:

local player = game.Players.LocalPlayer
local camera = game.Workspace.CurrentCamera
local runService = game:GetService('RunService')

local function cameraUpdate()
    local playerPosition = player.Character.HumanoidRootPart.Position
    local offset = player.Character.Torso.camOffset.Value
    local cameraPosition = playerPosition + offset
    camera.CoordinateFrame = CFrame.new(cameraPosition, playerPosition)
end

runService:BindToRenderStep('Camera', Enum.RenderPriority.Camera.Value, cameraUpdate)

When a player touches an axis switcher, the "camOffset" Vector3 value is updated, and this script checks and updates the camera on each Render Step. Right now the camera switches from one angle to the other in a split-second, due to BindToRenderStep, but I'd like there to be an interpolation between the two angles. I'm not sure exactly how to go about adding transitions. I'd like to use :Interpolate, but I don't know if it works if I'm already updating the camera on each render step; sure, the camera would transition, but it would take 1/60th of a second, so it wouldn't be noticeable. Using Interpolate for the entire 2D camera system (instead of BindToRenderStep) is too choppy, and it lags behind the player if they're walking, and my game's speed-oriented, so that doesn't work well. Does Interpolate take priority over BindToRenderStep? Is there some way to override BindToRenderStep for 1 second to allow Interpolate to work unhindered?

(Here's the axis-switcher script, if it helps.)

name = "TwoD"
name2 = "camOffset"
script.Parent.LeftSurface = 'Weld'
script.Parent.BackSurface = 'Weld'
local directionVector = script.Parent.CFrame.lookVector
local direction = "zero"
local xVal = directionVector.x
local zVal = directionVector.z

function round(number)
    return math.floor(number + 0.5)
    --I'm not sure why Roblox doesn't have a round function.
end

local xValue = round(xVal)
local zValue = round(zVal)

if xValue == 0 then
    if zValue == -1 then
        direction = "-Z"
    elseif zValue == 1 then
        direction = "+Z"
    elseif zValue == 0 then print('broken')
    end
end

if zValue == 0 then
    if xValue == -1 then
        direction = "-X"
    elseif xValue == 1 then
        direction = "+X"
    elseif xValue == 0 then print('broken')
    end
end
local config = script.Parent.CameraConfig
local h = config.HorizontalOffset.Value
local v = config.VerticalOffset.Value

local positiveX = Vector3.new(h, v, 0)
local negativeX = Vector3.new(-h, v, 0)
local positiveZ = Vector3.new(0, v, h)
local negativeZ = Vector3.new(0, v, -h)

local e = true
function onTouched(part)
    if not e then return end
    local player = game.Players:GetPlayerFromCharacter(part.Parent)
    if player then
        e = false

        local _,move = pcall(function() return player.Character.Torso[name] end)
        local _,offset = pcall(function() return player.Character.Torso[name2] end)
        if type(move) ~= "string" and type(offset) ~= "string" then
            local switch = {
                [move.maxForce.x > 0] = Vector3.new(0,0,1000000),
                [move.maxForce.z > 0] = Vector3.new(1000000,0,0)
            }
            move.maxForce = switch[true]
            local cSwitch1 = { -- <V
                [offset.Value.x ~= 0] = positiveZ,
                [offset.Value.z ~= 0] = negativeX           
            }
            local cSwitch2 = { -- <^
                [offset.Value.x ~= 0] = negativeZ,
                [offset.Value.z ~= 0] = negativeX           
            }
            local cSwitch3 = { -- >^
                [offset.Value.x ~= 0] = negativeZ,
                [offset.Value.z ~= 0] = positiveX           
            }
            local cSwitch4 = { -- >V
                [offset.Value.x ~= 0] = positiveZ,
                [offset.Value.z ~= 0] = positiveX           
            }
            if direction == '-Z' then
                offset.Value = cSwitch1[true]
            elseif direction == '+X' then
                offset.Value = cSwitch2[true]
            elseif direction == '+Z' then
                offset.Value = cSwitch3[true]
            elseif direction == '-X' then
                offset.Value = cSwitch4[true]
            end
            script.Parent.BrickColor = BrickColor.new(11)
            move.position = script.Parent.Position + Vector3.new(0,10,0)
            wait(1)
            script.Parent.BrickColor = BrickColor.new(140)
        end
        e = true
    end
end

script.Parent.Touched:connect(onTouched)

Here's a place that uses the 2D system I'm talking about. The green button is the 2D button, and the dark blue bricks are the axis-switchers. http://www.roblox.com/games/359437813/Testing (Please comment if my questions don't make sense. It's kinda hard to explain.)

TL;DR How do I make the camera interpolate if I'm already using BindToRenderStep to move the camera?

1 answer

Log in to vote
0
Answered by 8 years ago

Use unbindtorenderedstepped to unbind the camera function, interpolate and using interpolationfinished bind to renderedstepped when finished.

0
Good enough for me.  MetaRyan 5 — 8y
Ad

Answer this question