How do you find whether Actor B is behind Actor A, based on their location/rotations? In my custom FPS setup sometimes targets get closer to the player than the gun barrel. As my projectiles spawn with a Look At Rotation I find my gun firing backwards. I need to check whether the actors are in front (180 degrees for preference, but a configurable angle would be handy) of the gun barrel. Basically a cone of vision check but using maths not line traces.
DotProduct of two vectors is positive if vectors have the same directions, 0 if vectors are perpendicular, and negative if vectors have opposite directions.
In your case, first vector is gun actor forward vector.
Second vector will be direction vector from gun to target actor. It can be calculated by formula:
Normalize(TargetLocation - GunLocation)
So, dotproduct>=0 if target in front of gun, and dotproduct<0 if target is behind of gun.
Compute Vector To Target by subtracting your location from target location and normalize that vector
Perform a vector dot operation between those two vectors and get the arccos (maybe there is a builtin vector angle function, idk), then you have the angle between those vectors. You then can specify a tolerance and compare.
Maybe you want to change a few things according to your needs, e.g. don’t take pitch rotation of your character into account.
The posted solutions are very nice indeed, but I gotta say they’re a bit overengineered and overcomplicated.
It should be enough for you to calculate the target actor position relative to the “center” actor, functionality which is provided by the node Inverse Transform Location. With the relative target location, you can just check if the Y-axis is positive or negative.
This is illustrated here by a cube object placed behind and in front of a center actor, a door. Check the Y-axis on both cases:
Both GetActorLocation are global. Not only that but that exact code is being used currently in a published game which never had a bug reported on the doors. The only reason it had a downvote the first time was due to a douche that already erased his comments. Could you reconsider your downvote? Thanks.
I think what you didn’t realise is that the only purpose of the inverse transform location is to pass the actor location to a theoritical local space, have you tried this code to support your claim?
yea and it doesn’t work, im here from google responding to this old thread. the solutions above work, yours doesn’t. classic is coming out so dont worry about it too much.
is present in a published game with 11k downloads and there was not a single individual to complain it opened from the wrong direction. You must really be a God prove 11 thousand people wrong. I’d love to see your implementation, do you mind sharing?
I’m not flexing, I’m demonstrating tested code, not hunches. It has -2 due to you, uneducated fellow and a similar individual that deleted his comments out of shame in the exact same discussion.
I’m creating a door and needed to establish if the player was behind or in front of it… and Garcia’s solution works perfectly. Whereas I hasn’t been able to correctly implement the other solution. Although I believe it also should work. So it’s +1 for me too. I may have interpret something wrong with the vectors (because the gun example is a little different but remains the fact that this is simpler… and… it works.)
Just chipping in that I’m using Garcia’s solution to test which side of a ladder I am (in front or behind) and it works perfectly. Thank you Garcia.
Thanks @Gabriel_Garcia, your solution is much more concise and saves me 2 variables.
Here is the code in C++
// Calculate the direction of where the owner is being hit from. Greater than 1 = front, lesser than 1 = back.
float direction = Character->GetActorTransform().InverseTransformPosition(Instigator->GetActorLocation()).X;
I don’t think anyone’s method is wrong.
Probably different methods may work for everyone due to the differences in the projects.
I also tried all the methods here.
Frankly, my problem that I’ve been dealing with for hours has been solved only by @Gabriel_Garcia’s method.
Only the x value instead of the y value worked.