- Home /
Physics.Linecast seems to do opposite of what it says?
I'm using Physics.Linecast to check a line between my enemy and the player (going from the enemy to the player), and it seems that if the line reaches the player without being intersected on the way then it passes and the code that relies on it passing executes, but if the line hits anything on the way to the player (like a wall) then it fails and the code that relies on it passing doesn't execute. This is actually what I want it to do, and this is the code I'm using:
if (Physics.Linecast(transform.position,
player.transform.position))
{
canHitPlayer = true;
Debug.Log("Can hit player");
}
else
{
canHitPlayer = false;
Debug.Log("Cannot hit player");
}
But this seems to be the exact opposite of what the unity documentation says Physics.Linecast does, where the code should return true if the line hits anything in between the start and end points, so it should be false if it reaches the end point unimpeded.
https://docs.unity3d.com/ScriptReference/Physics.Linecast.html
Any ideas what's up with that?
And the reason I ask is because my code above does seem to work the way I want it to in most cases (even though it seems to be the opposite of what the documentation says): If the line is uninterrupted going from the enemy to the player, so it doesn't hit any scenery or whatever, then the enemy will fire at the player--that's what I want. And if the line is interrupted then they won't fire at the player--that's also what I want. Except the enemies seem to be able to shoot right through each other for some reason, when I would expect the line check to be stopped by other enemies and therefore prevent them from firing at the player unless they have a clear line of sight--that is not what I want.
Note: The enemies all have collision boxes on their parent objects, so I can't figure out why the code above seems to be working for the most part but not when enemies try to shoot and there is another enemy in the way, which should stop them from actually firing but doesn't.
Am I just doing this all wrong, and if so, what's the correct way to go about this?
Answer by RocketFriday · Oct 24, 2018 at 02:55 PM
I believe it's due to this.
Well I've not set any layer masks in the method, and the enemies are on the same default layer that the likes of the wall and pillars are, so shouldn't the line basically collide with every single collier it comes into contact with, which would also include other enemies?
Typically, I find that collisions, ray-casts and triggers tend to act up if there isn't a rigidbody in the mix. So ensure that you have one on one of the two objects involved (Ideally the object sending the cast) but if have a rigidbody on one of them and it still doesn't work, try adding one to both objects. Even if you have to disable use gravity and check is$$anonymous$$inematic.
oh and typically Physics.Raycast is used, ins$$anonymous$$d of linecast. Here's a video tutorial on shooting with raycasts.
I think you don't quite understand the point of a raycast or linecast in this case. The method will return true whenever it hits anything. You just pass a start position and an end position. Whenever this line hits any collider (whether it's of your player or any other object like a wall) the method will return true. It will only return false if there is no collider between the start and end point at all. Since you end your line cast at the player position your method will most likely always return true since it ends within the player object.
You have generally two options here: Either move your player object to a seperate layer and exclude that layer. This way when the linecast returns true you can not hit the player since you hit any other collider which is in the way. If the method returns false nothing is in the way and the line reached the end. This only works if you exclude the player object from the linecast.
The second option (which is the much more common one) is to use a Linecast overload that has a RaycastHit parameter so you can exa$$anonymous$$e what the linecast actually hit. That way you can check the name / tag of the object that you hit to figure out if you actually hit the player or something else.
O$$anonymous$$, I've changed the code to the following and it seems to work properly now:
RaycastHit hit;
if (Physics.Linecast(transform.position, player.transform.position, out hit))
{
GameObject theObject = hit.collider.gameObject;
if (hit.collider.gameObject.CompareTag("Player"))
{
canHitPlayer = true;
}
else
{
canHitPlayer = false;
}
}
So the Linecast is def going to hit the player and return true if nothing is in the way since the last thing it reaches is the player, which means there's a clear line of site to the player and enemy is then allowed to fire at them, but if it hits anything else on the way to the player then it will return false and the enemy is not allowed to fire until they have a clear line of sight.
:)
Although I still don't quite understand the structure of the method in terms of putting the Linecast/Raycast inside an if statement, because I would normally interpret this as anything that happens as a result of the if statement returning true would happen in a set of curly brackets right after the if statement, and then and I'd add an else statement after that to check for stuff that didn't return true, like this:
if (// check if something is true)
{
// If it's true then do something
}
else // So it returns false
{
// If it's false then do something else
}
I would have instinctively thought this would be the way to use the Linecast check, but it doesn't seem to work the way I think:
if (Physics.Linecast(transform.position, player.transform.position))
{
canHitPlayer = true; // Since this should mean it reached the player, which is the end check point
}
else
{
canHitPlayer = false; // Should mean it hit something before reaching the player
}
The enemies just fire right through each other when I use what I actually think would be the proper and simplest solution, which is the one directly above, and that's likely what got me all confused early on.
Your answer
Follow this Question
Related Questions
Linecast questions. 1 Answer
Help with Raycast C# 0 Answers
Raycast Physics2D not working as expected 1 Answer
Simulating Bullet Gravity using Raycasting 1 Answer
Physics2D, weird layerMask behavior on Linecast, Raycast and OverlapPoint 2 Answers