i’ve modified the isometric camera from roblox’s code samples to include support for camera shaking and rotating your character toward your mouse. however, what really stumps me is that sometimes, for no reason at all, it will inexplicably just… break? it angles the camera downwards, but still acts like the default camera and lets me move the camera around slightly before snapping it back?
this is what is supposed to happen.
this is what happens sometimes. it’s very inconsistent and somewhat buggy.
here is what the script looks like.
local services = {
Players = game:GetService("Players");
ReplicatedStorage = game:GetService("ReplicatedStorage");
RunService = game:GetService("RunService");
SoundService = game:GetService("SoundService");
}
local player = services.Players.LocalPlayer
local camera = workspace.CurrentCamera
local module_folder = services.ReplicatedStorage:WaitForChild("modules")
local explosion_distance = 65
local camera_depth = 64
local height_offset = 2
local field_of_view = 20
local function kaboom(explosion)
local camera_shaker = require(module_folder:WaitForChild("CameraShaker"))
local cam_shake = camera_shaker.new(Enum.RenderPriority.Camera.Value, function(shake_cframe)
if camera then
camera.CFrame = camera.CFrame * shake_cframe
end
end)
if explosion:IsA("Explosion") then
local distance = (player.Character.Head.Position - explosion.Position).magnitude
local intensity = distance / (explosion.BlastRadius / 6)
if intensity < explosion_distance then
if cam_shake then
cam_shake:Start()
cam_shake:ShakeOnce(explosion.BlastRadius / 2, 12, 0.15, 1.4)
end
end
end
end
local function update_camera()
local character = player.Character
if character then
local root_part = character:FindFirstChild("HumanoidRootPart")
local head = character:FindFirstChild("Head")
if root_part and head then
services.SoundService:SetListener(Enum.ListenerType.CFrame, head.CFrame)
local player_position = root_part.Position + Vector3.yAxis * height_offset
local camera_position = player_position + Vector3.one * camera_depth
camera.CFrame = CFrame.lookAt(camera_position, player_position)
local obscuring_parts = camera:GetPartsObscuringTarget({root_part.Position}, character:GetChildren())
if #obscuring_parts > 0 then
local highlight = character:FindFirstChildWhichIsA("Highlight")
if not highlight then
local highlight = Instance.new("Highlight")
highlight.Parent = character
highlight.OutlineTransparency = 0.45
highlight.FillColor = Color3.fromRGB(59, 58, 67)
highlight.FillTransparency = 0.86
end
else
local highlight = character:FindFirstChildWhichIsA("Highlight")
if highlight then highlight:Destroy() end
end
end
end
end
local function handle_mouse()
local character = player.Character
local mouse = player:GetMouse()
if character then
local root_part = character:FindFirstChild("HumanoidRootPart")
if root_part then
local obscuring_parts = camera:GetPartsObscuringTarget({root_part.Position}, character:GetChildren())
local highlight = character:FindFirstChildWhichIsA("Highlight")
if #obscuring_parts > 0 then
if not highlight then
highlight = Instance.new("Highlight")
highlight.Parent = character
highlight.OutlineTransparency = 0.45
highlight.FillColor = Color3.fromRGB(59, 58, 67)
highlight.FillTransparency = 0.86
end
else
if highlight then
highlight:Destroy()
end
end
local function ray_plane(plane_point, plane_normal, origin, direction)
return -((origin - plane_point):Dot(plane_normal)) / (direction:Dot(plane_normal))
end
local function create_body_gyro(parent)
local body_gyro = Instance.new("BodyGyro")
body_gyro.Parent = parent
body_gyro.D = 55
body_gyro.P = 5000
body_gyro.MaxTorque = Vector3.new(4000000, 4000000, 4000000)
print("gyro created, delicious!")
return body_gyro
end
local function update_body_gyro(body_gyro, target_cframe)
if body_gyro then
body_gyro.CFrame = body_gyro.CFrame:lerp(target_cframe, 0.09)
end
end
local ray = camera:ScreenPointToRay(mouse.X, mouse.Y)
local t = ray_plane(character.Head.Position, Vector3.new(0, 1, 0), ray.Origin, ray.Direction)
local head = character:WaitForChild("Head")
local body_gyro = head:FindFirstChildOfClass("BodyGyro") or create_body_gyro(head)
local plane_intersection_point = (ray.Direction * t) + ray.Origin
local target_cframe = CFrame.lookAt(head.Position, plane_intersection_point)
update_body_gyro(body_gyro, target_cframe)
end
end
end
camera.FieldOfView = field_of_view
camera.CameraType = Enum.CameraType.Scriptable
workspace.DescendantAdded:Connect(kaboom)
services.RunService:BindToRenderStep("Camera", Enum.RenderPriority.Camera.Value, update_camera)
services.RunService:BindToRenderStep("Mouse", Enum.RenderPriority.Last.Value, handle_mouse)