- Home /
How to detect if an object is under a shadow casted by a directional light
I'm assuming we can't treat a directional light as any other form of light, that is as a single point, but as a plane with the same orientation as the directional light. so instead of casting a ray from my object towards the center of the DirectionalLight, I'm casting it from myobject.transform.position
to myObject.transform.position - directection of DirectionalLight
so that I'm casting lines parallel to the light as in the picture
and if the ray hits a wall on it's way then set a bool value underSun= true
else underSun=false
and to increase the accuracy of the detection, instead of casting a single ray from the center of the object ,I'm casting four each from the it's top corners and on everyUpdate if a rayCast from any of these corners doesn't hit a wall then break and set underSun= true
this does make sense to me, but I'm getting some weird unwanted results with my code and I would appreciate if anyone can point me to the right direction. see in gif below
the code is here
using UnityEngine;
using System.Collections;
public class NewPlayer : MonoBehaviour {
public NewSun sun;
private MeshRenderer mesh;
private RaycastHit hit;
private bool underSun = false;
// Use this for initialization
void Start () {
mesh = GetComponent<MeshRenderer>();
}
// Update is called once per frame
void Update () {
underSun = false;
Vector3 sunDir = sun.transform.forward;
sunDir.Normalize();
sunDir *= 100;
foreach (Transform child in transform) {
if (!Physics.Raycast(child.position, child.position - sunDir, 30, LayerMask.GetMask("Wall")))
{
Debug.DrawLine(child.position, child.position - sunDir, Color.red);
underSun = true;
}
else {
Debug.DrawLine(child.position, child.position - sunDir, Color.green);
}
}
if (underSun)
{
mesh.material.color = Color.red;
}
else {
mesh.material.color = Color.green;
}
}
}
That's your actual, complete code? Where is "sunDirection" defined?
sunDirection =sunDir now , it's basically the transform.forward vector of the directional light which is assigned publicly
What you had written before generated a compile error - if you're asking for help with code, you really need to write exactly the code you were using :)
So your logic seems sound but your colour coding is a little tricky to follow: a green debug line of the raycast indicates that no collider has been hit, whereas a green coloured cube means that at least one collider has been hit, right? And your "bad behaviour" video seems to indicate that all four raycasts are hitting something.
$$anonymous$$ay I suggest you change your logic to use Debug.DrawLines to show all the raycasts, then colour them red if they hit something and green if they don't? You'll find it much easier to visualise. You can then use one of the other overloads of Physics.Raycast() that outputs a hitinfo of the collider that was hit and print its name, and the position at which it was hit.
Shouldn't the second parameter to RayCast just be the direction ie -1f * sunDir
?
I think that would converge the rays towards a point ins$$anonymous$$d of casting parallel rays
No, that would be true if the second parameter were an end point for the ray, and the OP is using it as if that's the case. It's not, it's a direction. So it needs to be the same for all the casts in order for them to parallel.
Answer by tanoshimi · Sep 23, 2016 at 09:55 AM
Having read @Bonfire-Boy's comment above, I think I've spotted your problem. I'm not sure your Debug.DrawLines are actually visualising your Raycasts correctly. Take a careful look at the function signatures:
In Physics.RayCast(), the first two Vector3 parameters are an origin and a direction.
In Debug.DrawLine, the first two Vector3 parameters are an origin and an end position.
So, for Debug.DrawLine you're correct to use child.position - sunDir
but, for RayCast, you should be using -1f * sunDir
as he suggests.
That's what the problem was, it works at last ,thanks a lot guys :)