How do i make a Light Detection System?

So im trying to make stealth game right? decided to have a mechanic where the more in the darkness you are, the harder it is for you to be detected, somewhat like the old thief games. i want to have a “darkness” value that is used to change all sorts of things that make it harder the the player to be detected. those changes dont REALLY need specifying as i know exactly what i want to do with those and how to do it.

the issue i have is that i dont exactly know how to code the method in which i get my “darkness” value. my plan is to have a second camera on the player that watches a sphere also mounted on the player. this sphere’s job is to soak up all the light in the level so we can have a temporary texture that captures what lighting the player is in from the second camera (render texture) that we then access from the GPU as an array and approximate the “darkness” of that image from the colours using a formula from here: image - Formula to determine perceived brightness of RGB color - Stack Overflow

it seems in order to access this render texture of the sphere that is used to get a read on the lighting of the character, i probably need to use AsyncGPUReadback.Request but to be completely honest with anyone reading, i have no idea how this is meant to be used. ive read the unity documentation for it and cant really make sense of what it needs inputted to function or how to to use it.

ALSO for anyone wondering why i dont just use a Raycast from the lights or something simplier like that, i kind of want something more dynamic that doesnt just factor the distance from the light but also the colour and such. i also think using rays would get a bit more tricky when dealing with things such as transparent surfaces that only let in a certain amount of light like dark tinted glass.

There are some major pitfalls with such an approach:

  • It sounds like it would probably be really difficult to design levels around this mechanic. There would be so many different inputs contributing towards the final visibility of the player, that you might have to do things like tweak the reflectiveness of some wall materials and such to get the level design to work like you want.
  • It sounds like tweaking the game’s render pipeline, the PC’s textures, the skybox and such could very easily lead to your levels breaking and having to be redesigned.
  • It sounds game mechanics could even be affected by the players’ display settings unless you’re careful to avoid that.
  • It sounds like the end result could be difficult to read by the player. The visibility meter could be quite unstable and keep unexpectedly jumping between “camouflaged” and “visible” in the middle of shadowy corridor, just because some rays of light coming from far away end up sometimes bouncing into your pixels a bit more.

I think it would very likely lead to better end-user experience if you decouple the level design from the rendering layer, and give yourself more discrete and easy-to-read tools, like light sources with clear radiuses, that make it easier to design fun levels that aren’t so fragile. You can still have the system take into consideration things like the colors of light sources, without reading rendered pixels.

2 Likes

To add to the above, you pretty much never should or want to derive your data from your visuals. This is especially true when using this data to drive gameplay. Instead, your data should drive your visuals and your gameplay.

2 Likes

this is really sound advice! ill rethink my approach to be something seperate from visuals. its probably raycasts and checkspheres from here on. any other useful unity classes i should be aware about when revising my approach on this?

1 Like

I’m currently doing a stealth game and I’m using the radius, dot product (if spotlight) and a raycast to test if my player is in light. The texture method you’ve suggested could also work and be more precise but will probably be more costly. You could place a real time reflection probe on the player and access the rendered texture from script.

Another approach could be to user trigger colliders on the light sources to have them register themselves with the visibility system when the player is within radius.

1 Like

You can query the light probes at runtime

1 Like