I need help with a script that works "badly"

It happens that I am trying to implement a first-person system in my game, so far so good, what happens is that the hair interferes with the view and I have already tried thousands of ways but I can’t solve it

Here the code:

Camera code:

repeat wait() until game:GetService("Players").LocalPlayer.Character ~= nil
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")

CanToggleMouse = {allowed = true; activationkey = Enum.KeyCode.F;} 
CanViewBody = false
Sensitivity = 0.6
Smoothness = 0.05
FieldOfView = 90

local Camera = game.Workspace.CurrentCamera
local Player = Players.LocalPlayer
local m = Player:GetMouse()
m.Icon = "http://www.roblox.com/asset/?id=569021388"

local Character = Player.Character or Player.CharacterAdded:Wait()
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local Head = Character:WaitForChild("Head")

local running = true
local freemouse = false

local CamPos, TargetCamPos = Camera.CoordinateFrame.p, Camera.CoordinateFrame.p
local AngleX, TargetAngleX = 0, 0
local AngleY, TargetAngleY = 0, 0

-- Definir límites para el eje Y (vertical)
local MaxVerticalAngle = 80

function updatechar()
	for _, v in pairs(Character:GetChildren()) do
		if CanViewBody then
			if v.Name == 'Head' then
				v.LocalTransparencyModifier = 0
				v.CanCollide = true
			end
		else
			if v:IsA('BasePart') or v:IsA('UnionOperation') or v:IsA('MeshPart') then
				v.LocalTransparencyModifier = 0
				v.CanCollide = true
			end
		end
		if v:IsA('Accessory') or v:IsA('Hat') then
			local handle = v:FindFirstChild('Handle')
			if handle then
				handle.LocalTransparencyModifier = 0
				handle.CanCollide = true
			end
		end
	end
end

function handleInput(inputObject)
	if inputObject.UserInputType == Enum.UserInputType.MouseMovement then
		local delta = Vector2.new(inputObject.Delta.x / Sensitivity, inputObject.Delta.y / Sensitivity) * Smoothness
		TargetAngleX = TargetAngleX - delta.y
		TargetAngleY = (TargetAngleY - delta.x) % 360
	elseif inputObject.UserInputType == Enum.UserInputType.Touch then
		local delta = Vector2.new(inputObject.Delta.x, inputObject.Delta.y) * Sensitivity * Smoothness
		TargetAngleX = TargetAngleX - delta.y
		TargetAngleY = (TargetAngleY - delta.x) % 360
	end
end

UserInputService.InputChanged:Connect(handleInput)

UserInputService.InputBegan:Connect(function(inputObject)
	if inputObject.UserInputType == Enum.UserInputType.Keyboard then
		if inputObject.KeyCode == CanToggleMouse.activationkey then
			if CanToggleMouse.allowed and not freemouse then
				freemouse = true
			else
				freemouse = false
			end
		end
	end
end)

RunService.RenderStepped:Connect(function()
	if running then
		updatechar()

		-- Evitar obstrucciones visuales
		local ray = Ray.new(Head.Position, (Camera.CoordinateFrame.p - Head.Position).unit * 10)
		local hitPart, hitPos = game.Workspace:FindPartOnRay(ray, Camera, false, true)

		if hitPart then
			TargetCamPos = hitPos
		else
			TargetCamPos = Head.Position + (Camera.CoordinateFrame.lookVector * 10)
		end

		CamPos = CamPos + (TargetCamPos - CamPos) * 0.28
		AngleX = math.clamp(AngleX + (TargetAngleX - AngleX) * 0.35, -MaxVerticalAngle, MaxVerticalAngle)
		local dist = TargetAngleY - AngleY
		dist = math.abs(dist) > 180 and dist - (dist / math.abs(dist)) * 360 or dist
		AngleY = (AngleY + dist * 0.35) % 360
		Camera.CameraType = Enum.CameraType.Scriptable

		Camera.CFrame = CFrame.new(Head.Position) * CFrame.Angles(0, math.rad(AngleY), 0) * CFrame.Angles(math.rad(AngleX), 0, 0) * CFrame.new(0, 0.5, 0)
		HumanoidRootPart.CFrame = CFrame.new(HumanoidRootPart.Position) * CFrame.Angles(0, math.rad(AngleY), 0)
	end

	if (Camera.Focus.p - Camera.CoordinateFrame.p).magnitude < 1 then
		running = false
	else
		running = true
		if freemouse == true then
			UserInputService.MouseBehavior = Enum.MouseBehavior.Default
		else
			UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
		end
	end

	if not CanToggleMouse.allowed then
		freemouse = false
	end

	Camera.FieldOfView = FieldOfView
end)

Body code:

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

char.Humanoid.CameraOffset = Vector3.new(0, 0, -1)

-- Buscar partes del modelo del personaje que contienen "Hair" en el nombre
local hairParts = {}
for _, part in pairs(char:GetDescendants()) do
	if part:IsA("BasePart") and string.find(part.Name:lower(), "hair") then
		table.insert(hairParts, part)
	end
end

-- Establecer transparencia en 1 para todas las partes del cabello encontradas
for _, hairPart in ipairs(hairParts) do
	hairPart.Transparency = 1
end

RunService.RenderStepped:Connect(function(step)
	local ray = Ray.new(char.Head.Position, ((char.Head.CFrame + char.Head.CFrame.LookVector * 2) - char.Head.Position).Position.Unit)
	local ignoreList = char:GetChildren()

	local hit, pos = game.Workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)

	if hit then
		char.Humanoid.CameraOffset = Vector3.new(0, 0, -(char.Head.Position - pos).magnitude)
	else
		char.Humanoid.CameraOffset = Vector3.new(0, 0, -1)
	end
end)

Have a happy rest of the day!!

I’ve skimmed your code briefly and came across what I think is the problem. You never set the CanViewBody variable to true, thus the updatechar function can never continue past the if statement checking if CanViewBody is true. Hope this helps!

Cheers,
Techy

1 Like

Thank you very much for your help, that was not the root of the problem but you helped me find it, thank you very much.