Загрузка данных


local sensitivity_pc = 0.8
local sensitivity_mobile = 1.5
local first_person_key = Enum.KeyCode.F

local head_hig = 1.2
local forw_offset = 0.8

local max_angl = math.rad(100)
local mouse_cursor = false
local smoth = 0.15

local first_person_fov = 70
local third_person_fov = 60

local walk_bob_speed = 8
local walk_bob_amount = 0.035
local run_bob_speed = 12
local run_bob_amount = 0.06
local side_bob_amount = 0.035

local uis = game:GetService("UserInputService")
local runService = game:GetService("RunService")

local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera

local cur_pit = 0
local cu_ya = 0
local targ_pic = 0
local targ_ya = 0

local drag_cam = false
local last_tou = Vector2.new(0, 0)
local fir_pes = true
local dis_3 = 8
local thirdPersonHeight = 2

local sensa = uis.TouchEnabled and sensitivity_mobile or sensitivity_pc

local hide_parts = {}

local crosshairGui
local crosshair

local function hideHeadAndAccessories(character)
	hide_parts = {}

	local head = character:FindFirstChild("Head")

	if head then
		head.LocalTransparencyModifier = 1
		table.insert(hide_parts, head)

		local face = head:FindFirstChild("face")

		if face and face:IsA("Decal") then
			face.Transparency = 1
			table.insert(hide_parts, face)
		end
	end

	for _, accessory in character:GetDescendants() do
		if accessory:IsA("Accessory") then
			local handle = accessory:FindFirstChild("Handle")

			if handle then
				local weld =
					handle:FindFirstChildOfClass("Weld")
					or handle:FindFirstChildOfClass("WeldConstraint")
					or handle:FindFirstChildOfClass("Motor6D")

				if weld then
					local part0 = weld.Part0
					local part1 = weld.Part1

					if (part0 and part0.Name == "Head") or (part1 and part1.Name == "Head") then
						handle.LocalTransparencyModifier = 1
						table.insert(hide_parts, handle)
					end
				end
			end
		end
	end
end

local function showHeadAndAccessories()
	for _, part in hide_parts do
		if part and part.Parent then
			if part:IsA("Decal") then
				part.Transparency = 0
			else
				part.LocalTransparencyModifier = 0
			end
		end
	end

	hide_parts = {}
end

local function createCrosshair()
	if crosshairGui then
		crosshairGui:Destroy()
	end

	crosshairGui = Instance.new("ScreenGui")
	crosshairGui.Name = "CrosshairGui"
	crosshairGui.ResetOnSpawn = false
	crosshairGui.IgnoreGuiInset = true
	crosshairGui.Parent = player:WaitForChild("PlayerGui")

	crosshair = Instance.new("TextLabel")
	crosshair.Name = "Crosshair"
	crosshair.Size = UDim2.new(0, 20, 0, 20)
	crosshair.Position = UDim2.new(0.5, -10, 0.5, -10)
	crosshair.BackgroundTransparency = 1
	crosshair.Text = "+"
	crosshair.TextColor3 = Color3.new(1, 1, 1)
	crosshair.TextSize = 18
	crosshair.Font = Enum.Font.GothamBold
	crosshair.Visible = fir_pes
	crosshair.Parent = crosshairGui
end

local function updateCrosshair()
	if crosshair then
		crosshair.Visible = fir_pes
	end
end

local function updateCamera()
	local character = player.Character
	if not character then
		return
	end

	local head = character:FindFirstChild("Head")
	local hrp = character:FindFirstChild("HumanoidRootPart")
	local humanoid = character:FindFirstChildOfClass("Humanoid")

	if not head or not hrp or not humanoid then
		return
	end

	cu_ya = cu_ya + (targ_ya - cu_ya) * smoth
	cur_pit = cur_pit + (targ_pic - cur_pit) * smoth

	local charaPosition = hrp.Position
	local yaw = CFrame.Angles(0, cu_ya, 0)
	local pitch = CFrame.Angles(cur_pit, 0, 0)
	local camRot = yaw * pitch

	if fir_pes then
		local forward = Vector3.new(
			hrp.CFrame.LookVector.X,
			0,
			hrp.CFrame.LookVector.Z
		)

		if forward.Magnitude > 0 then
			forward = forward.Unit
		end

		local bob = Vector3.new(0, 0, 0)

		if humanoid.MoveDirection.Magnitude > 0.05 then
			local speed = humanoid.WalkSpeed
			local isRunning = speed > 16

			local bobSpeed = isRunning and run_bob_speed or walk_bob_speed
			local bobAmount = isRunning and run_bob_amount or walk_bob_amount

			local time = os.clock()

			local vertical = math.sin(time * bobSpeed) * bobAmount
			local horizontal = math.cos(time * bobSpeed * 0.5) * side_bob_amount

			bob = Vector3.new(horizontal, vertical, 0)
		end

		local camPosition =
			head.Position
			+ Vector3.new(0, head_hig - 1.2, 0)
			+ forward * forw_offset
			+ bob

		camera.CFrame = CFrame.new(camPosition) * camRot
		camera.FieldOfView = first_person_fov

		local lookDirection = camRot.LookVector
		local flatDirection = Vector3.new(
			lookDirection.X,
			0,
			lookDirection.Z
		)

		if flatDirection.Magnitude > 0 then
			hrp.CFrame = CFrame.lookAt(
				charaPosition,
				charaPosition + flatDirection.Unit
			)
		end
	else
		local cameraOffset =
			camRot.LookVector * -dis_3
			+ Vector3.new(0, thirdPersonHeight, 0)

		local camPosition = charaPosition + cameraOffset

		camera.CFrame = CFrame.lookAt(
			camPosition,
			charaPosition + Vector3.new(0, 2, 0)
		)

		camera.FieldOfView = third_person_fov
	end

	updateCrosshair()
end

local function toggleViewMode()
	local character = player.Character
	if not character then
		return
	end

	fir_pes = not fir_pes

	if fir_pes then
		hideHeadAndAccessories(character)
		camera.FieldOfView = first_person_fov
	else
		showHeadAndAccessories()
		camera.FieldOfView = third_person_fov
	end

	updateCrosshair()
end

local function setupCamera(character)
	camera.CameraType = Enum.CameraType.Scriptable
	camera.FieldOfView = first_person_fov
	uis.MouseIconEnabled = mouse_cursor

	hideHeadAndAccessories(character)
	createCrosshair()

	if uis.TouchEnabled then
		local playerGui = player:WaitForChild("PlayerGui")

		local oldGui = playerGui:FindFirstChild("MobileViewToggle")
		if oldGui then
			oldGui:Destroy()
		end

		local buttonGui = Instance.new("ScreenGui")
		buttonGui.Name = "MobileViewToggle"
		buttonGui.ResetOnSpawn = false
		buttonGui.Parent = playerGui

		local button = Instance.new("TextButton")
		button.Name = "ToggleButton"
		button.Size = UDim2.new(0, 30, 0, 30)
		button.Position = UDim2.new(0, 20, 0, 20)
		button.BackgroundColor3 = Color3.new(0.2, 0.2, 0.2)
		button.BackgroundTransparency = 0.3
		button.BorderSizePixel = 0
		button.Text = "1"
		button.TextColor3 = Color3.new(1, 1, 1)
		button.TextScaled = true
		button.Parent = buttonGui

		if first_person_key == 0 then
			button.Visible = false
		end

		local corner = Instance.new("UICorner")
		corner.CornerRadius = UDim.new(0, 10)
		corner.Parent = button

		local stroke = Instance.new("UIStroke")
		stroke.Color = Color3.new(0.5, 0.5, 0.5)
		stroke.Thickness = 2
		stroke.Parent = button

		button.MouseButton1Click:Connect(function()
			toggleViewMode()
			button.Text = fir_pes and "1" or "3"
		end)
	end
end

local function onCharacterAdded(character)
	character:WaitForChild("Head")
	character:WaitForChild("HumanoidRootPart")

	cur_pit = 0
	cu_ya = 0
	targ_pic = 0
	targ_ya = 0
	fir_pes = true

	setupCamera(character)

	uis.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
end

uis.InputChanged:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if input.UserInputType == Enum.UserInputType.MouseMovement then
		local delta = input.Delta

		targ_ya = targ_ya - delta.X * sensa * 0.005
		targ_pic = targ_pic - delta.Y * sensa * 0.005

		targ_pic = math.clamp(targ_pic, -max_angl, max_angl)

	elseif input.UserInputType == Enum.UserInputType.Touch and drag_cam then
		local currentPosition = Vector2.new(
			input.Position.X,
			input.Position.Y
		)

		local delta = currentPosition - last_tou
		last_tou = currentPosition

		targ_ya = targ_ya - delta.X * sensa * 0.005
		targ_pic = targ_pic - delta.Y * sensa * 0.005

		targ_pic = math.clamp(targ_pic, -max_angl, max_angl)
	end
end)

uis.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end

	if input.UserInputType == Enum.UserInputType.MouseButton2 then
		if uis.MouseBehavior == Enum.MouseBehavior.LockCurrentPosition then
			uis.MouseBehavior = Enum.MouseBehavior.Default
		else
			uis.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
		end

	elseif input.UserInputType == Enum.UserInputType.Touch then
		drag_cam = true
		last_tou = Vector2.new(
			input.Position.X,
			input.Position.Y
		)

	elseif input.KeyCode == first_person_key and first_person_key ~= 0 then
		toggleViewMode()
	end
end)

uis.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.Touch then
		drag_cam = false
	end
end)

runService.RenderStepped:Connect(function()
	updateCamera()
end)

if player.Character then
	onCharacterAdded(player.Character)
end

player.CharacterAdded:Connect(onCharacterAdded)

player.AncestryChanged:Connect(function()
	if not player.Parent then
		showHeadAndAccessories()
		uis.MouseBehavior = Enum.MouseBehavior.Default
	end
end)