Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

How to: Lens Flare : Ignore Layers programatically? (C#)

Discussion in 'Scripting' started by Antypodish, Jul 16, 2018.

  1. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,558
    Basically I am trying to change Lens Flare -> Ignore Layers programatically in c#. But it seams, I can not see the relevant methods, or value to do so.

    So I try to grab lensFlare from object:
    Code (CSharp):
    1. LensFlare lensFlare = gameObjectWithLensFlare.GetComponent <LensFlare> () ;
    And then search for anything, related to layer, ignore, or mask. But I can not find it (via Visual Studio) ;
    lensFlare has other exposed components, like Flare, Color, Brightness, Fade Speed.
    But Neither Ignore Layers, nor Directional options are available via script.

    Does anyone knows, where they are hidden?

    PS.
    Reference to API:LensFlare
    https://docs.unity3d.com/Manual/class-LensFlare.html
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,599
    LensFlare is a component. Components plug into GameObjects. GameObjects expose all the common things like tags and layers and whatnot.

    Code (csharp):
    1.          LensFlare lensFlare = gameObjectWithLensFlare.GetComponent <LensFlare> () ;
    2.  
    3.         lensFlare.gameObject.tag = "MySpiffyTag";
    4.         lensFlare.gameObject.layer = 13;
    Although in your case above you already HAVE the gameObjectWithLensFlare, so just use that directly!
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,599
    Ooop-edit: re-read your post a bit more. It does not appear the actual in-component Ignore Layers property is exposed, at least not in my 2017.3.1 Unity. The docs are currently for 2018.2 so it's possible they did expose more in the latest Unity.
     
  4. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,558
    Thx for a response.
    Indeed you initial response, is not what I was after.

    Regarding dock for 2018, this is Unity version that I am working on.
    Here is dock for 2017.4. But I believe, the lens flare component is even older. But I may be wrong, if I don't see docks prior to 2017.4. By quick look at, there is little to no difference between both docs.

    Just for better clarification, I can do for example
    Code (CSharp):
    1. LensFlare lensFlare = gameObjectWithLensFlare.GetComponent <LensFlare> () ;
    2. lensFlare.fadeSpeed = 1 ;
    But as have you noticed, I can NOT, do

    Code (CSharp):
    1. LensFlare lensFlare = gameObjectWithLensFlare.GetComponent <LensFlare> () ;
    2. lensFlare.ignoreLayers = 10 ;
    or equivalent, since the property is not exposed.

    At the moment, this puts me at the position, that instead having one elegant object, with simple mask switch via code, I may end up with anything between 5 to even 20 extra flare objects, with preset relevant masks via inspector for each, which I simply enable, or disable then via code.
    Also, that creates potential future development problem, as if I add new layers, I need explicitly remember, to adjust Ignored Layers mask for each of the flare object.
    Additionally, since I cannot see the variable for these flare masks in C#, I cannot create programatically all of these flare objects. :(

    I still hope there is some hidden way.
    Maybe even via reflections, since I would call switch method no more often, than once a few min.
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,599
    That's probably the best way. Having thought on this even more I seem to remember there was a property like this in WindZones that was not exposed and we ended up reflecting on it to get at it.

    On the one hand it's not the best idea and subject to future breakage, but on the other hand, it is a documented property visible in the Unity inspector, which of course gets at it with reflection too.

    Good luck!
     
  6. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,558
    I tried reflection
    Code (CSharp):
    1. System.Reflection.MethodInfo [] methods = typeof(LensFlare).GetMethods();
    2. System.Reflection.PropertyInfo [] properties = typeof(LensFlare).GetProperties();
    To get both properties and methods and unless I am blind, I don't see there anything, which referees to layers.
    I may come back to this later, with some fresher ideas.
    Didn't expected to be so troublesome.
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,599
    Ah that's reflection in a nutshell my friend. :)

    I concur with your findings. I did some more digging, asked for more binding flags and still got nothing useful that looked like ignoring stuff.

    I also looked into UnityEngine.Flare but got nothing useful there.

    This was my snippet of working code (it's a mess, bunch of commented-out things I tried):

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.UI;
    6. using System.Reflection;
    7.  
    8. public class TestLensflare : MonoBehaviour
    9. {
    10.     public Text text;
    11.  
    12.     void Start ()
    13.     {
    14.         System.Reflection.FieldInfo [] fields = typeof(LensFlare).GetFields( BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
    15.  
    16.         System.Reflection.MethodInfo [] methods = typeof(LensFlare).GetMethods( BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
    17. //        System.Reflection.MethodInfo [] methods = typeof(Flare).GetMethods( BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
    18.  
    19.         System.Reflection.PropertyInfo [] properties = typeof(LensFlare).GetProperties( BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
    20. //        System.Reflection.PropertyInfo [] properties = typeof(Flare).GetProperties( BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
    21.  
    22.         string s = "Entire list:\n";        // StringBuilder is welcome to bite me
    23.  
    24.         text.text = "Fields:";
    25.         s += "\nFields:";
    26.  
    27.         foreach( var f in fields)
    28.         {
    29.             Debug.Log( "field:" + f.ToString());
    30.             text.text += "\n" + f.ToString();
    31.             s += "\n" + f.ToString();
    32.         }
    33.  
    34.         text.text += "\nMethods:";
    35.         s += "\nMethods:";
    36.  
    37.         foreach( var m in methods)
    38.         {
    39.             Debug.Log( "method:" + m.ToString());
    40.             text.text += "\n" + m.ToString();
    41.             s += "\n" + m.ToString();
    42.         }
    43.  
    44.         text.text += "\nProperties:";
    45.         s += "\nProperties:";
    46.  
    47.         foreach( var p in properties)
    48.         {
    49.             Debug.Log( "property:" + p.ToString());
    50.             text.text += "\n" + p.ToString();
    51.             s += "\n" + p.ToString();
    52.         }
    53.  
    54.         System.IO.File.WriteAllText( "TestLensflare.txt", s);
    55.     }
    56. }
    57.  
    58.  
    And this was my final output list of methods:

    Entire list:

    Fields:
    Methods:
    UnityEngine.Flare get_flare()
    Void set_flare(UnityEngine.Flare)
    Single get_brightness()
    Void set_brightness(Single)
    Single get_fadeSpeed()
    Void set_fadeSpeed(Single)
    Color get_color()
    Void set_color(Color)
    Void INTERNAL_get_color(Color ByRef)
    Void INTERNAL_set_color(Color ByRef)
    Boolean get_enabled()
    Void set_enabled(Boolean)
    Boolean get_isActiveAndEnabled()
    UnityEngine.Transform get_transform()
    UnityEngine.GameObject get_gameObject()
    UnityEngine.Component GetComponent(System.Type)
    Void GetComponentFastPath(System.Type, IntPtr)
    T GetComponent[T]()
    UnityEngine.Component GetComponent(System.String)
    UnityEngine.Component GetComponentInChildren(System.Type, Boolean)
    UnityEngine.Component GetComponentInChildren(System.Type)
    T GetComponentInChildren[T]()
    T GetComponentInChildren[T](Boolean)
    UnityEngine.Component[] GetComponentsInChildren(System.Type)
    UnityEngine.Component[] GetComponentsInChildren(System.Type, Boolean)
    T[] GetComponentsInChildren[T](Boolean)
    Void GetComponentsInChildren[T](Boolean, System.Collections.Generic.List`1[T])
    T[] GetComponentsInChildren[T]()
    Void GetComponentsInChildren[T](System.Collections.Generic.List`1[T])
    UnityEngine.Component GetComponentInParent(System.Type)
    T GetComponentInParent[T]()
    UnityEngine.Component[] GetComponentsInParent(System.Type)
    UnityEngine.Component[] GetComponentsInParent(System.Type, Boolean)
    T[] GetComponentsInParent[T](Boolean)
    Void GetComponentsInParent[T](Boolean, System.Collections.Generic.List`1[T])
    T[] GetComponentsInParent[T]()
    UnityEngine.Component[] GetComponents(System.Type)
    Void GetComponents(System.Type, System.Collections.Generic.List`1[UnityEngine.Component])
    Void GetComponents[T](System.Collections.Generic.List`1[T])
    System.String get_tag()
    Void set_tag(System.String)
    T[] GetComponents[T]()
    Boolean CompareTag(System.String)
    Void SendMessageUpwards(System.String, System.Object, SendMessageOptions)
    Void SendMessageUpwards(System.String, System.Object)
    Void SendMessageUpwards(System.String)
    Void SendMessageUpwards(System.String, SendMessageOptions)
    Void SendMessage(System.String, System.Object, SendMessageOptions)
    Void SendMessage(System.String, System.Object)
    Void SendMessage(System.String)
    Void SendMessage(System.String, SendMessageOptions)
    Void BroadcastMessage(System.String, System.Object, SendMessageOptions)
    Void BroadcastMessage(System.String, System.Object)
    Void BroadcastMessage(System.String)
    Void BroadcastMessage(System.String, SendMessageOptions)
    UnityEngine.Component get_rigidbody()
    UnityEngine.Component get_rigidbody2D()
    UnityEngine.Component get_camera()
    UnityEngine.Component get_light()
    UnityEngine.Component get_animation()
    UnityEngine.Component get_constantForce()
    UnityEngine.Component get_renderer()
    UnityEngine.Component get_audio()
    UnityEngine.Component get_guiText()
    UnityEngine.Component get_networkView()
    UnityEngine.Component get_guiElement()
    UnityEngine.Component get_guiTexture()
    UnityEngine.Component get_collider()
    UnityEngine.Component get_collider2D()
    UnityEngine.Component get_hingeJoint()
    UnityEngine.Component get_particleEmitter()
    UnityEngine.Component get_particleSystem()
    System.String get_name()
    Void set_name(System.String)
    HideFlags get_hideFlags()
    Void set_hideFlags(HideFlags)
    System.String ToString()
    Int32 GetInstanceID()
    Int32 GetHashCode()
    Boolean Equals(System.Object)
    Void Finalize()
    System.Type GetType()
    System.Object MemberwiseClone()
    IntPtr obj_address()
    Properties:
    UnityEngine.Flare flare
    System.Single brightness
    System.Single fadeSpeed
    UnityEngine.Color color
    System.Boolean enabled
    System.Boolean isActiveAndEnabled
    UnityEngine.Transform transform
    UnityEngine.GameObject gameObject
    System.String tag
    UnityEngine.Component rigidbody
    UnityEngine.Component rigidbody2D
    UnityEngine.Component camera
    UnityEngine.Component light
    UnityEngine.Component animation
    UnityEngine.Component constantForce
    UnityEngine.Component renderer
    UnityEngine.Component audio
    UnityEngine.Component guiText
    UnityEngine.Component networkView
    UnityEngine.Component guiElement
    UnityEngine.Component guiTexture
    UnityEngine.Component collider
    UnityEngine.Component collider2D
    UnityEngine.Component hingeJoint
    UnityEngine.Component particleEmitter
    UnityEngine.Component particleSystem
    System.String name
    UnityEngine.HideFlags hideFlags
     
    SamFernGamer4k and Antypodish like this.
  8. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,558
    Thats great contribution and log dump to txt.
    I used your code, to look also inside FlareLayer, since LensFlare requires it on the camera.
    I thought maybe there is something hidden. But neither found anything useful.
    Therefore, I have no idea, what a black magic is there in play?

    Code (CSharp):
    1. Entire list:
    2.  
    3. Fields:
    4. Methods:
    5. Boolean get_enabled()
    6. Void set_enabled(Boolean)
    7. Boolean get_isActiveAndEnabled()
    8. UnityEngine.Transform get_transform()
    9. UnityEngine.GameObject get_gameObject()
    10. UnityEngine.Component GetComponent(System.Type)
    11. Void GetComponentFastPath(System.Type, IntPtr)
    12. T GetComponent[T]()
    13. UnityEngine.Component GetComponent(System.String)
    14. UnityEngine.Component GetComponentInChildren(System.Type, Boolean)
    15. UnityEngine.Component GetComponentInChildren(System.Type)
    16. T GetComponentInChildren[T](Boolean)
    17. T GetComponentInChildren[T]()
    18. UnityEngine.Component[] GetComponentsInChildren(System.Type, Boolean)
    19. UnityEngine.Component[] GetComponentsInChildren(System.Type)
    20. T[] GetComponentsInChildren[T](Boolean)
    21. Void GetComponentsInChildren[T](Boolean, System.Collections.Generic.List`1[T])
    22. T[] GetComponentsInChildren[T]()
    23. Void GetComponentsInChildren[T](System.Collections.Generic.List`1[T])
    24. UnityEngine.Component GetComponentInParent(System.Type)
    25. T GetComponentInParent[T]()
    26. UnityEngine.Component[] GetComponentsInParent(System.Type, Boolean)
    27. UnityEngine.Component[] GetComponentsInParent(System.Type)
    28. T[] GetComponentsInParent[T](Boolean)
    29. Void GetComponentsInParent[T](Boolean, System.Collections.Generic.List`1[T])
    30. T[] GetComponentsInParent[T]()
    31. UnityEngine.Component[] GetComponents(System.Type)
    32. Void GetComponents(System.Type, System.Collections.Generic.List`1[UnityEngine.Component])
    33. Void GetComponents[T](System.Collections.Generic.List`1[T])
    34. System.String get_tag()
    35. Void set_tag(System.String)
    36. T[] GetComponents[T]()
    37. Boolean CompareTag(System.String)
    38. Void SendMessageUpwards(System.String, System.Object, SendMessageOptions)
    39. Void SendMessageUpwards(System.String, System.Object)
    40. Void SendMessageUpwards(System.String)
    41. Void SendMessageUpwards(System.String, SendMessageOptions)
    42. Void SendMessage(System.String, System.Object)
    43. Void SendMessage(System.String)
    44. Void SendMessage(System.String, System.Object, SendMessageOptions)
    45. Void SendMessage(System.String, SendMessageOptions)
    46. Void BroadcastMessage(System.String, System.Object, SendMessageOptions)
    47. Void BroadcastMessage(System.String, System.Object)
    48. Void BroadcastMessage(System.String)
    49. Void BroadcastMessage(System.String, SendMessageOptions)
    50. UnityEngine.Component get_rigidbody()
    51. UnityEngine.Component get_rigidbody2D()
    52. UnityEngine.Component get_camera()
    53. UnityEngine.Component get_light()
    54. UnityEngine.Component get_animation()
    55. UnityEngine.Component get_constantForce()
    56. UnityEngine.Component get_renderer()
    57. UnityEngine.Component get_audio()
    58. UnityEngine.Component get_guiText()
    59. UnityEngine.Component get_networkView()
    60. UnityEngine.Component get_guiElement()
    61. UnityEngine.Component get_guiTexture()
    62. UnityEngine.Component get_collider()
    63. UnityEngine.Component get_collider2D()
    64. UnityEngine.Component get_hingeJoint()
    65. UnityEngine.Component get_particleEmitter()
    66. UnityEngine.Component get_particleSystem()
    67. Int32 GetInstanceID()
    68. Int32 GetHashCode()
    69. Boolean Equals(System.Object)
    70. System.String get_name()
    71. Void set_name(System.String)
    72. HideFlags get_hideFlags()
    73. Void set_hideFlags(HideFlags)
    74. System.String ToString()
    75. Void Finalize()
    76. System.Type GetType()
    77. System.Object MemberwiseClone()
    78. IntPtr obj_address()
    79.  
    80.  
    81. Properties:
    82. System.Boolean enabled
    83. System.Boolean isActiveAndEnabled
    84. UnityEngine.Transform transform
    85. UnityEngine.GameObject gameObject
    86. System.String tag
    87. UnityEngine.Component rigidbody
    88. UnityEngine.Component rigidbody2D
    89. UnityEngine.Component camera
    90. UnityEngine.Component light
    91. UnityEngine.Component animation
    92. UnityEngine.Component constantForce
    93. UnityEngine.Component renderer
    94. UnityEngine.Component audio
    95. UnityEngine.Component guiText
    96. UnityEngine.Component networkView
    97. UnityEngine.Component guiElement
    98. UnityEngine.Component guiTexture
    99. UnityEngine.Component collider
    100. UnityEngine.Component collider2D
    101. UnityEngine.Component hingeJoint
    102. UnityEngine.Component particleEmitter
    103. UnityEngine.Component particleSystem
    104. System.String name
    105. UnityEngine.HideFlags hideFlags
     
  9. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,599
    It really could be anything: they could have a few accessor functions in the lowest C++ level engine code and reveal them through some other adjunct mechanism that the Unity Editor can discover using some other dark corner of their API that we don't have insight into.
     
  10. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    It doesn't even have bindings for the ignore layers in the source code, which is very odd: https://github.com/Unity-Technologi...Runtime/Export/GraphicsComponents.bindings.cs (or for directional for some reason?)

    I wonder where it's getting the values from.

    Anyways -- to fix your actual issue -- set your flare ignore layers to Everything so that it never turns off manually and set the Brightness to 0. Use a manual raycast from your camera to the light source and if nothing blocks the raycast, lerp the Brightness to the desired value using the fade speed. That's exactly how the flare works internally anyways.
     
    Antypodish likes this.
  11. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,558
    One one side, I do wonder, why this Ignore Layers property is so hidden from the world. This also apples to Lens Flare Directional Boolean flag (irrelevant for my need atm.).
    On other hand,

    This seams very interesting and I am urged to try it out as soon as possible. Sounds like actual effective solution. Many thanks.

    I will come back later, to report results.
     
  12. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,558
    After previous discussion I have resolved the problem, as GroZZleR suggested, using raycast. Therefore, I managed to get down, to one object per flare. Many thanks.

    Lens Flare in the Project
    Just out of curiosity, if anyone would ask regarding discussed application and need for it.
    In my project I use Lense Flares for multiple suns in single solar system. In the future, possibly something else as well may be source of flare. This normally is not the issue.

    Multiple Parallel Worlds
    However, as solar system is expected, it contains multiple celestial bodies. In my case that extra 4 planets, as per current prototype. Each planet, or I call them also worlds, can have own gravity and objects. These are active on each planet at the same time, but without interacting between worlds.

    Large Distances
    Providing planets are small, it is easy to make them offset in Cartesian space, so physics and light do not clashes. Yet in my project, each planet may be as big as 1000 diameter. This means, if using large distances, I would be running int floating point issues.

    Avoiding Floating Origin
    To avoid floating point issue, yet having physics going on each planet, without floating origin shifting, my each planet and related objects are in 0 origin. This means each planet shares space, with other planets. Hence, requirement for setting different layers for each planet and their objects.

    Lens Flare - Ignoring Layer Case Study
    Here is the Lens Flare matter coming to play. Normally, Lens Flare is colliding with every active collider, with consideration of the ignore layers on lens flare itself. However, if I am on one of the planet, the Lens Flare can be obstructed by any object. Even from other active, but invisible planets and their objects. Then I can "travel" to another planet, by simply switching programatically the camera culling mask. This is by allowing camera see only objects on relevant world at given time.

    Lens Flare With Raycast
    Therefore, here comes idea of setting Ignore Layers prgrammatically for Lens Flares as well, so I can have same source of flare as one object, for multiple worlds, without switching collides of each object, or additional trickery, with layers and colliders. Now by using raycast, I can easly provide relevant mask, to which flare should fade in and out. And additionally, I got more flexibility, when to add and fade flares.

    Extra: Interplanetary Travel
    In my project I use another layer and camera, for rendering scalled down the solar system, with has orbiting planets. From there, I can click on every planet, and zoom in to the relevant world (layer switch).

    And screenshot from a prototype, with selected multiple worlds and their vertical spinning axis (as cylinder). They are all overlapping (since at 0 origin) and their cubes as well, without physics clashing. And in same scene, partial trailed orbits of traveling planets.


    LensFlares 01.jpg
     
    SamFernGamer4k likes this.