I’ve been trying to find a system that can detect other character’s humanoidrootpart and not my own for a power system that im working on, but it’s been detecting my character even though I made it so it should ignore my character, and it hasn’t been detecting other character’s HMRP.
Similiar to this system, but detecting the enemies HMRP instead:
Local Script:
-- Import our services
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
-- Identify our target for use in the function below
-- Variables
local players = game:GetService("Players")
local playersTable = players:GetPlayers()
local plr = players.LocalPlayer
local Character = plr.Character or plr.CharacterAdded:Wait()
local MyHumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
for i,player in pairs(playersTable) do
if player.Name ~= plr.Name and player.Character.Name ~= plr.Character.Name then continue end
table.remove(playersTable,i)
local EnemyCharacter = player.Character
local EnemyCharacterRootPart = EnemyCharacter.HumanoidRootPart
local RaycastParameters = RaycastParams.new()
RaycastParameters.FilterDescendantsInstances = {Character}
local Camera = workspace.CurrentCamera
local TargetOnScreen = false
local TargetVisible = false
-- Primary function
local function checkIfPartIsOnScreen(EnemyHMRP)
-- Use :WorldToViewportPoint
local _, IsOnScreen = Camera:WorldToViewportPoint(EnemyHMRP.Position)
-- Check if our target is on screen, and update our variable informing us if it is.
if IsOnScreen and (not TargetOnScreen) then
TargetOnScreen = true
print("The target is now in our FOV!")
print(EnemyHMRP.Parent.Name)
-- Do the same, but in reverse
elseif (not IsOnScreen) and TargetOnScreen then
TargetOnScreen = false
-- If the target is off screen, then the target must also not be visible.
TargetVisible = false
print("The target is no longer in our FOV.")
end
-- We don't need to perform a raycast check if the target is out of our FOV
if TargetOnScreen then
-- This may be confusing, but it is Vector3 math. It is getting the direction between our Camera and the part.
local Direction = (EnemyCharacterRootPart.Position - Camera.CFrame.Position).Unit
-- This 200 could be customized to set a specific range that you are checking for the player in, though performing
-- a separate magnitude check beforehand will likely be more optimized.
local RaycastResult = workspace:Raycast(Camera.CFrame.Position, Direction * 200, RaycastParameters)
-- Check if our part was not hit by our Raycast check!
if (not RaycastResult) or RaycastResult.Instance ~= EnemyCharacterRootPart then
-- Now that we know that the target is obscured, we need to check if we need to output!
if TargetVisible then
TargetVisible = false
print("The target is now obscured.")
end
else
-- If the above is not true, we can see the target.
if (not TargetVisible) then
TargetVisible = true
print("The target is visible.")
end
end
end
end
-- Run our check every frame, you may want to not do this depending on how much you are running with this check.
RunService.RenderStepped:Connect(function()
checkIfPartIsOnScreen(EnemyCharacterRootPart)
end)
break
end
--Making sure MyPlayer Is excluded from the rest
-- This is not technically needed, but it is likely preferable as we do not want to our player model obscuring the part
-- to count as an obstruction.
Probably because of the if statement you have: “if the player is not the local player, then continue.” This just continues until it finds the local player, meaning all of the process that you have only works for the local player. Maybe changing it to “player is equal to local player” then continue, so it always ignores the local player.
if player == plr then
continue
end
Also your raycast parameters only accepts the localCharacter. Instead use the enemyCharacter or the enemy’s HumanoidRootPart:
Okay i fixed the script up a little and It seems to work. I do have a couple of issues though. So I tried it out with two players and player 2 detected player 1 on his output but player 1 couldn’t detect player 2 in his output for some reason… Why is this? Could it be because of the loop?
Video:
In game Video:
-- Import our services
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
-- Identify our target for use in the function below
-- Variables
local players = game:GetService("Players")
local playersTable = players:GetPlayers()
local plr = players.LocalPlayer
local Character = plr.Character or plr.CharacterAdded:Wait()
local MyHumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
for i,player in pairs(playersTable) do
if player.Name == plr.Name and player.Character.Name == plr.Character.Name then continue end
table.remove(playersTable,i)
local EnemyCharacter = player.Character
local EnemyCharacterRootPart = EnemyCharacter.HumanoidRootPart
local RaycastParameters = RaycastParams.new()
RaycastParameters.FilterDescendantsInstances = {EnemyCharacterRootPart}
local Camera = workspace.CurrentCamera
local TargetOnScreen = false
local TargetVisible = false
-- Primary function
local function checkIfPartIsOnScreen(EnemyHMRP)
-- Use :WorldToViewportPoint
local _, IsOnScreen = Camera:WorldToViewportPoint(EnemyHMRP.Position)
-- Check if our target is on screen, and update our variable informing us if it is.
if IsOnScreen and (not TargetOnScreen) then
TargetOnScreen = true
print("The target is now in our FOV!")
print(EnemyHMRP.Parent.Name)
-- Do the same, but in reverse
elseif (not IsOnScreen) and TargetOnScreen then
TargetOnScreen = false
-- If the target is off screen, then the target must also not be visible.
TargetVisible = false
print("The target is no longer in our FOV.")
end
-- We don't need to perform a raycast check if the target is out of our FOV
if TargetOnScreen then
-- This may be confusing, but it is Vector3 math. It is getting the direction between our Camera and the part.
local Direction = (EnemyCharacterRootPart.Position - Camera.CFrame.Position).Unit
-- This 200 could be customized to set a specific range that you are checking for the player in, though performing
-- a separate magnitude check beforehand will likely be more optimized.
local RaycastResult = workspace:Raycast(Camera.CFrame.Position, Direction * 200, RaycastParameters)
-- Check if our part was not hit by our Raycast check!
if (not RaycastResult) or RaycastResult.Instance ~= EnemyCharacterRootPart then
-- Now that we know that the target is obscured, we need to check if we need to output!
if TargetVisible then
TargetVisible = false
print("The target is now obscured.")
end
else
-- If the above is not true, we can see the target.
if (not TargetVisible) then
TargetVisible = true
print("The target is visible.")
end
end
end
end
-- Run our check every frame, you may want to not do this depending on how much you are running with this check.
RunService.RenderStepped:Connect(function()
checkIfPartIsOnScreen(EnemyCharacterRootPart)
end)
end
--Making sure MyPlayer Is excluded from the rest
-- This is not technically needed, but it is likely preferable as we do not want to our player model obscuring the part
-- to count as an obstruction.
That’s because player 1 was the first to join, and the players’ table only had one item, which was player 1. You should also connect it to the player joining, and I’m pretty sure that if the player dies, the entire function is pointless. Your code is very messy and you even have two Players Service.
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
local camera = workspace.CurrentCamera
local function TrackCharacter(character: Model)
local humanoidRootPart: Part = character:WaitForChild("HumanoidRootPart")
local humanoid: Humanoid = character:WaitForChild("Humanoid")
local connection: RBXScriptConnection
local characterOnScreen = false
local characterVisible = false
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = { character }
connection = RunService.RenderStepped:Connect(function()
local _, isOnScreen = camera:WorldToViewportPoint(humanoidRootPart.Position)
if isOnScreen and not characterOnScreen then
characterOnScreen = true
print(character.Name .. " is in our FOV")
elseif not isOnScreen and characterOnScreen then
characterOnScreen = false
characterVisible = false
print(character.Name .. " is no longer on our FOV")
end
if characterOnScreen then
local direction = (humanoidRootPart.Position - camera.CFrame.Position).Unit
local ray = workspace:Raycast(camera.CFrame.Position, direction * 200, raycastParams)
if not ray or not (ray.Instance == humanoidRootPart) then
if characterVisible then
characterVisible = false
print(character.Name .. " is now obscured")
end
else
if not characterVisible then
characterVisible = true
print(character.Name .. " is visible")
end
end
end
end)
humanoid.Died:Connect(function()
connection:Disconnect()
end)
end
local function PlayerAdded(player: Player)
TrackCharacter(player.Character or player.CharacterAdded:Wait())
player.CharacterAdded:Connect(TrackCharacter)
end
do
local currentPlayers = Players:GetPlayers()
table.remove(currentPlayers, table.find(currentPlayers, localPlayer))
for _, player in ipairs(currentPlayers) do
coroutine.wrap(TrackCharacter)(player.Character or player.CharacterAdded:Wait())
end
end
Players.PlayerAdded:Connect(PlayerAdded)
This part does not really work, I just copied the code you had, I do have a solution to this, but you should try to fix it on your own, if not just ask on the #help-and-feedback:scripting-support .