Hello, I’m currently trying to make a hostage system, and I’m wondering how I would detect when a player is behind another player. Would this possibly be done with lookvectors?
There are some ways, a couple I can think of is
- ray casting
- welding a part to the front of the player, then using
BasePart::GetTouchingParts
to see if they are touching the welded part (not really recommended but it can work)
Say you have RootPart1 and RootPart2. To check if RootPart1 is behind RootPart2 you’d do something like:
local ObjectSpace = RootPart2.CFrame:inverse() * RootPart1.CFrame
local MaxDistance = 4
if ObjectSpace.Z < 0 and (RootPart1.CFrame.p - RootPart2.CFrame.p).magnitude <= MaxDistance then
-- is behind and within range
end
So now all you have to do is get rootpart1 and rootpart2. Thanks!
Don’t forget to mark the reply as being the solution if it answered your question!
Raycasting might be a better method, as it eliminates the need for something like, ‘rootpart2’. All you have to know is the HumanoidRootPart of the LocalPlayer, and then just cast a ray behind them, and check if it hits a part. If it does, check if that part is apart of a player’s character, if it is, and the player’s character is close enough to the LocalPlayer, then you can run whatever code you want, now that you know they’re behind them.
Well what is the exact definition of behind in this case? I would say 120 degrees or less, in the negative LookVector direction, a radius in distance. Rather than exactly wherever the ray is being cast.
I would rather have much more wiggle room than just exactly directly behind the player in question.
If you’re thinking about lookvectors, you’re in the right mindset. You can take the dot product between the look vector of the “in front” player and the “distance” vector between the two players. If the result is negative, then the second player is behind the “in front” player you are checking.
In pseudocode,
local lookVector = FrontPlayer.LookVector
local Position = BackPlayer.Position - FrontPlayer.Position
if (lookVector.dot(Position) < 0) then
-- "BackPlayer" is behind "FrontPlayer"
end
Good point, I wasn’t thinking about how we were defining behind.
Yo how would you do this with a player in front of you instead of behind?
Then ObjectSpace.Z
would be greater than 0:
local ObjectSpace = RootPart2.CFrame:inverse() * RootPart1.CFrame
local MaxDistance = 4
if ObjectSpace.Z > 0 and (RootPart1.CFrame.p - RootPart2.CFrame.p).magnitude <= MaxDistance then
-- is in front and within range
end
By “FrontPlayer” are you getting the player or the HumanoidRootPart
The HumanoidRootPart. I guess I should have clarified that, thanks for pointing it out.
In my case Raycasting worked the best, i recommend using Raycasting.
A simple way I did this when I made one way doors for my game is to get two positions: one one stud in front of the player and one one stud behind. Then, whichever you are closer to is the side you are on:
local Root = Character.HumanoidRootPart
local Front, Behind = Root.CFrame * CFrame.new(0, 0, -1), Root.CFrame * CFrame.new(0, 0, 1)
local Target = workspace.Target -- You want to find out if this object is in front of or behind the player
if (Target.Position - Front.Position).Magnitude > (Target.Position - Behind.Position).Magnitude then
-- Front distance is greater than behind, so they are behind the player
else
-- Front distance is less than behind, so they are in front
end
Bear in mind this works in a range of 180 degrees, you can’t have a precise window.