Moving overhead camera makes the player die, and parts be removed from workspace

Hi,

I’m making a small game where the player will be able to own a drone where the camera will be located, and offer a view from above.

It worked well until I added the ability to control the altitude of the drone. Then, sometimes, the game goes completely nuts:

  • the player’s HumanoidRootPart’s CFrame becomes NAN, NAN, NAN…
  • then the player’s HumanoidRootParts disapppears from Workspace (player dies, it seems)
  • actually many of the parts in Workspace are removed
  • the game shows the screen “Gameplay Paused”

It’s rather simple to trigger with the following LocalScript. Just press ‘F’ and wait a couple seconds.

local UserInputService = game:GetService("UserInputService")


local Players = game:GetService("Players")
local player = Players.LocalPlayer


local drone = false
local drone_follow = false
local drone_altitude = 40

local function handleKeyPressed(keycode: Enum.KeyCode)
	if keycode == Enum.KeyCode.F then
		drone = not drone
		print("DRONE:", drone)
		if drone then
			task.wait(1)
			drone_follow = true
		end
	elseif keycode == Enum.KeyCode.T then
		drone_altitude += 5
		print("New altitude ", drone_altitude)
	elseif keycode == Enum.KeyCode.G then
		drone_altitude -= 10
	end
end

-- Listen to key down
UserInputService.InputBegan:Connect(function(io:InputObject, gameProcessed: boolean)
	if io.UserInputType == Enum.UserInputType.Keyboard then
		if (UserInputService:GetFocusedTextBox()) then
			return; -- make sure player's not chatting!
		end
		handleKeyPressed(io.KeyCode)
	end
end)

local RunService = game:GetService("RunService")

local dronespeed = 1.5

RunService.Heartbeat:Connect(function(step)

	if drone and drone_follow then
		local hrp = player.Character:FindFirstChild("HumanoidRootPart")
		if not hrp then
			print("HRP disappeared !!!")
			drone = false
			return
		end
		local camera = workspace.CurrentCamera
		camera.CameraType = Enum.CameraType.Scriptable
		local cf = hrp.CFrame :: CFrame

		print("IN camera cframe got", camera.CFrame, "with hrp at", cf)
		local want_target = cf.Position + cf.LookVector.Unit * 10
		local h = drone_altitude
		local want_camera_pos = want_target + Vector3.new(0, h, 0)
		local diff_pos = want_camera_pos - camera.CFrame.Position
		local newpos = camera.CFrame.Position + step * dronespeed * diff_pos
		local newtarget = newpos - Vector3.new(0, h, 0) -- wrong y but who cares
		camera.CFrame = CFrame.lookAt(newpos, newtarget, Vector3.xAxis)
		print("OUT camera cframe now", camera.CFrame)
	end

end)

while true do
	task.wait(2)
	if drone then
		drone_altitude += 1
		print("New altitude ", drone_altitude)

	end
end

Try this, you can create a separate part or object in the workspace to represent the drone’s position and use that as a reference for updating the camera’s CFrame.

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer

local drone = false
local drone_follow = false
local drone_altitude = 40

local function handleKeyPressed(keycode)
    if keycode == Enum.KeyCode.F then
        drone = not drone
        print("DRONE:", drone)
        if drone then
            task.wait(1)
            drone_follow = true
        end
    elseif keycode == Enum.KeyCode.T then
        drone_altitude = drone_altitude + 5
        print("New altitude ", drone_altitude)
    elseif keycode == Enum.KeyCode.G then
        drone_altitude = drone_altitude - 10
    end
end

UserInputService.InputBegan:Connect(function(io, gameProcessed)
    if io.UserInputType == Enum.UserInputType.Keyboard then
        if UserInputService:GetFocusedTextBox() then
            return
        end
        handleKeyPressed(io.KeyCode)
    end
end)

local RunService = game:GetService("RunService")
local dronespeed = 1.5

RunService.Heartbeat:Connect(function(step)
    if drone and drone_follow then
        local dronePart = workspace:FindFirstChild("DronePart")
        if not dronePart then
            print("DronePart disappeared !!!")
            drone = false
            return
        end
        local camera = workspace.CurrentCamera
        camera.CameraType = Enum.CameraType.Scriptable
        local cf = dronePart.CFrame
        local want_target = cf.Position + cf.LookVector * 10
        local h = drone_altitude
        local want_camera_pos = want_target + Vector3.new(0, h, 0)
        local diff_pos = want_camera_pos - camera.CFrame.Position
        local newpos = camera.CFrame.Position + step * dronespeed * diff_pos
        local newtarget = newpos - Vector3.new(0, h, 0)
        camera.CFrame = CFrame.lookAt(newpos, newtarget, Vector3.new(0, 1, 0))
    end
end)

while true do
    task.wait(2)
    if drone then
        drone_altitude = drone_altitude + 1
        print("New altitude ", drone_altitude)
    end
end

Thanks for your reply, but I don’t really see how that’s going to work for me, since I want the camera to follow the player.

Besides, what I’m really interested in is to understand what’s going on. So far i’m inclined to believe this is a bug in Roblox.

Use RunService.Heartbeat so it keeps the characters position updated for the drone to follow

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer

local drone = false
local drone_follow = false
local drone_altitude = 40

local function handleKeyPressed(keycode)
    if keycode == Enum.KeyCode.F then
        drone = not drone
        print("DRONE:", drone)
        if drone then
            task.wait(1)
            drone_follow = true
        end
    elseif keycode == Enum.KeyCode.T then
        drone_altitude = drone_altitude + 5
        print("New altitude ", drone_altitude)
    elseif keycode == Enum.KeyCode.G then
        drone_altitude = drone_altitude - 10
    end
end

UserInputService.InputBegan:Connect(function(io, gameProcessed)
    if io.UserInputType == Enum.UserInputType.Keyboard then
        if UserInputService:GetFocusedTextBox() then
            return
        end
        handleKeyPressed(io.KeyCode)
    end
end)

local RunService = game:GetService("RunService")
local dronespeed = 1.5

RunService.Heartbeat:Connect(function(step)
    if drone and drone_follow then
        local character = player.Character
        if not character then
            print("Character not found !!!")
            drone = false
            return
        end
        local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
        if not humanoidRootPart then
            print("HumanoidRootPart not found !!!")
            drone = false
            return
        end
        local playerPosition = humanoidRootPart.Position
        local camera = workspace.CurrentCamera
        camera.CameraType = Enum.CameraType.Scriptable
        local want_target = playerPosition + Vector3.new(0, 5, 10)
        local h = drone_altitude
        local want_camera_pos = want_target + Vector3.new(0, h, 0)
        local diff_pos = want_camera_pos - camera.CFrame.Position
        local newpos = camera.CFrame.Position + step * dronespeed * diff_pos
        local newtarget = newpos - Vector3.new(0, h, 0)
        camera.CFrame = CFrame.lookAt(newpos, newtarget, Vector3.new(0, 1, 0))
    end
end)

while true do
    task.wait(2)
    if drone then
        drone_altitude = drone_altitude + 1
        print("New altitude ", drone_altitude)
    end
end

Thanks VVshenok, but I don’t think you really understood my issue, possibly I did not explain clearly enough.

What I want to know is : how/why does updating the camera position cause the player to die and parts of workspace to be deleted ?