Hi all! My code below is used as apart of a combat class that I made in a module script. The aim of it is to detect if the player is: in range of the enemy, within the FOV of the enemy and can directly be seen by the enemy (through raycasting). If all of those parameters are met, the function will return true
, however if not, the function will return false
.
PlayerInputHandler:
RunService.RenderStepped:Connect(function()
CombatClass.CheckPlayersRangeFromEnemy(HRP)
end)
CombatClass:
local function IsEnemyInRange(enemy, comparisonValue, HRPPos)
if enemy ~= nil then
if (HRPPos - enemy).Magnitude < comparisonValue then
return true
end
end
end
local function IsPlayerInRange(HRPPos)
local EnemiesInRangeOf = {}
local EnemiesInFOVOf = {}
for _, enemy in pairs(enemiesGroup:GetChildren()) do
if IsEnemyInRange(HRPPos, enemy:FindFirstChild("ViewDistance").Value, enemy.PrimaryPart.Position) then
table.insert(EnemiesInRangeOf, enemy)
end
end
for i = 1, #EnemiesInRangeOf do
local enemyToPlayer = (HRPPos - EnemiesInRangeOf[i].PrimaryPart.Position).Unit
local enemyLookVector = EnemiesInRangeOf[i].PrimaryPart.CFrame.LookVector
local dotProduct = enemyToPlayer:Dot(enemyLookVector)
if dotProduct > 0.7 then
table.insert(EnemiesInFOVOf, EnemiesInRangeOf[i])
end
end
return EnemiesInFOVOf
end
local function CanEnemySeePlayer(enemy, HRP)
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {enemy}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
local rayDirection = (HRP.Position - enemy.PrimaryPart.Position)
local raycast = workspace:Raycast(enemy.PrimaryPart.Position, rayDirection, raycastParams)
if raycast then
local hitPart = raycast.Instance
if hitPart.Parent.PrimaryPart == HRP then
return true
else
return false
end
else
return false
end
end
function CombatClass.CheckPlayersRangeFromEnemy(HRP)
local EnemiesInFOVOf = IsPlayerInRange(HRP.Position)
for i = 1, #EnemiesInFOVOf do
local enemyDetectionResult = CanEnemySeePlayer(EnemiesInFOVOf[i], HRP)
print(enemyDetectionResult)
end
end
At first I had this function run from the side of the enemy, meaning that every enemy would always be checking to see if the player can be seen by them, however I found it to be extremely laggy and unoptimized, thus moving it to the client side. I currently have no idea on how to improve it or make it more efficient, since it really isn’t great to always be running a raycast from every enemy, to the player, but if you can please give me any feedback, that would be great!