Damage players I'm facing

I’m working on this combat script, I’m currently using magnitude but I don’t like how you don’t have to be facing the target to hit them.
What would I have to do exactly to make it so they have to be facing the target for it to damage the target.

local Combat = game:GetService("ReplicatedStorage").Remotes.RemoteEvent1


local DmgTable = {
	Hit1 = 5;
	Hit2 = 6;
	Hit3 = 5;
	Hit4 = 6;
	Hit5 = 10;
}


local function Damage(Humanoid, Amount)
	Humanoid:TakeDamage(Amount)
end


Combat.OnServerEvent:Connect(function(Client, Combo) 
	print(DmgTable[Combo])
	for _, player in ipairs (game.Players:GetChildren()) do
		if player ~= Client and (Client.Character.HumanoidRootPart.Position - player.Character.HumanoidRootPart.Position).Magnitude < 10 then
			Damage(player.Character.Humanoid, DmgTable[Combo])
		end 
	end
end)
	

You could use raycasting

So something like this should work?

local Ray1 = Ray.new(Client.Character.HumanoidRootPart.Position, Client.Character.HumanoidRootPart.CFrame.lookVector * 10)

you probably meant
.lookVector * 10

Yes, then just check if the ray is hitting a humanoid, if so damage the following player

If you want a bit of leeway, such as 45 degrees in either direction, then the Dot operator is your new friend.

local vector = player.Character.HumanoidRootPart.Position - Client.Character.HumanoidRootPart.Position
local direction = Client.Character.HumanoidRootPart.CFrame.LookVector

if vector.Magnitude < 10 and vector.Unit:Dot( direction ) > 0.707 then
    -- attack is valid, do the damage
end

Here’s a quick diagram I made while answering a similar question earlier:

To change the angle, swap 0.707 for the cosine of the angle you want. To widen it to 60° in each direction, you’d put 0.5 (because cos(60°) = 0.5).

8 Likes

Thanks, this is exactly what I was looking for.

1 Like

As with a previous thread that I saw before, anyone who is recommending Raycasting for this solution is wrong.

Dot product is 100% the way to go for getting ‘if a player is facing object/position a,b,c’, and is extremely lightweight in computations and does not use instancing when compared to Raycasting.

Thank you for saving this thread

1 Like

that is perfect,
but there is another way
the reason this is so much longer is because it works with the corner cases, e.g. the angle being 90, 180, etc. (it pretty much does the same thing as yours lol)

local ang = 45 -- check if they are in your RootPart's view within 45 degrees
---------------------------------------------------------------------------------------------------------------------
ang = math.clamp(ang, -180, 180)
local dot = (enemyRootPart.Position - localRootPart.Position).Unit:Dot(-localRootPart.CFrame.LookVector)
local angleDot = -math.cos(math.rad(ang))

if (dot < 0 and dot < angleDot) or (dot > 0 and dot <= angleDot) or (dot == 0 and ang == 90 and dot > angleDot) or (dot == 0 and ang > 90 and dot <= angleDot) or (dot == 0 and ang < 90 and dot < angleDot) then
    print('in range!')
end
2 Likes