Removing Existing Constraint On Unity's Spotlight Component

Hey everyone, is there any way to remove or adjust the existing “Spot Angle” constraint on Unity’s Spotlight component? I need a spot angle of minimum 0.1, but the slider prevents any values lower than 1. This is specific to my project, so no other solutions such as resizing the scene to make the spotlight appear smaller will work.

I’ve tried custom editor scripts, as well as “reflection techniques” suggested by gpt to bypass these constraints, but nothing seems to have any effect. Please let me know if this is at all possible. Thank you!

I guess the custom inspector is here: UnityCsReference/Editor/Mono/Inspector/LightEditor.cs at master · Unity-Technologies/UnityCsReference · GitHub

Copying this into a new editor script and modifying it as needed might be a possibility.

It’s licensed for reference only as mentioned at the top of every entry in that repo.

1 Like

Then “reference” it to write your own custom editor.

1 Like

There might also be a clamper in the engine code. I tried the most naive script (see below) and even when I don’t have the Light selected (which should inhibit editor / inspector window code… I think???), it still appears to be floor()ed to 1.0

Try it yourself.

using UnityEngine;

public class ForceSpot : MonoBehaviour
{
    void Update ()
    {
        Light L = GetComponent<Light>();
        L.spotAngle = 0.1f;

        float x = L.spotAngle;
        Debug.Log( x);
    }
}
2 Likes

Have you tried assigning a cookie to the spot light to mask out the additional area you don’t want included in your cone?

From memory: make a texture - a black square with a white dot in the center (diameter 10% of the image’s width), make your spotlight with a 1 degree spot angle, assign that texture as the “cookie”. There might be settings you need to apply in the texture importer (it might need to clamp rather than repeat, you might want to have it uncompressed).

Otherwise, if this is for a highly specific use case, you could write your own light and shader(s) which use it.

Or, also depending on the use case, can you move the light closer to the object it’s shining on to approximate a narrower cone?

1 Like

Will the light even be visible if you were able to set it lower? I’m currently playing around with a spotlight in URP, and when the inner is set to 0 and the outer to 1 as shown in the image below nothing is visible on the plane it’s shining at.

Edit: I had to turn the intensity up to 1e+08. Is the purpose to create a laser point?

9871476--1422942--upload_2024-6-3_23-54-49.png

Here’s what it looks like when it’s set to a distance of 0.1 from the plane with an intensity of 1,000. I can get it to be bigger by pulling the light source away. So like @angrypenguin suggested this seems to be the approach that will get you the smallest point.

Screenshot - You might have to press your face to the monitor

Example code made while testing - GPT-4o assisted

using UnityEditor;
using UnityEngine;

public class SpotlightController : MonoBehaviour
{
    public Light spotlight;
    public float distanceFromObject = 0.1f;
    public float rotationSpeed = 5f;

    private float mouseX;
    private float mouseY;
    private float xRotation;
    private float yRotation;

    void Update()
    {
        RotateView();
        TryPositionSpotlight();
    }

    void TryPositionSpotlight()
    {
        var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out var hit))
        {
            var spotlightPosition = hit.point + hit.normal * distanceFromObject;
            spotlight.transform.position = spotlightPosition;
            spotlight.transform.rotation = Quaternion.LookRotation(-hit.normal);
        }

        if (Input.GetKey(KeyCode.Escape)) EditorApplication.isPaused = true;
    }

    void RotateView()
    {
        mouseX += Input.GetAxis("Mouse X") * rotationSpeed;
        mouseY -= Input.GetAxis("Mouse Y") * rotationSpeed;

        yRotation = Mathf.Clamp(mouseY, -90f, 90f);

        Camera.main.transform.localRotation = Quaternion.Euler(yRotation, mouseX, 0);
    }
}
1 Like

Great question. I typically make dedicated functionality or effects for “tiny bright things”. If something is bright enough then we can see it even if its size is essentially zero, because light from it still reaches our eyes, but general purpose rendering tends not to deal with that very well.

Examples: stars at night, lights on aircraft, the bright dot made by a laser pointer.

For lasers, my usual starting strategy is to use a raycast to determine what it’s shining on, then draw a textured quad at the desired location. You can then start applying controls from there, e.g. apply a minimum size in screen space.

I still remember the first time I saw an Atari Asteroids machine, tucked in a tiny dark corner in the subterranean shopping mall of the Hyatt Regency in downtown Los Angeles.

I was absolutely mesmerized by the glowy vector graphic dots of the pew-pew-pew! I wish there was a way to get that on a normal raster monitor. I suppose HDR is starting to go in that direction…

This Asteroids game was tucked in a little corner with a Stern Scramble machine, and right outside was a small Carls Jr hotdog cart. Asteroids clearly made an impression on me that I remember the area so well.

And across the way in that same area of the mall was the Radio Shack where I first saw a computer. “Why does that television have a typewriter in front of it?” Hats off to the kid working there who showed me how to make a BASIC program, and I was hooked. :slight_smile:

Obligatory first program:

10 PRINT "KURT"
20 GOTO 10

Almost impossible to code that without reflexively putting a ; at the end of each line.

Okay, thanks for letting me hijack your thread with my memories!!

OP: I hope you find a suitable solution to your narrow-beam spotlight.

1 Like