Player can still move when they shouldn't

When the players characters HumanoidRootPart or the players ‘Enemy Root’ is in view of any other player they are supposed to not be able to move, the player is supposed to only be able to move when not seen by another player, however despite being seen or within view they can for some reason move bit, why is this and how can I prevent this?

local enemy = script.Parent
local hostchar = enemy:FindFirstChild("Host").Value
local host = game:GetService("Players"):GetPlayerFromCharacter(hostchar)
local enemyRoot = enemy:FindFirstChild("Root")
local detectionDistance = 100 -- Change this to your desired detection distance in studs
local maxAllowedAngle = math.cos(math.rad(45)) -- Maximum allowed angle in radians

-- Define the additional part (workspace.Part)
local additionalPart = hostchar:FindFirstChild("HumanoidRootPart")

local canMove = true
local moving = false

-- Function to check if a player is within the detection distance of either part
local function isPlayerWithinDistance(player)
	local character = player.Character
	if not character then
		return false
	end

	local head = character:FindFirstChild("Head")
	if not head then
		return false
	end

	local distanceToenemy = (enemyRoot.Position - head.Position).magnitude
	local distanceToAdditionalPart = (additionalPart.Position - head.Position).magnitude

	return distanceToenemy <= detectionDistance or distanceToAdditionalPart <= detectionDistance
end

-- Function to check if the player's head is directed towards either part
local function isPlayerLooking(player)
	local character = player.Character
	if not character then
		return false
	end

	local head = character:FindFirstChild("Head")
	if not head then
		return false
	end

	local directionToenemy = (enemyRoot.Position - head.Position).unit
	local directionToAdditionalPart = (additionalPart.Position - head.Position).unit

	local characterOrientation = character.HumanoidRootPart.CFrame.lookVector

	local dotProductToenemy = directionToenemy:Dot(characterOrientation)
	local dotProductToAdditionalPart = directionToAdditionalPart:Dot(characterOrientation)

	-- Adjust this threshold as needed for both parts
	return dotProductToenemy >= maxAllowedAngle or dotProductToAdditionalPart >= maxAllowedAngle
end

-- Function to perform raycasts for both parts
local function performRaycasts(player)
	local character = player.Character
	if not character then
		return false
	end

	local head = character:FindFirstChild("Head")
	if not head then
		return false
	end

	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.FilterDescendantsInstances = {player.Character} -- Exclude the player's character

	local raycastResultToenemy = workspace:Raycast(
		head.Position,
		(enemyRoot.Position - head.Position).unit * (enemyRoot.Position - head.Position).magnitude,
		raycastParams
	)

	local raycastResultToAdditionalPart = workspace:Raycast(
		head.Position,
		(additionalPart.Position - head.Position).unit * (additionalPart.Position - head.Position).magnitude,
		raycastParams
	)

	return (raycastResultToenemy and raycastResultToenemy.Instance == enemyRoot) or
		(raycastResultToAdditionalPart and raycastResultToAdditionalPart.Instance == additionalPart)
end

local function checkHeadDirection()
	for _, player in pairs(game.Players:GetPlayers()) do
		if player ~= host then
			if isPlayerWithinDistance(player) then
				if isPlayerLooking(player) and performRaycasts(player) then
					canMove = false
					hostchar.Humanoid.WalkSpeed = 0
					print("Being looked at")
				else
					canMove = true
					hostchar.Humanoid.WalkSpeed = 22
					print("View blocked or not looked at")
				end
			else
				canMove = true
				hostchar.Humanoid.WalkSpeed = 22
				print("Players are outside of distant range")
			end
		end
	end
end

hostchar:FindFirstChild("Humanoid"):GetPropertyChangedSignal("MoveDirection"):Connect(function()
	if hostchar.Humanoid.MoveDirection.Magnitude > 0 then
		enemyRoot.Move.Playing = true
		moving = true
	else
		enemyRoot.Move.Playing = false
		moving = false
	end
end)

game:GetService("RunService").Heartbeat:Connect(function()
	checkHeadDirection()
	if moving == true then
		enemy:SetPrimaryPartCFrame(hostchar:FindFirstChild("HumanoidRootPart").CFrame)
	end
end)

game:GetService("Players").PlayerRemoving:Connect(function(player)
	if player == host then
		hostchar:Destroy()
		enemy:Destroy()
	end
end)

hostchar.Humanoid.Died:Connect(function()
	hostchar:Destroy()
	enemy:Destroy()
end)
1 Like

You can also anchor the HumanoidRootPart to make sure the player can’t move and add an additional check to apply the new settings only if the current value is the opposite, to avoid running the same settings over and over again for nothing.

local Look = isPlayerLooking(player)
local Rays = performRaycasts(player)
if Look and Rays and canMove == true then
	canMove = false
	hostchar.Humanoid.WalkSpeed = 0
	hostchar.HumanoidRootPart.Anchored = true
	print("Being looked at")
elseif Look and Rays and canMove == false then 
	canMove = true
	hostchar.Humanoid.WalkSpeed = 22
	hostchar.HumanoidRootPart.Anchored = false
	print("View blocked or not looked at")
end

This worked, however it now seems to not be able to move despite no other players present, and the last thing printed into the console is that it’s being looked at.
It appears the host still affects this for some reason despite the script checking to make sure it doesn’t check the main host.

Oh yeah my bad, its because of the “Look” and “Ray”, can you eventually try this

local Look = isPlayerLooking(player)
local Rays = performRaycasts(player)
if Look and Rays and canMove == true then
	canMove = false
	hostchar.Humanoid.WalkSpeed = 0
	hostchar.HumanoidRootPart.Anchored = true
	print("Being looked at")
elseif (not Look and not Rays and canMove == false) or (Look and not Rays and canMove == false) then 
	canMove = true
	hostchar.Humanoid.WalkSpeed = 22
	hostchar.HumanoidRootPart.Anchored = false
	print("View blocked or not looked at")
end

If it didn’t work too, you still can only add the anchored, it should be fine.

if isPlayerLooking(player) and performRaycasts(player) then
	canMove = false
	hostchar.Humanoid.WalkSpeed = 0
	hostchar.HumanoidRootPart.Anchored = true
	print("Being looked at")
else
	canMove = true
	hostchar.Humanoid.WalkSpeed = 22
	hostchar.HumanoidRootPart.Anchored = false
	print("View blocked or not looked at")
end

The 2nd one fixes the movement when other players that aren’t the host look at it, though the host still affects it for some reason. Nevermind, fixed the issue, thank you.

1 Like

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