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

2D light - edit shape from script

Discussion in '2D' started by amitm, Jan 5, 2020.

  1. amitm

    amitm

    Joined:
    Jul 16, 2014
    Posts:
    2
    Hi!

    I'm trying to edit the shape of a Freeform Light 2D component from a script but I can't find the proper variable. Do you guys know how I can do that? or even better, how I can create 2d light from a line render?

    Thanks!
     
    Avalin likes this.
  2. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,256
    Here you go.

    Code (CSharp):
    1. public UnityEngine.Experimental.Rendering.Universal.Light2D shapeLight;
    Then you can feed it an array of Vector3's

    Code (CSharp):
    1. light.shapePath = arrayOfVector3s;
    You could make a script that gets all the points of a line renderer, put that into an array and bob's your uncle.
     
  3. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,802
    Gibbonfiend and electric_jesus like this.
  4. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,256
    Just checked in a project I had, damn. Well forget my answer.
     
  5. MrErdalUral

    MrErdalUral

    Joined:
    Mar 17, 2017
    Posts:
    1
    I checked and couldn't find a way either!
    I was trying to add dynamic shadows using raycasts around the player game object and set the shape to the hit positions.

    At least make the field protected in future updates please!

    For now I generate a mesh using the hit positions that masks a "darkness object" to get a similar effect.
     
  6. DuckGonzales

    DuckGonzales

    Joined:
    Mar 30, 2020
    Posts:
    1
    How did you use a 2d mask with a mesh?
     
  7. TheKraken64

    TheKraken64

    Joined:
    Jun 30, 2015
    Posts:
    2
    I found a (hacky) solution to this problem using reflection. Honestly it's a bit surprising that this works. But for my own purposes, it doesn't seem to break anything:

    Code (CSharp):
    1. using System.Reflection;
    2. using UnityEngine.Experimental.Rendering.Universal;
    3.  
    4. ...
    5.  
    6. void SetFieldValue<T>(object obj, string name, T val) {
    7.     var field = obj.GetType().GetField(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    8.     field?.SetValue(obj, val);
    9. }
    10.  
    11. void SetShapePath(Light2D light, Vector3[] path) {
    12.     SetFieldValue<Vector3[]>(light, "m_ShapePath",  path);
    13. }
    14.  
    I'm using Universal RP version 7.2.1.
     
  8. JankyOldDog

    JankyOldDog

    Joined:
    Dec 14, 2017
    Posts:
    3
    I got around this by creating a Light2D prefab with the number of points I needed in the shapePath. When I instantiate the prefab into the scene, the light's shapePath array is initialized with the correct number of elements. Each element of the array can then be set to whatever Vector3 position you need. The drawback is that you will create a prefab for each shapePath array size that you need.
     
    Gibbonfiend likes this.
  9. SERG__ZV

    SERG__ZV

    Joined:
    May 19, 2016
    Posts:
    8
    The answer is late, but suddenly whoever needs it. If you need to edit this in a prefab without a script. You need to enable draw gizmos on the scene. Then there will appear lines and nodes for which you can drag.
     
  10. dots_me

    dots_me

    Joined:
    Jun 7, 2021
    Posts:
    3
    For some reason this doesn't seem to work more than once, I put it into the Update method and it only updates on start. It does work once though. Do you have an idea why this might be and how I could make it work as intended? (updating every frame as everything does in the Update method)
     
  11. myazuid

    myazuid

    Joined:
    Jan 29, 2019
    Posts:
    26
    Hi, an old thread I know!

    I copied your approach here some while back but never solved an issue that came up which is that the light doesn't update on screen until you click edit shape in the inspector and click one of the points in the shape. Did you hit this issue and if so, did you come up with a solution by any chance? Thanks!
     
  12. WightKnight1

    WightKnight1

    Joined:
    Feb 25, 2017
    Posts:
    1
    Figured out a solution for this that works for me. If you get to the state above where you're able to set the shape of a light, but only on creation and not every frame you can force the light to recalculate the mesh by calling
    Code (CSharp):
    1. light.BroadcastMessage("UpdateMesh");
    on your light object. Didn't realize you could invoke private functions by broadcasting a message, but I guess you can.

    I assume there's a reason why this isn't in the public API and is likely inefficient, but... :cool:
     
  13. Buildasaurus

    Buildasaurus

    Joined:
    May 9, 2023
    Posts:
    1
    While it is true that shapePath is read-only as LiterallyJeff pointed out, that isn't a huge problem, because you can use SetShapePath with the array points.
    Code (CSharp):
    1. light.SetShapePath(new Vector3[] {});
    So if you want to edit the freeform shape from code, this should do the job (did it for me at least).
     
    diesoftgames likes this.
  14. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,256
    That method did not exist at the time of the original post. It didn't exist until Unity 2021.3 or URP 12.1.