Magnitude in Front of a Player

  1. What do you want to achieve? Keep it simple and clear!
    I want to get the distance in front of a player using a Magnitude distance calculation so that I can apply damage to a humanoid if it exists in that area.

  2. What is the issue?
    Currently, when a player clicks with a tool, the player will damage any humanoid in a circular radius around them, but I want the player to only damage other players if they are facing towards, and within a small range of another player, something fitting for a punch.

  3. What solutions have you tried so far?
    In order to go from a hitbox that functions as a radius around the player, to one that is directly in front of the player, depending on where they are facing, I have tried to use :toWorldSpace to change the distance to be relative to where the player is, but this hasn’t worked out, and still keeps the hitbox in a radius-like fashion.

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local remoteEvent = game.ReplicatedStorage:WaitForChild("punchEvent")
local people = game.Workspace.people
local tool = script.Parent
local character = tool.Parent

local function onRemoteEvent(player)
	print "remote fired"
	local peopleTable = people:GetChildren()
	local rightArmPosition = tool.Parent["Right Arm"].Position
	local rightArm = tool.Parent["Right Arm"]


	for i,v in pairs(peopleTable) do 
		if v:FindFirstChild("Humanoid") then
			local enemy = v
			local eHumanoid = enemy.Humanoid
			local distance = (rightArmPosition - v.HumanoidRootPart.CFrame:toWorldSpace(CFrame.new(0,0,-5)).Position).Magnitude
			print (distance)
			if distance < 10 and v.Name ~= player.Name then
				eHumanoid:TakeDamage(10)
			end
		end
	end
end

remoteEvent.OnServerEvent:Connect(onRemoteEvent)

Code for the server script that handles the magnitude calculations above.


Currently, as seen above, the dummy is able to be damaged, even when the player is far from, and not facing towards the dummy.

Use Region3 or Raycast. Hopfully that works.

Short answer: use the dot product of the distance vector and the character’s HumanoidRootPart LookVector.

I use this for hit detection between players instead, also it only detects in front of the player
( the variable ‘c’ is your character)


	    local R =  Ray.new(c.HumanoidRootPart.Position, c.HumanoidRootPart.CFrame.lookVector*8)--change the 8 to the distance you want the hit detectin to be
		local v = workspace:FindPartOnRay(R, c)
		if v ~= nil then
			if v.Parent:findFirstChild("Humanoid") and v.Parent ~= c then
               v.Parent.Humanoid:TakeDamage(10)
            end
        end
2 Likes

better way

local distVector = character.HumanoidRootPart.Position - npc.HumanoidRootPart.Position
local dot = character.HumanoidRootPart.CFrame.LookVector:Dot(distVector)
local dotAngle = math.acos(dot)
if dotAngle < math.rad(30) then -- angle threshold check
    -- do stuff
end
1 Like

Hey, I tried your solution, and I saw that while dot was returning different values dependent on where my character was facing, dotAngle would return the same value of 1.5707963267949 and -nan(ind). The actual if/then statement itself was working, as when I removed the dotAngle < math.rad(30), the humanoid would still take damage (just from any distance obviously). I’m not really great with trigonometry, but I think the error lies within that local dotAngle = math.acos(dot) line (or I just did something dumb in my code).

	for i,v in pairs(peopleTable) do 
		if v:FindFirstChild("Humanoid") then
			local enemy = v
			local eHumanoid = enemy.Humanoid
			--local distance = (rightArmPosition - v.HumanoidRootPart.CFrame:toWorldSpace(CFrame.new(0,0,-5)).Position).Magnitude
			--print (distance)
			local distVector = character.HumanoidRootPart.Position - enemy.HumanoidRootPart.Position
			local dot = character.HumanoidRootPart.CFrame.LookVector:Dot(distVector)
			local dotAngle = math.acos(dot)
			print (dotAngle)
			if dotAngle < math.rad(30) and v.Name ~= player.Name then
				print "damage"
				eHumanoid:TakeDamage(10)
			end
		end
	end
end
1 Like