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!
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!
Here you go.
public UnityEngine.Experimental.Rendering.Universal.Light2D shapeLight;
Then you can feed it an array of Vector3’s
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.
Not sure if those docs are out of date but it looks like “shapePath” is read-only:
public Vector3[ ] shapePath { get; }
Just checked in a project I had, damn. Well forget my answer.
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.
craftymelodicdutchshepherddog
How did you use a 2d mask with a mesh?
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:
using System.Reflection;
using UnityEngine.Experimental.Rendering.Universal;
...
void SetFieldValue<T>(object obj, string name, T val) {
var field = obj.GetType().GetField(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
field?.SetValue(obj, val);
}
void SetShapePath(Light2D light, Vector3[] path) {
SetFieldValue<Vector3[]>(light, "m_ShapePath", path);
}
I’m using Universal RP version 7.2.1.
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.
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.
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)
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!
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 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… ![]()
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.
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).
That method did not exist at the time of the original post. It didn’t exist until Unity 2021.3 or URP 12.1.