Download

Detecting partial visibility to light

Have a look at the following situation:
[spoiler]d9YQOZ5.png[/spoiler]
The pill-shaped object on the right is the character controlled by the player. The cone/cylinder object on the left uses a spotlight to create the green light ring. The yellow debug line is being casted from the spotlight source to the middle of the character mesh and is obstructed by the wall in the middle.

As in this approach, I’m checking if the player character collides with the cone of the spotlight first. If this condition is met, I’m casting a ray from the spotlight source to the middle of the player character.

As you can see in the image above, the problem with this is that I can’t detect a character that is only partially (without its middle point) visible, and I haven’t found a good solution to this yet. The only idea that came to my mind was to just do multiple raycasts, but I doubt that’s a good solution as it’s still very inaccurate. What techniques could I use to check if the character is being directly lit by the light source? I’m using the UE4.12, in case there have been some new related features I didn’t notice.

The AffectsPrimitive() lookup is actually just use the AffectsBounds() to figure out whether the spotlight is affecting the target bounds or not, however it only will evaluate a sphere bound (not the actual collision capsules), and the pointlight is just looking for distances. These quick validations are very inaccurate and simply will just fail a lot in your case. I believe you should implement a more robust approach to make sure the light cone is intersect with the actual physical body of the character (evaluate a capsule shape, or do some lookups on the whole PhAT for instance), this should ensure you the partial matches as well. This way the ray testing might not be needed, tho it still can speed up a few lookups. You can also distribute the validations across numerous frames (ticks) that should help you to conserve frame times. In reality a person’s would require some time to actually recognize the target and react to it, so you can experiment within a ~100msec timeframe or so.