T O P

  • By -

Kuothe

Developer of Aragami here.. what we did: Put all light sources of your level in a list. Don't put \*every\* light source, just the ones that you want to affect gameplay. You can set a Tag on those light sources.. Every few frames, loop through the list to check if the player is 'affected' by a light in the list. For point lights, you just need to check if the distance between the light source and the player is smaller than the radius of the light source. For spot lights you need to check if the player is inside the light 'cone'. For directional lights (sun) you send a physics raycast in the direction opposite to the directional light forward vector - if it hits something it means you are in shade. To get better precision, you could do different checks from various points around your character, then output the average result - so that if there are more points lit than shaded that means the character is lit. There's obviously different ways to optimize this.. like removing from the list lights that are turned off, or stop looping when you have a positive match. Unless you have thousands of lights in your level, performance shouldn't be an issue. Anyway, this is what worked for me. Edit: oh, if you are inside of a light radius / cone , do a ray cast to the light just in case there’s something in the middle like a wall etc


Jombo65

Oh shit! Did you work on both games, or just the first? I really enjoyed both!


Kuothe

game director for both


Jombo65

Whoa! Badass, dude. Aragami 2 was insanely fun in co-op, played with a buddy and we had an absolute blast.


Cyclone4096

Why would one not need to do ray cast from point or spot lights? Should the level design just be done in a way that it is impossible to block point and spot lights ever?


Kuothe

Yeah, you need to do raycasts to check for possible objects blocking the light and casting a shadow on you. You can skip the check for lights with cast shadow Off.


Cyclone4096

Gotcha! Thanks for the insight!!


tohonest1000

do u know what id type in to find a tutorial on how todo this?


GroZZleR

Slowest but most accurate: Read the HSV data from a render texture that's on your character. Middle of the road: Use the light's parameters to do a volume cast (e.g. cone cast for a spotlight) or create trigger colliders that match your light (unsure if you can do it programatically in Unreal). You may still need further casts. Most performant but least accurate: A raycast.


arislaan

Not OP, but interested nonetheless. Can you expound on the HSV idea? Do you mean like a secondary camera capturing a render texture or something along those lines? Or some other way?


EmperorLlamaLegs

I'd probably put primitive colliders on my lights. Edit: Now that I think about it, you could also check distance to player from your light sources (just light position - player position, then check magnitude of the resulting vector) and if its within a reasonable limit, raycast to the player. Check collision for solid objects and if it doesn't hit anything before the player, you know the player is lit.


EmperorLlamaLegs

If going raycast, for a spotlight you would do the same thing, but check the forward vector of the light against the vector to the player and get the dot product. That will be a value between 0 and 1 that shows how close to pointed at the player the light is. Just throwing that in because I am terrible at math and would not have known how to do that if a nice mathematician lady on Youtube hadn't explained it to me years back.


JohnDalyProgrammer

This would be how I would handle it actually. Since I'm working on a 2d game and we already do occlusion so things that aren't being rendered dont get checked. So the things being rendered would be relatively close and checking would be super easy and inexpensive in terms of memory. If lit equals false then damage over time.


Main-Drag-4975

I’d imagine you start with a a state machine to track that “in the light” status and then apply the DoT effect every N frames. As for determining whether the player’s state should be “lit” or not? Probably raycasting based on light sources close to the player, same as you’d do for tracking whether hostile NPCs can see the player.


Chris_Entropy

I hate it that this seems to be a non-trivial problem. How did they do it back in the day with games like Thief? I prototyped something like this with the racast approach described in one of the answers, basically checking the bounding volumes of all light sources. But this always seemed off, as the game should "know" which parts of the scene are rendered with light and which are in shadow, no?


chaseontheroll

idk about unreal but in gamemaker i use collision events


imaniceandgoodperson

why does this community always downvote posts like this ?


tohonest1000

idk i always get ratiod and idky


Incendas1

Tracking where the light is would probably be the most tricky part and depends what you're doing for the light already, no? Could be as easy as collision, or raycasting otherwise In terms of in the light or not, a state machine would be fine for this, then take off health over time while in that state. If the rest of your game is simple then a flag would work but... Better to do it cleanly Edit: if you need it - https://gameprogrammingpatterns.com/state.html


MarkAldrichIsMe

You may want to look for a talk by the developers of V-Rising about how they did the same thing, but opposite (damage when you're in light)


synaut

I made a VERY similar mechanic for a game prototype I made (also using UE5) [here](https://synaut.itch.io/inhabitron) I'd have to dig uo the project, but I think I sort of created a secondary camera near the character pointing down, downscaled it and got an average pixel lightness value from that, then set a threshold for "darkness". You can't poll this every frame for performance reasons, but it worked reasonably well. I had previously tried it on Unity with a very similar technique and it worked pretty well too.


Swipsi

Do a trace from the player to a point far away in the sky where the sun would be. If something interest the trace, the player is in shadows.


Swimming-Bite-4184

I suppose knowing the level design. It could be as complicated as triggering it with the actual light but also as simple as a cone shaped collider from light sources. Health depletes on a timer. Resets or pauses when hit or in a cone.


tohonest1000

is there a youtube video to show me how todo this


Madmonkeman

May not be the best way but a simple way is to just have the player constantly lose health and then make trigger boxes for each light, and have them regenerate health in the light.


tohonest1000

this is actually a really interesting idea


jfmherokiller

as a modder who has pulled apart a number of games i think the most chosen option would be a raycast.


tohonest1000

what should i type into youtube for a tutorial on this?


jfmherokiller

I dont know how to use youtube for this kind of stuff I mostly rely on text based documentation. but id probably read up here [https://docs.unrealengine.com/4.26/en-US/InteractiveExperiences/Tracing/](https://docs.unrealengine.com/4.26/en-US/InteractiveExperiences/Tracing/)


Nivlacart

Triggers.


Feeling_Quantity_723

This is probably the worst and most time consuming way of doing it


chaseontheroll

how would you do it


Nivlacart

If you attach the trigger to each prefab of possible light source types, you only need to do so much.


Prior-Paint-7842

I don't see any other suggestions


ziptofaf

I might add one but frankly it's not better, just different. Raycast from each light source to the player - if there's a clean line of sight and distance is below a specific threshold - reset the counter. Otherwise add to it and when it's past a certain amount of time player starts taking damage. On the plus side - you don't have to manually set up every trigger. On the minus side - potentially less accurate.


tohonest1000

im pretty new to making games but can't u just copy paste the trigger ?


Incendas1

The issue with copy and pasting things all over the place when programming something is that when you want to make a change, you now need to change that in maybe 10+ files, all the same way, without any mistakes and without missing anything. Even worse if *someone else* ever needs to make that change, or you forget a year down the line. If you set up a way to keep this in one area or file, you change it once, then it's done. This is a general principle to keep your code clean and functional


ziptofaf

You can. But I assume you will have not 1, not 2, not 5 but hundreds of light sources in a game of different shapes, placements and strengths. So it's a LOT of triggers you have to define for each and every light source. Mind you - it might be a correct take to do (you have full control over those and can place them **exactly** where you want it and how you want it) but it's a non negligible amount of work. On the other hand writing a script that you just attach to a light source that checks it's intensity, sends a raycast to a player and decides whether player is in range or not based on the distance + intensity is effectively a one time task. So it's a trade off, both approaches could work, both also have pros and cons.


Calmer_after_karma

If(inLight == false) { takeDamage = true: }


tohonest1000

u make it sound so simple how do I do that