Body follows camera and glitching

So, i have a body follow camera script, made with IK, there is a part that body looking at. But body start glitching when this part on the back.
Video: 2023-03-28 19-13-10.mp4 - Google Drive
Local script:

local run = game:GetService("RunService")
local parts = {}
local lookvector = Vector3.zero

local function charadded(char)
	task.wait()
	
	local ik = Instance.new("IKControl")
	ik.Type = Enum.IKControlType.LookAt
	ik.ChainRoot = char:WaitForChild("UpperTorso") or char:WaitForChild("Torso")
	ik.EndEffector = char:WaitForChild("Head")
	ik.Target = parts[game.Players:GetPlayerFromCharacter(char)]
	ik.Weight = 1
	ik.Parent = char:FindFirstChildOfClass("Humanoid")
	
	char:FindFirstChildOfClass("Humanoid").Died:Once(function() 
		ik:Destroy() 
	end)
end

local function plradded(player)
	local part = Instance.new("Part")
	part.CanCollide = false
	part.CanQuery = false
	part.CanTouch = false
	part.Anchored = true
	part.Transparency = 1
	part.Parent = workspace

	parts[player] = part

	if player.Character ~= nil then 
		charadded(player.Character) 
	end
	player.CharacterAdded:Connect(charadded)
end

local function plrremoved(plr)
	parts[plr]:Destroy()
	parts[plr] = nil
end

for i,player in game.Players:GetPlayers() do plradded(player) end
game.Players.PlayerAdded:Connect(plradded)
game.Players.PlayerRemoving:Connect(plrremoved)


run.RenderStepped:Connect(function(deltatime)
	for player, part in parts do
		if player.Character == nil then continue end
		part.Position = player.Character:WaitForChild("Head").Position + player:GetAttribute("lookvector") * 10 
	end
end)

Create a disabled LocalScript called “Animate” in StarterCharacterScripts.

Unfortunately, animations are bugged. Until it is fixed, you can disable them.

But isn’t there a way to somehow check the camera angle and turn off the Ik if this is true. Maybe use :Dot()

Oh, if that’s the problem, then yes. I would use Vector3:Angle instead of Dot so I can target a specific axis.

Yes you right, but how to use it? In my second script i did this:

game.Workspace.CurrentCamera:GetPropertyChangedSignal("CFrame"):Connect(function()
	if db == true then return end
	if game.Workspace.CurrentCamera.CFrame.LookVector:Dot(lookvector) > 0.99 then return end
	local deltatime = time() - eventtime
	if game.Workspace.CurrentCamera.CFrame.LookVector:Angle(lookvector) > 0.14 and game.Workspace.CurrentCamera.CFrame.LookVector:Angle(lookvector) ~= 0.149 then -- i added this
		player.Character:FindFirstChildOfClass("Humanoid"):WaitForChild("BodyMove").Weight = 0
	else
		if deltatime > 0.1 then
			player.Character:FindFirstChildOfClass("Humanoid"):WaitForChild("BodyMove").Weight = 1
			eventtime = time()
			lookvector = game.Workspace.CurrentCamera.CFrame.LookVector
			event:FireServer(lookvector)
		else
			db = true
			task.wait(0.1 - deltatime)
			player.Character:FindFirstChildOfClass("Humanoid"):WaitForChild("BodyMove").Weight = 1
			db = false
			eventtime = time()
			lookvector = game.Workspace.CurrentCamera.CFrame.LookVector
			event:FireServer(lookvector) 
		end
	end
end)

but its break ik and my character

You need an axis to use the Angle. In your case, it would be Vector3.yAxis if I’m correct.

game.Workspace.CurrentCamera.CFrame.LookVector:Angle(lookvector,Vector3.xAxis) like this? But i think i need x axis because i need to stop player glitching body by watching back

Oh, then it’s the X axis relative to the player’s character. You’d make the axis parameter player.Character:GetPivot().XVector

This is kinda works. But character refuses to look sometimes, i know this is gonna work, but i need to configure the script so that at a certain angle the character does not glitch his body. I’m not good in math, maybe there is a method to find a angle on which ik weight will be set to 0
Currently. I’m trying this:

game.Workspace.CurrentCamera:GetPropertyChangedSignal("CFrame"):Connect(function()
	if db == true then return end
	if game.Workspace.CurrentCamera.CFrame.LookVector:Dot(lookvector) > 0.99 then return end
	local deltatime = time() - eventtime
	if deltatime > 0.1  then
		if game.Workspace.CurrentCamera.CFrame.LookVector:Angle(lookvector,player.Character:GetPivot().XVector) > 0.14 and game.Workspace.CurrentCamera.CFrame.LookVector:Angle(lookvector,player.Character:GetPivot().XVector) ~= 0.149 then
			print(game.Workspace.CurrentCamera.CFrame.LookVector:Angle(lookvector,Vector3.xAxis))
			player.Character:FindFirstChildOfClass("Humanoid"):WaitForChild("BodyMove").Weight = 0
			eventtime = time()
			lookvector = game.Workspace.CurrentCamera.CFrame.LookVector
			event:FireServer(lookvector)
		else
			print(game.Workspace.CurrentCamera.CFrame.LookVector:Angle(lookvector,Vector3.xAxis))
			player.Character:FindFirstChildOfClass("Humanoid"):WaitForChild("BodyMove").Weight = 1
			eventtime = time()
			lookvector = game.Workspace.CurrentCamera.CFrame.LookVector
			event:FireServer(lookvector)
		end
	else
		if game.Workspace.CurrentCamera.CFrame.LookVector:Angle(lookvector,player.Character:GetPivot().XVector) > 0.14 and game.Workspace.CurrentCamera.CFrame.LookVector:Angle(lookvector,player.Character:GetPivot().XVector) ~= 0.149 then
		db = true
		task.wait(0.1 - deltatime)
		player.Character:FindFirstChildOfClass("Humanoid"):WaitForChild("BodyMove").Weight = 0
		db = false
		eventtime = time()
		lookvector = game.Workspace.CurrentCamera.CFrame.LookVector
	    event:FireServer(lookvector) 
		else
			player.Character:FindFirstChildOfClass("Humanoid"):WaitForChild("BodyMove").Weight = 1
		end
	end
end)

And there is a video: 2023-03-29 19-11-02.mp4 - Google Drive

Try the RootPart’s XVector instead of the pivot.

I used :Dot, and this fixed the problem.
My script:

run.RenderStepped:Connect(function(deltatime)
	for player, part in parts do
		if player.Character == nil then continue end
		if game.Workspace.CurrentCamera.CFrame.LookVector:Dot(player.Character.PrimaryPart.CFrame.LookVector) < -0.7 then
			part.Position = player.Character:WaitForChild("Head").Position + player:GetAttribute("lookvector") * 10 
			player.Character:FindFirstChildOfClass("Humanoid"):WaitForChild("BodyMove").Weight = 0
		else
			part.Position = player.Character:WaitForChild("Head").Position + player:GetAttribute("lookvector") * 10 
			player.Character:FindFirstChildOfClass("Humanoid"):WaitForChild("BodyMove").Weight = 1
		end
	end
end)

Everything turned out to be easier than I thought. It was just necessary to understand that when the PrimaryPart.CFrame.LookVector and Camera.CFrame.LookVector look in different directions, then you need to turn off the Ik, for this i used:Dot()

And i’m improved script, how i said, i have special part that ik makes body to follow, and i changed from camera.CFrame.LookVector:Dot() to part.CFrame.LookVector


run.RenderStepped:Connect(function(deltatime)
	for player, part in parts do
		if player.Character == nil then continue end
		if part.CFrame.LookVector:Dot(player.Character.PrimaryPart.CFrame.LookVector) < -0.7 or part.CFrame.LookVector:Dot(player.Character.PrimaryPart.CFrame.LookVector) > 0.95 then
			part.CFrame = CFrame.new(Vector3.new(0,0,0),game.Workspace.CurrentCamera.CFrame.LookVector)
			part.Position = player.Character:WaitForChild("Head").Position + player:GetAttribute("lookvector") * 10 
			player.Character:FindFirstChildOfClass("Humanoid"):WaitForChild("BodyMove").Weight = 0
		else
			part.CFrame = CFrame.new(Vector3.new(0,0,0),game.Workspace.CurrentCamera.CFrame.LookVector)
			part.Position = player.Character:WaitForChild("Head").Position + player:GetAttribute("lookvector") * 10 
			player.Character:FindFirstChildOfClass("Humanoid"):WaitForChild("BodyMove").Weight = 1
		end
	end
end)


Part moves with delays, which forces the player to “turn” his body 360 degrees, as it was before. Now it doesn’t work and all the errors are definitely fixed. I don’t know why I’m writing this, but maybe someone will need it later.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.