I’m making a game kind of like a 2d mario game but I have a problem! When the player jumps, the camera moves up with them so that they can no longer see the ground. I tried using the x and z coordinates of the HumanoidRootPart and an initial y position, but then the y position won’t update when they go up a hill or something. So basically I want to stop the camera from updating when they are jumping. Any help would be appreciated!
local Camera = game.Workspace.CurrentCamera
local LocalPlayer = game.Players.LocalPlayer
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
LocalPlayer.Character:WaitForChild("HumanoidRootPart")
Camera.CameraType = Enum.CameraType.Attach
Camera.CameraSubject = LocalPlayer.Character.HumanoidRootPart
Camera.FieldOfView = 20
local RunService = game:GetService("RunService")
local function onUpdate()
if LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("HumanoidRootPart") then
Camera.CFrame = CFrame.new(LocalPlayer.Character.HumanoidRootPart.Position) * CFrame.new(0, 6, 110)
end
end
RunService:BindToRenderStep("Camera", Enum.RenderPriority.Camera.Value, onUpdate)
The problem here is that the camera is locked to the HumanoidRootPart. You’d probably have to listen for a :GetPropertyChangedSignal() event and then once it starts, set a debounce to false and then wait for the FloorMaterial property to be set to not nil. Then set an if statement to determine whether the Y axis should be set or not.
local runService = game:GetService('RunService')
local humanoid = Character.Humanoid
local humanoidRootPart = Character.HumanoidRootPart
local currentCamera = workspace.CurrentCamera
local isJumping = false
local debounce = false
local calculateHeight = false
local initJumpHeight
local function MovementRenderStep()
if calculateHeight then
initJumpHeight = humanoidRootPart.Position.Y
end
currentCamera.CFrame = CFrame.new(humanoidRootPart.Position.X, 0, humanoidRootPart.Position.Z) * CFrame.new(0, initJumpHeight, 110)
end
humanoid:GetPropertyChangedSignal('Jump'):Connect(function()
if debounce == false then
debounce = true
calculateHeight = false
initJumpHeight = currentCamera.CFrame.Position.Y
repeat runService.RenderStepped.Wait() until humanoid.FloorMaterial ~= nil
calculateHeight = true
end
end
Thanks for the reply. You gave me a few ideas, but the main problem is that RenderStepped:wait() gives the player their normal camera for however long they’re in the air. I still need to update the Camera’s X and Z positions while the player is in the air with RenderStepped.
I figured this much out, but now I need a way to transition smoothly between the different Y values (Y value before the jump → Y value after the jump) because it looks very choppy:
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local Camera = game.Workspace.CurrentCamera
local LocalPlayer = game.Players.LocalPlayer
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local IsJumping = false
local PosX
local PosY
local PosZ
Camera.CameraType = Enum.CameraType.Attach
Camera.CameraSubject = LocalPlayer.Character.HumanoidRootPart
Camera.FieldOfView = 20
Humanoid.StateChanged:Connect(function(OldState, NewState)
if NewState == Enum.HumanoidStateType.Jumping then
if not IsJumping then
print("Jumping")
IsJumping = true
end
elseif NewState == Enum.HumanoidStateType.Landed then
if IsJumping then
print("Landed")
IsJumping = false
end
end
end)
local function onUpdate()
if LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("HumanoidRootPart") and IsJumping == false then
PosX = HumanoidRootPart.Position.X
PosY = HumanoidRootPart.Position.Y
PosZ = HumanoidRootPart.Position.Z
Camera.CFrame = CFrame.new(PosX,PosY,PosZ) * CFrame.new(0, 6, 110)
else --Player is in the air, don't update y position
PosX = HumanoidRootPart.Position.X
PosZ = HumanoidRootPart.Position.Z
Camera.CFrame = CFrame.new(PosX,PosY,PosZ) * CFrame.new(0, 6, 110)
end
end
RunService:BindToRenderStep("Camera", Enum.RenderPriority.Camera.Value, onUpdate)
Really I need to somehow tween/interpolate the camera between the jumping and landing positions. I was thinking maybe I could perform the Tween outside of the OnUpdate function and then set IsJumping back to false, but there’s no way to continuosly update the position during the tween, and a loop would look sloppy. There must be a better way to do this lol