• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Lypheus · Apr 30, 2010 at 11:41 PM · physicsraycastsight

Line of Sight with Physics.Linedraw or Physics.Raycast Unreliable?

Alright, so I'm trying to implement a basic LoS algorithm here and while it seems pretty obvious at first, something is just not right - Physics.Linedraw (or Raycast) seem quite flakey in returning consistent LoS detection.

I have a screenshot showing a case where I'm clearly within LoS but its not being picked up (green lines = LoS, red lines = no LoS).

http://grab.by/47J0

If I walk around it constantly flips between having LoS or not. If your behind something obvious, such as the hill, at least that seems consistent - so there must be some kind of artifact causing this. When I use a 3DText over the heads of red line npc's, it always comes back as the hit.collider.name == "Terrain", yet its clear that terrain is not directly causing this.

Heres the simplified code below, I'm aware its costly and inefficient, right now my focus is in trying to get this working 100% consistently ... it's probably something silly but I'm at a loss:

    // TODO: This MUST be moved into a place thats only called when PC's MOVE or Environment Changes!  Calling in Update() will be insanely expensive
private void CheckLoS()
{
    // walk over each non-player controlled entity in scene (TODO: needs culling with range check)
    foreach(GameObject subject in GameObject.FindGameObjectsWithTag("NPC"))
    {
        // check against each player controlled entity in scene
        foreach (GameObject player in GameObject.FindGameObjectsWithTag("Player"))
        {
            // add +2.0f to y-axis to account for height of player/npc (hardcoded for now, top of rigidbody/collider later)
            Vector3 playerPosition = player.transform.position + new Vector3(0.0f, 2.0f, 0.0f);
            Vector3 subjectPosition = subject.transform.position + new Vector3(0.0f, 2.0f, 0.0f);
            if (!Physics.Linecast(playerPosition, subjectPosition))
            {
                Debug.DrawLine(playerPosition, subjectPosition, Color.green);
            }
            else
            {
                Debug.DrawLine(playerPosition, subjectPosition, Color.red);
            }
        }
    }
}
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by Peter G · May 01, 2010 at 01:48 AM

One thing I notice that your script may not be accounting for is that the linecast will collide with the NPC's collider also because Unity is checking if a line between one position and another collides with anything. So even if there is a LoS to your NPC from your player, it will return false because the player's colliders will be hit. So you have to change you linecast to:

RaycastHit hit;

if(Physics.Linecast(playerPosition, subjectPosition, hit)) { if(subject.collider == hit.collider) Debug.DrawLine(playerPosition, subjectPosition, Color.green);

  else  
       Debug.DrawLine(playerPosition, subjectPosition, Color.red);

}

else { Debug.DrawLine(playerPosition, subjectPosition, Color.green);//not sure what this would be if we missed, because we should always hit something. }

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Lypheus · May 01, 2010 at 03:47 AM 0
Share

You are 100% correct - it was the players collision box causing this, just two thoughts to add here:

  1. The code you listed definitely works, but just for future reference for anyone stumbling on this - the "hit" parameter should be "out hit" to satisfy the Physics.Linecast API.

  2. I'm wondering if using a layer filter and assigning it to "player" soldiers would be more efficient or does it really matter here?

avatar image Lypheus · May 01, 2010 at 04:10 AM 0
Share

I am seeing the last "else" case happening right now, it switches between the two green cases as i move a PC around - is this most likely poor/missing colliders on the subject and/or player? I do know the subjects are not setup right atm.

avatar image spinaljack · May 01, 2010 at 09:04 AM 0
Share

Layer masks makes physics much faster so you should use it as much as you can

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

No one has followed this question yet.

Related Questions

HOW DO I USE RAYCASTHIT 2D???? 1 Answer

Is it possible to allow a raycast to pass through a collider to hit things behind it? 6 Answers

Applying Normal force from ground to player 1 Answer

Problem With Physics.Raycast 1 Answer

2D Slope acceleration 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges