- Home /
Blob shadow going through multiple objects.
Since i am using Basic Unity, I'm limited to use the Blob Shadow Projector. It has worked fine for me until now, because of the following:
In one of the scenes, i have a few platforms, which are a few units above other objects, including a Terrain.
My problem is, the projector casts the blob shadow on any surfaces within the range of the projector. I tried to use a Spotlight instead, but unsuccessfully, because black is 100% transparent.
How do i prevent the blob shadow from being projected on multiple surfaces without sacrificing projection on slopes?
The blob shadow was placed as a component on a Ball-shaped player. Edit: Here's a screenshot:
If you're not too picky about a few dollars, there's the additional option of: http://u3d.as/content/gustav-olsson/shadow-volumes-toolkit/2gF.
Answer by dai1741 · Sep 29, 2011 at 07:13 AM
I think there is no way to cast shadow only on the first hit object for free.
You can simulate it by changing the projector's range dynamically, however, this can cause awkward effects in many cases.
If that's ok for you, write a script like below and attach it to the parent GameObject of Blob Shadow Projector.
ShadowClipper.js
var shadowProjector : Projector; // the shadow projector
var shadowDistanceTolerance : float = 0.5; // positive number used to cast shadow on terrains correctly
private var origNearClipPlane : float;
private var origFarClipPlane : float;
function Start() {
if(!shadowProjector) shadowProjector = transform.GetComponentInChildren.<Projector>();
origNearClipPlane = shadowProjector.nearClipPlane;
origFarClipPlane = shadowProjector.farClipPlane;
}
function Update() {
var ray = new Ray(shadowProjector.transform.position
+ shadowProjector.transform.forward.normalized * origNearClipPlane,
shadowProjector.transform.forward);
var hit : RaycastHit;
if (Physics.Raycast (ray, hit, origFarClipPlane - origNearClipPlane,
~shadowProjector.ignoreLayers)) {
var dist = hit.distance + origNearClipPlane;
shadowProjector.nearClipPlane = Mathf.Max(dist - shadowDistanceTolerance, 0);
shadowProjector.farClipPlane = dist + shadowDistanceTolerance;
//Debug.Log("Ray hit at: " + hit.point + ", distance: " + dist);
}
}
hey this is great code, i modified it a little and post for the heck of it
Answer by lunisolar · Aug 31, 2011 at 03:06 PM
I haven't been able to try unity in depth yet, but I know photoshop. not sure if this will work, but if you were doing something like that in PS you would create 2 copies of the shadow and cut away the part you dont want showing through the platform.
Answer by Nerull22 · Aug 31, 2011 at 01:42 AM
All right, not sure how much of an answer this is, as I'm not 100% for what you're using. But if you're using a light, I would look into culling masks. You should be able to select what type of object it will project onto. Hope this helps.
Tried that, but it doesn't works in my case. The platforms and the terrain are in the same layer since i need the shadow on both of them. What i really want is the blob shadow showing on platforms, without also going through them.
Answer by luniac · Jun 25, 2012 at 03:57 AM
#pragma strict
var shadowProjector : Projector; // the shadow projector
var shadowDistanceTolerance : float = 0.5; // positive number used to cast shadow on terrains correctly
private var hit : RaycastHit;
private var dist : float;
private var origNearClipPlane : float;
private var origFarClipPlane : float;
private var ray : Ray;
function Start() {
if(!shadowProjector) shadowProjector = transform.GetComponentInChildren.<Projector>();
origNearClipPlane = shadowProjector.nearClipPlane;
origFarClipPlane = shadowProjector.farClipPlane;
}
function Update() {
ray = new Ray(shadowProjector.transform.position
+ shadowProjector.transform.forward.normalized * origNearClipPlane,
shadowProjector.transform.forward);
if (Physics.Raycast (ray, hit, origFarClipPlane - origNearClipPlane, ~shadowProjector.ignoreLayers))
{
dist = hit.distance + origNearClipPlane;
Debug.Log(dist);
//shadowProjector.nearClipPlane = Mathf.Max(dist - shadowDistanceTolerance, 12);
//dist = 12 for large ball
if(dist >= 12)
shadowProjector.nearClipPlane = 15;//value higher than 12
else
shadowProjector.nearClipPlane = origNearClipPlane;
shadowProjector.farClipPlane = dist + shadowDistanceTolerance;
//Debug.Log("Ray hit at: " + hit.point + ", distance: " + dist);
}
}
includes some values specific to my game, but basically the shadow fades in once again ins$$anonymous$$d of being at almost constant strength all the time. Only problem is if you have lots of edges over each other then the shadow will be projected on all of em.. albeit at different strength based on distance, so it sorta is realistic.. as far as blob shadows go...
just use dist >= "your farthest distance value where object is touching surface point blank"
actually with more testing i see that theres an instant if object is in air above surface where shadow disappears... perhaps theres way to fix that but im tired of blob shadows ....
Answer by Xorse · Oct 30, 2012 at 06:50 PM
Hi I'm new to Unity but have had similar problems, take a look at this: http://answers.unity3d.com/questions/8753/how-to-prevent-blob-shadow-to-cast-on-my-player.html This may help if you can dynamically change which layers it should ignore. Let me know if this works as this may be useful when I get further with my Unity project. Thanks
Maybe if you can use a ray cast to find the object directly beneath you and enable this in the layer while disabling the last object the ray cast found?
Found this as well: http://answers.unity3d.com/questions/168084/change-layer-of-child.html Hope this helps!
Your answer
Follow this Question
Related Questions
Blob shadow changes transparency 2 Answers
Do blob shadow projectors work on iPhone? 1 Answer
[Unity3D 3.5.6f4] Get rid of shadow projector artefact 1 Answer
Projector (Blob Shadow) does not work properly 1 Answer
Blob shadow problem 2 Answers