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. Dismiss Notice

Question Editor script - how to change lighting settings?

Discussion in 'Scripting' started by fuzzy3d, Feb 2, 2023.

  1. fuzzy3d

    fuzzy3d

    Joined:
    Jun 17, 2009
    Posts:
    219
    Hi,
    I would like to use a Editor script to change this:
    upload_2023-2-2_13-53-36.png
    to this:
    upload_2023-2-2_13-54-16.png

    "Cast Shadows" -> Two Sided
    "Static Shadow Caster" -> true
    "Contribute Global Illumination" -> Light Probes

    It's beyond my level... please help.
    Thank you
     
  2. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    Do you mean you'd like to click a button and update all selected objects to those settings?

    That would involve 4 things:
    - Creating your button/menu-item, and having it call a (static) method. => Customising Unity’s Menu Bar using MenuItem | Unity Tips (hugecalf-studios.github.io)
    - Grabbing everything from the active selection => Unity - Scripting API: Selection (unity3d.com)
    - Looping through the Renderers (GetComponents<Renderer>()) and setting the variables like you would normally do. => Unity - Scripting API: Renderer (unity3d.com) (see ShadowCastingMode, LightProbeUsage, etc)
    - 'Dirtying' the objects so the changes can be saved. => Unity - Scripting API: EditorUtility.SetDirty (unity3d.com)
     
    unity_H69WxuyUa80urA likes this.
  3. fuzzy3d

    fuzzy3d

    Joined:
    Jun 17, 2009
    Posts:
    219
    I can do everything except ShadowCastingMode, LightProbeUsage.. settings. I can add menu item, loop thru selected, but I cannot set values in Inspector properly...


    [MenuItem("moje/add Collider LOD0")]
    static void VypniStiny()
    {
    foreach (var model in Selection.gameObjects)
    {
    foreach (var r in model.GetComponentsInChildren<MeshRenderer>())
    {
    SerializedObject so = new SerializedObject(r);
    //
    r.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.TwoSided;
    r.staticShadowCaster = true;
    //
    GameObjectUtility.SetStaticEditorFlags(r.gameObject, StaticEditorFlags.ContributeGI);
    //
    so.FindProperty("m_ScaleInLightmap").floatValue = 0f;
    //
    //SerializedProperty lightProbeUsageProp = so.FindProperty("m_LightProbeUsage");
    //lightProbeUsageProp.intValue = 1;
    //
    //r.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.BlendProbes;
    //
    if (r.gameObject.name.Contains("_LOD0"))
    {
    if(r.gameObject.GetComponent<BoxCollider>() == null)
    {
    BoxCollider _bc = (BoxCollider)r.gameObject.AddComponent(typeof(BoxCollider));
    }
    }
    //
    so.ApplyModifiedProperties();
    }
    }
    }


    add collider is o.k....
    unity 2022.2
     
    Last edited: Feb 2, 2023
  4. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    What do you mean by "I cannot set values in Inspector properly"?
     
  5. fuzzy3d

    fuzzy3d

    Joined:
    Jun 17, 2009
    Posts:
    219
    The code I wrote does not change the values of the selected game object (in the Inspector).

    r.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.TwoSided;
    r.staticShadowCaster = true;
    is not working
    but
    so.FindProperty("m_ScaleInLightmap").floatValue = 0f;
    yes
     
  6. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,194
    If you take your inspector into debug mode, and then hold down alt, the labels will show the actual internal property names rather than display names.
     
    Chubzdoomer likes this.
  7. fuzzy3d

    fuzzy3d

    Joined:
    Jun 17, 2009
    Posts:
    219
    I see...
    Everything works now for me (more or less) except "Receive Global Illumination", change from Lightmaps to Light Probes. I want Light Probes.
     
  8. fuzzy3d

    fuzzy3d

    Joined:
    Jun 17, 2009
    Posts:
    219
    Ha!
    You can right-click on Inspector property!
    upload_2023-2-2_18-10-29.png
    Then "Copy Property Path" and... It is working now!

    EDIT: I'm going crazy, I have to run this script twice to see the correct values in the Inspector(?!)
     
    Last edited: Feb 2, 2023
    Chubzdoomer likes this.
  9. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,194
    It might be that the inspector doesn't update? It doesn't automatically detect that the underlying data has changed at it needs to redraw.

    Try clicking on the inspector somewhere after you run the script, that will redraw it. Alternatively, deselect the light and then reselect it.

    Also, just to be sure: You are calling ApplyModifiedProperties on the light's SerializedObject, right?
     
  10. fuzzy3d

    fuzzy3d

    Joined:
    Jun 17, 2009
    Posts:
    219
    I think yes

    [MenuItem("moje/add Collider LOD0")]
    static void VypniStiny()
    {
    foreach (var model in Selection.gameObjects)
    {
    foreach (var r in model.GetComponentsInChildren<MeshRenderer>())
    {
    SerializedObject so = new SerializedObject(r);
    //
    r.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.TwoSided;
    r.staticShadowCaster = true;
    //
    GameObjectUtility.SetStaticEditorFlags(r.gameObject, StaticEditorFlags.ContributeGI);
    //
    so.FindProperty("m_ScaleInLightmap").floatValue = 0f;
    //
    so.FindProperty("m_StitchLightmapSeams").boolValue = false;
    //
    SerializedProperty LPProp = so.FindProperty("m_ReceiveGI");
    LPProp.intValue = 2;
    //
    r.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.BlendProbes;
    //
    if (r.gameObject.name.Contains("_LOD0"))
    {
    if(r.gameObject.GetComponent<BoxCollider>() == null)
    {
    BoxCollider _bc = (BoxCollider)r.gameObject.AddComponent(typeof(BoxCollider));
    }
    }
    //
    so.ApplyModifiedProperties();
    }
    }
    }


    It is possible that part of my problems was and still is caused by the Inspector not updating...
     
  11. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,194
    so.ApplyModifiedProperties only saves the things you changed through the serializedObject interface. So when you do eg.
    r.shadowCastingMode = blah
    , that's not getting saved to file by so.ApplyModifiedProperties.

    You should do all the changes through
    so.GetProperty("foo").xValue = bar;
    , as that gives automatic saving to file and undo support. If you for some reason need to use the object directly, you'll want to do that in it's own chunk:

    Code (csharp):
    1. r.foo = bar;
    2. r.xxx = yyy;
    3. EditorUtility.SetDirty(r);
    4.  
    5. var so = new SerializedObject(r);
    6. so.GetProperty("hello").xValue = x;
    7. so.GetProperty("sailor").xValue = y;
    8. so.ApplyModifiedProperties();

    The reason for this is pretty straight forward; the SerializedObject is a copy of the (serializable) data in the object, with a link back to the object. Calling ApplyModifiedProperties does three things:
    - Mark the object as dirty
    - Inserts an undo operation in the undo stack
    - writes all the changed data from the SerializedObject back to the main object

    This mean that the other changes that you did won't necessarily be persisted when you do things in this way.
     
    fuzzy3d and SF_FrankvHoof like this.
  12. fuzzy3d

    fuzzy3d

    Joined:
    Jun 17, 2009
    Posts:
    219
    Thank you, sir!