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
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