-- Настройки
local isTesting = false -- Сделал название без пробела для корректной работы
local minDistance = -10
local maxDistance = 4
local rigidness = 0.6
-- Ссылки на объекты
local runService = game:GetService("RunService")
local player = game.Players.LocalPlayer
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
local rootPart = character:WaitForChild("HumanoidRootPart")
local head = character:WaitForChild("Head")
-- Создание детали CamPart
local camPart = Instance.new("Part")
camPart.Name = "CamPart"
camPart.CanCollide = false
camPart.Anchored = true
camPart.Shape = Enum.PartType.Ball
camPart.Size = Vector3.new(1, 1, 1) -- Уменьшил размер, чтобы не мешал
if not isTesting then
camPart.Transparency = 1
camPart.Parent = character
else
camPart.Color = Color3.fromRGB(0, 255, 0)
camPart.Parent = workspace
local highlight = Instance.new("Highlight")
highlight.Parent = camPart
highlight.FillColor = Color3.new(0, 0, 1)
end
-- Изначальная позиция
camPart.CFrame = head.CFrame
runService.RenderStepped:Connect(function(dt)
local camera = workspace.CurrentCamera
if not camera then return end
-- Защита от "улетания" координат (NaN или бесконечность)
if camPart.Position.Magnitude > 10000 then
camPart.CFrame = head.CFrame
end
-- Плавное движение CamPart к голове персонажа
-- Используем (1 - math.exp(-rigidness * dt * 10)) для идеально плавного Lerp при любом FPS
local alpha = math.clamp(rigidness * dt * 10, 0, 1)
camPart.Position = camPart.Position:Lerp(head.Position, alpha)
-- Поворачиваем CamPart в сторону головы
camPart.CFrame = camPart.CFrame:Lerp(CFrame.lookAt(camPart.Position, head.Position), alpha)
-- Вычисляем локальное смещение относительно RootPart
-- Это критический момент: мы смотрим, где находится CamPart относительно торса
local relativeVector = rootPart.CFrame:PointToObjectSpace(camPart.Position)
-- Коррекция высоты (так как камера обычно на уровне глаз, а не в центре торса)
local offset = relativeVector - Vector3.new(0, 1.5, 0)
-- Ограничение дистанции
local clampedX = math.clamp(offset.X, minDistance, maxDistance)
local clampedY = math.clamp(offset.Y, minDistance, maxDistance)
local clampedZ = math.clamp(offset.Z, minDistance, maxDistance)
-- Применяем смещение к камере через Humanoid
humanoid.CameraOffset = Vector3.new(clampedX, clampedY, clampedZ)
-- Логика "доворота" камеры, если смещение слишком большое
if offset.Magnitude > maxDistance / 2 then
local lookTarget = camera.CFrame:Lerp(CFrame.lookAt(camera.CFrame.Position, head.Position), 0.1)
camera.CFrame = camera.CFrame:Lerp(lookTarget, alpha)
end
end)