Search Unity

[RELEASED] GPU Line of Sight / Field of View

Discussion in 'Assets and Asset Store' started by Tycho, Jul 16, 2014.

  1. Ripityom

    Ripityom

    Joined:
    Jan 9, 2016
    Posts:
    22
    Oh too bad, I tried to be as specific as I could. Hiding whole renderers would work for for the enemies themselves, however they probably also will have their own line of sight. In my game currently I use desaturation and blur as image effects with the asset, and since I don't want enemies LoS to have impact on the camera effects I use a simple raycast / mesh renderer solution for them. This mesh can be quite large so if the player sees an enemy, the enemy's LoS can reach outside the players LoS so displaying the whole mesh is a little problematic.

    Can you suggest a solution to this problem by any chance?
    Is it possible to have multiple "group" of LoS, so for example for enemies only display their LoS as a simple color without affecting the desaturation / blur?
    Is it possible to display enemies LoS only inside players LoS with this asset?

    Thanks for the help.
     
  2. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    I think the easiest way to achieve this would be to use two LOSMask and LOSBufferStorage script components on your camera. The first set renders the LOS for the enemies, and then afterwards you render the LOS for the player on top. This way you can also have different image effects applied to both masks.

    You would only need to modify the LOSMask script, so that you can define which subset of LOS source you want to render to the mask (ex: enemies, player).

    So for example, you'd change this code at line 135:
    Code (CSharp):
    1.             for (int i = 0; i < losSources.Count; i++)
    2.             {
    3.                 if (losSources[i].IsVisible)
    4.                     RenderSourceToMask(losSources[i], ref maskRenderTexture);
    5.             }
    to

    Code (CSharp):
    1.             for (int i = 0; i < losSources.Count; i++)
    2.             {
    3.                 if (losSources[i].IsVisible && losSources[i].CompareTag("Enemy"))
    4.                     RenderSourceToMask(losSources[i], ref maskRenderTexture);
    5.             }
     
  3. ba3uk

    ba3uk

    Joined:
    Jul 15, 2017
    Posts:
    7
    Hi, I will buy your assets, but I have one question - how does all this work on mobile devices?
    Maybe there are some tests, screenshots?
     
  4. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    Hi,

    Mobile platforms are not supported, as stated on the asset store page.
     
  5. chiblue3D

    chiblue3D

    Joined:
    Apr 25, 2012
    Posts:
    19
    I just purchased this solution specifically because of my own solution performance using raycasting... My project is a third person where I have AI characters, the AI objects have a sensor script that loads a list of found targets, i.e. other game objects that are considered "enemy" based on several criteria... The reason I purchased this was to integrate it into my own project... What I am trying to do is to get any game objects that are in the Line of sight and then add the game objects to a list of enemy gameobjects being tracked... I don't seem to be able to get this to work... I created a script using code from the existing LOS scripts... The m_VisibilityInfo contains a value but no visible sources...

    Code (CSharp):
    1.    
    2. public class AIPlayerLOSSensor : MonoBehaviour
    3.     {
    4.  
    5.         private AISensorResponse _airesponse = new AISensorResponse();
    6.         private LOS.LOSVisibilityInfo m_VisibilityInfo;
    7.         private void OnEnable()
    8.         {
    9.             m_VisibilityInfo = GetComponent<LOS.LOSVisibilityInfo>();
    10.             _airesponse = GetComponent<R_AISensorResponse>();
    11.             if(_airesponse == null)
    12.             {
    13.                 Debug.LogWarning("No AISensorResponse class found on player");
    14.             }
    15.         }
    16.         private void Update()
    17.         {
    18.             foreach (LOS.ILOSSource losSource in m_VisibilityInfo.VisibleSources)
    19.             {
    20.                 Player _player = losSource.GameObject.GetComponent<Player>();
    21.                 // Only add LOS ources that aren't attached to the player
    22.                 if (_player != null && _player.GameState.CurrentState.IsPlaying)
    23.                 {
    24.                     _airesponse.AddTarget(losSource.GameObject);
    25.                 }
    26.             }
    27.         }
    28.  
    29.     }
     
  6. detournement_19

    detournement_19

    Joined:
    Oct 10, 2014
    Posts:
    5
    I understand that the asset doesn't currently support HDRP. Is that something you are considering adding? Curious if that's a time-consuming/complicated thing or not.
     
  7. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    If I understand your explanation correctly, I think you're using the LOSVisibilityInfo script component incorrectly.

    The LOSVisibilityInfo component is designed to check if an object is visible to any of the LOS sources in the scene, instead of returning a list of objects inside a LOS.

    So a solution would be to add a LOSVisibilityInfo component to the enemy objects (targets) instead of adding it to the AI objects.
     
  8. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    I still need to do more research to see how complicated it would be to get it working, but I'll try to look into it soon.
     
  9. chiblue3D

    chiblue3D

    Joined:
    Apr 25, 2012
    Posts:
    19
    So I have my script backwards... I should detect the check of the LOS sources on the enemy and then cast the LOS source game object to the AI target sensor class... guess I got is completely backwards... thanks

    I changed this around, but I am still getting no VisibleSources... I added the camera and the LOS Source to the AI as I previously stated, added the LOSVisibilityInfo to my Player, added the changed script to the Player, but still no sources are being detected??? is there something else I need?
     
    Last edited: Feb 19, 2019
  10. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    Yes, that's correct.

    The easiest way to do this would be to add a script to the enemies, which subscribes to the OnLineOfSightEnter and OnLineOfSightExit events of the attached LOSVisibilityInfo component.
    When one of the events are raised, check if the losSource parameter of the event has a AIPlayerLOSSensor component attached, and then add / remove the enemy to a list in that script.
     
  11. chiblue3D

    chiblue3D

    Joined:
    Apr 25, 2012
    Posts:
    19
    Ok I will play around with that option, by the way very much like this solution... particularly the performance..
     
  12. chiblue3D

    chiblue3D

    Joined:
    Apr 25, 2012
    Posts:
    19
    Ok I doing something wrong... this is the code, but the event is not firing...

    Code (CSharp):
    1.         LOSVisibilityInfo _losvisible;
    2.         private void OnEnable()
    3.         {
    4.             _losvisible = GetComponent<LOSVisibilityInfo>();
    5.             _losvisible.OnLineOfSightEnter += this.LineOfSightEnter;
    6.         }
    7.  
    8.         void LineOfSightEnter(GameObject sender, ILOSSource losSource)
    9.         {
    10.             Debug.Log("Line of sight from " + sender);
    11.         }
    You can ignore this, I had to add the components to a render objects, makes sense now.. works perfectly... thanks again
     
    Last edited: Feb 19, 2019
    Tycho likes this.
  13. Ripityom

    Ripityom

    Joined:
    Jan 9, 2016
    Posts:
    22
    Hi!

    The asset is working really great for my game so far, but I'm thinking about adding a fog-like effect outside the LOS most likely by using a particle system.
    Do you have any solution to mask a particle system based on LOS? If nothing else, is it possible to render using 2 cameras, one for inside and one for outside the LOS? I read something about this in this thread, but I couldn't figure out how to set up a 2-camera rendering like that.

    Thanks!
     
  14. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    To create a fog-like effect in the area outside of the LOS, I would suggest using image effects / post processing instead of particles, because it’s easier to implement and probably better for performance.

    Instead of using the standard desaturate effect, you could use a combination of image effects to simulate fog. I think what would work well is blur, color correction and some kind of animated texture overlay.

    If you’re using the deferred rendering pipeline, you could even use the global fog effect to create a height fog.
     
  15. Ripityom

    Ripityom

    Joined:
    Jan 9, 2016
    Posts:
    22
    I tried using the global fog image effect from the standard assets, but it seems to ignore the LOS mask (or the LOS ignores the image effect).
     
  16. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    Did you place the global fog image effect in between the LOSBufferStorage and LOSMask components on your camera object?
     
  17. Ripityom

    Ripityom

    Joined:
    Jan 9, 2016
    Posts:
    22
    Yes, this is how my camera is set up along with the result:
     

    Attached Files:

  18. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    Your setup looks correct.

    My guess is that the Global Fog image effect uses the ImageEffectOpaque attribute, which always forces it to render before transparent objects, ignoring the order you set in the inspector.

    I guess the simplest solution would be to emulate a blur effect using a combination of other image effects, or removing the attribute from the global fog OnRenderImage function.
     
  19. Ripityom

    Ripityom

    Joined:
    Jan 9, 2016
    Posts:
    22
    I'll give it a try and see how that turns out. Thanks!
     
    Tycho likes this.
  20. Ripityom

    Ripityom

    Joined:
    Jan 9, 2016
    Posts:
    22
    Removing the ImageEffectOpaque attribute solved the problem indeed. I didn't like the result but thanks for the help regardless :)
     
  21. Ripityom

    Ripityom

    Joined:
    Jan 9, 2016
    Posts:
    22
    I have another question. Most of my games mechanics are based around deciding if the player or other characters are in the light or darkness (visualized by this asset). I noticed that standing close to a wall that has a LOSSource on the other side (a lamp for instance) results in the player being registered as if she was in light. After checking the source code I understand that visibility calculations are based on the bounding box of the mesh instead of the mesh itself. Can you confirm that? Because this way working with a humanoid character makes it really inaccurate as the bounding box will be significantly larger as the mesh itself.
    Thanks in advance.
     
  22. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176

    Yes, that’s correct.

    But you could easily modify the LOSCuller script to use the bounds of a collider instead of the renderer.

    Simply change the update function from
    Code (CSharp):
    1.         private void Update()
    2.         {
    3.             m_IsVisible = CustomCull(gameObject.GetComponent<Renderer>().bounds, m_RaycastLayerMask.value);
    4.         }
    to

    Code (CSharp):
    1.         private void Update()
    2.         {
    3.             m_IsVisible = CustomCull(gameObject.GetComponent<Collider>().bounds, m_RaycastLayerMask.value);
    4.         }
    Because there are so many possible use-cases for this assets, I’ve decided to keep the detection scripts rather barebone so they’re easy to adapt to any situation.
     
    s_s_k and Ripityom like this.
  23. Zeevex

    Zeevex

    Joined:
    Jan 15, 2018
    Posts:
    22
    Hello Entropi,
    Before i'm to purchase this asset i'm looking into a 'This war of mine' pov & style LoS/Fog of war, where i can also use it for multiplayer and have other players invisible if they're out of line of sight(i.e. in a different room)
    based off of comments i've read this seems possible but am just looking for confirmation (":
     
  24. Zeevex

    Zeevex

    Joined:
    Jan 15, 2018
    Posts:
    22
    just tried the demo, seems possible :p
     
    Tycho likes this.
  25. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    Yes, this LOS system can also be used to handle visibility for multiplayer games. I've used it myself to create a prototype for a top-down tactical multiplayer shooter, where other players are only visible inside the LOS.

    But please keep in mind this asset is only for line of sight and does not provide a revealing fog of war effect.
     
  26. Zeevex

    Zeevex

    Joined:
    Jan 15, 2018
    Posts:
    22

    that's cool, all i'm after if the LoS capability.. however how would I have the cameras only render their own localplayer and not other players characters?
    i.r player 1 only sees player 1 if player 2 is out of LOS
    if player 2 enters sight, player 1 sees both player 1 and player 2
    upload_2019-4-7_14-26-22.png
     
  27. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    To achieve this you would need to instantiate different prefabs for local and remote players.

    Only the prefab for the local player should have an LOSSource component attached.
     
  28. BradFichter

    BradFichter

    Joined:
    Nov 17, 2016
    Posts:
    4
    Do you know if anyone has successfully gotten this to work on a HoloLens? The basic setup didn't work (just got the plugin) so I thought I would ask before digging in to see what the issues are. Could be image effects.
     
  29. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    Sorry for the late reply, but this asset was designed for standalone PC or Mac builds and does not support mobile platforms due to performance reasons, as mentioned on the asset store page.
     
  30. BradFichter

    BradFichter

    Joined:
    Nov 17, 2016
    Posts:
    4
    It is working on Hololens pretty well. Now I'm just trying to see where to modify the code to trigger the LOS render on an event rather than continually.
     
  31. Kamil-Sobierajski

    Kamil-Sobierajski

    Joined:
    Dec 14, 2016
    Posts:
    41
    Hey.
    I was trying to set LOS in LWRP. But I have 2 errors and some Alerts.

    Allers :
    The LOS Stencil Mask component does currently not support MSAA.
    Disabling MSAA in Quality Settings!
    UnityEngine.Debug:LogWarning(Object)
    LOS.LOSStencilMask:CheckSettings(Camera) (at Assets/Line Of Sight/Scripts/LOSStencilMask.cs:258)
    LOS.LOSStencilMask:Update() (at Assets/Line Of Sight/Scripts/LOSStencilMask.cs:273)

    Errors:
    Assets\Line Of Sight\Example Scene\Assets\Scripts\AINPC.cs(3,26): error CS0246: The type or namespace name 'NavMeshAgent' could not be found (are you missing a using directive or an assembly reference?)

    Is this system incompatible? It will be upgraded? Or left how it is?
     
  32. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    The asset does not support the LWRP, as clearly mentioned on the Unity Asset Store page, but the errors you're seeing are not related to the use of the LWRP.

    Regarding the first warning; If you want to use MSAA in your project, you can use the LOS Layer Excluder instead of the LOS Stencil Mask component. Please check section 2.2 of the documentation for more details.

    The compiler error is caused by a change in Unity namespaces. The script containing the error is part of the included example scene. You can either delete the entire "Example Scene" folder, or add "using UnityEngine.AI;" at the top of the script.
     
  33. Kamil-Sobierajski

    Kamil-Sobierajski

    Joined:
    Dec 14, 2016
    Posts:
    41
    Hey.
    I work on 2019.1 PBR.
    I have problem with builds, everything worked fine but I can't make a build. So I make a fresh project and try again. But the problem is the same. I was trying to make build before I Instal LOS and it was work. So I need to find what is wrong after add LOS.

    After build (Build failed) I have a lot of alerts about LOS scripts.

    upload_2019-9-1_0-47-23.png

    The error about LOS is:
    Assets\Line Of Sight\Scripts\LOSHelper.cs(199,26): error CS1061: 'Camera' does not contain a definition for 'hdr' and no accessible extension method 'hdr' accepting a first argument of type 'Camera' could be found (are you missing a using directive or an assembly reference?)​

    When I click on this error it point me to the LOSHelper script.

    Well. I was check in unity helper and I was a different setting for HDR on my camera.
    It looks like this:
    upload_2019-9-1_1-5-23.png
    And I have only 2 settings. I can use Grphicssetting or set if Off.
    But this must change not so long ago, becouse in help we have scrin witch checkbox on HDR.
    It look like this:
    upload_2019-9-1_1-7-13.png

    So My camera uses Graphic settings. But I cant find any kind of HDR settings in Project settings. Did you maybe know where I need to search for this stuff?

    I have no idea about Player error ( Error building Player because scripts had compiler errors ). And secound one about build player window
    UnityEditor.BuildPlayerWindow+BuildMethodException: 2 errors
    at UnityEditor.BuildPlayerWindow+DefaultBuildMethods.BuildPlayer (UnityEditor.BuildPlayerOptions options) [0x00242] in C:\buildslave\unity\build\Editor\Mono\BuildPlayerWindowBuildMethods.cs:194
    at UnityEditor.BuildPlayerWindow.CallBuildMethods (System.Boolean askForBuildLocation, UnityEditor.BuildOptions defaultBuildOptions) [0x0007f] in C:\buildslave\unity\build\Editor\Mono\BuildPlayerWindowBuildMethods.cs:97
    UnityEngine.GUIUtility:processEvent(Int32, IntPtr)​

    Did you have some tips what can help me with this?
     
  34. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    Hi,

    I just tried importing the asset into an empty project using Unity version 2019.1.14f1 and everything seems to be working as expected. I also tried creating a standalone build with the example scene, and there were no compiler errors and the build worked as expected.

    When importing the asset into your project, you'll be prompted with the API Update Required dialog window. Be sure to select the "I Made a Backup. Go Ahead!" button. This will update the code of the asset and replace any obsolete API function calls with the correct ones.

    The LOSHelper script will also be updated and the error will disappear. There will still be some compiler warnings, but those can be safely ignored.
     
  35. peon

    peon

    Joined:
    Aug 6, 2012
    Posts:
    13
    Hi,

    I've been playing around with your asset. It's a nice one, I like it.

    I've couple of questions though:

    1. Can I stop LOS source cameras Target Texture rendering while game is not running? The constant rendering seems to slow down my poor old computer.
    renderTexture.png


    2. When I rotate my Player (and camera) I get jitter on some edges of fov. Can I do something about these jittery edges:

    jitteryEdges.png

    Thanks in advance.
     
  36. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    1. You could remove the [ExecuteInEditMode] attribute from the top of LOSMask.cs script. This will stop it from running in the editor, but this will also cause the effect to not be visible in the editor.
    2. Increasing the Render Target Width and Height properties on the LOS source should reduce the jitter. You can also try reducing the far clipping distance for the attached camera.
    Let me know if you have any other question ;)
     
  37. BradFichter

    BradFichter

    Joined:
    Nov 17, 2016
    Posts:
    4
    Hi,

    Adding the LOS Stencil Renderer to a GameObject containing a LineRenderer doesn't seem to work. LineRenderer still included. It does work for a cube in the same scene. Did I miss something somewhere?

    Thanks
     
  38. Ripityom

    Ripityom

    Joined:
    Jan 9, 2016
    Posts:
    22
    I just wanted to thank you for this, just tried and works great. I ended up using it for something different, but really works great.
    I'm curious: how does having two LOS mask and buffer storage impact performance?
     
  39. Ripityom

    Ripityom

    Joined:
    Jan 9, 2016
    Posts:
    22
    Also I noticed that the Unity post processing is only applied inside the mask, but not outside, is it a known behaviour, and if so do you know of any workarounds? Thanks!
     
  40. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    I'm afraid the LOS Stencil Renderer component current only works with Mesh or Skinned Mesh Renderer components.
     
  41. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    The performance penalty should be fine if you only render a subset of LOS sources per LOS mask. Rendering the LOS sources and calculating their line of sight is the most expensive part of this system.

    Could you post a screenshot of the inspector showing how your main camera is setup with the LOS mask components and post processing? The order of the components determine to what part of the image the post processing is applied.
     
  42. Ripityom

    Ripityom

    Joined:
    Jan 9, 2016
    Posts:
    22
    I think it would be best if I quickly explained what I'd like to achieve:
    I need to have 3 levels of vision:
    1. Areas affected by light with full saturation and brightness
    2. Areas that are not effected by light but directly visible by the player are desaturated with 0.2 brightness
    3. Other areas are in complete darkness
    upload_2019-9-20_14-12-37.png

    I modified the LOS Mask script so you can specify a list of tags that the mask should be applied to. So right now I have two masks on the same camera object: one that is applied to the Flashlight tag (that tag is used for light sources) and does the 0.2 desaturation, and one that is applied to the Player AND the Flashlight tag that creates the complete darkness for areas that are not visible by the player or any light sources. The post processing is at the bottom of the component list.

    upload_2019-9-20_14-13-27.png

    The strange thing is that it seems that some image effects, Color Grading for example are applied to the whole image, but others, like Antialiasing is not.

    There also might be a better or more efficient way to achieve what I do, I don't know...

    Thanks for the help in advance!
     
  43. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    Your setup looks correct.

    My best guess is that the some of the post processing effects don't respect the order set in the inspector, or use the stencil buffer.

    Can you try disabling the LOS Stencil Mask and LOS Stencil Mask Renderer components and see if that changes anything?
     
  44. Ripityom

    Ripityom

    Joined:
    Jan 9, 2016
    Posts:
    22
    I updated the Post Processing stack from the package manager which seemed to fixed this issue, however now the antialiasing is not applied to the edge of the LoS:
    upload_2019-9-20_16-9-5.png
    Any idea?
     
  45. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    Which type of AA are you using?

    Some algorithms might not detect it as an edge because it's not part of the actual geometry.
     
  46. Ripityom

    Ripityom

    Joined:
    Jan 9, 2016
    Posts:
    22
    I'm using FXAA, but it's the same for all available (SMAA, TAA)
     
  47. Tycho

    Tycho

    Joined:
    Nov 24, 2012
    Posts:
    176
    Mhh, that's odd. It sounds like the AA is not being applied to the final resulting image then. I'll have to check if there's a workaround. What version of the post processing stack are you using?
     
  48. Ripityom

    Ripityom

    Joined:
    Jan 9, 2016
    Posts:
    22
    2.1.7.
    On the Post Processing Layer component there is a "Directly to Camera Target" flag, but it basically disables the whole LoS.
     
    Tycho likes this.
  49. Ripityom

    Ripityom

    Joined:
    Jan 9, 2016
    Posts:
    22
    I found another anomaly which might help:I managed to take objects get hidden partially by using two cameras, but it only works when the post processing layer conponent is enabled in the camera with lower depth. If I disable it then it seems like LoS would mess up the depth buffer in some way... If I enable post processing or disable LoS its working as expected.
     
  50. Ripityom

    Ripityom

    Joined:
    Jan 9, 2016
    Posts:
    22
    Hi,

    I have a quick question: in my topdown game most of the level is black, only parts visible to the player is rendered. Is there another way to render areas outside it (for example explosions) without using a 360 setup with 6 cameras? It works but I'm a little bit worried about performance. Thanks