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?