I’m using the sample First Person Controller prefab in a simple scene along w/ a single directional light that has shadows turned on. For whatever reason, as I move the player around using W,A,S,D, the shadow appears to move as well.
Its in the prefab, and its not under any of the prefab objects in the hiearchy view. This should mean its not a child of anything correct? I tried parenting the directional light w/ another scene model but the shadows still moves w/ the player.
I tried placing a spot light w/ shadows on and that seams to work fine.
The CharacterShadow script doesn’t move with the player since it’s logic only uses point lights and therefor their positions. You just have to move the light with you’r player on use a different ortographic view.
The side effect is that you’ll get much sharper/detailed shadows with the same texture size.
not sure if you read my question or if I’m misinterpreting your suggestion, but I want nice static shadows as if from a sun (yes, dynamic, not baked) however when I move w/ the FPS prefab the shadows move as well.
Look at my changes in CharacterShadow the changes work fine in my project. The script examines the light type and changes it’s behaviour. When using a dirctinal light the projector (not the light) gets moved with the player.
using UnityEngine;
public class CharacterShadow : MonoBehaviour
{
public GameObject target;
public float castingDistance = 10.0f;
public float lightness = 0.6f;
public int textureSize = 512;
public Texture fadeoutTexture;
public bool blur = false;
public int blurIterations = 1;
public LayerMask ignoreLayer; // don't cast shadow on this layers
public LayerMask targetLayer; // all objects within this layer are used to cast shadows
public float directionalOffset = 1.0f;
private RenderTexture shadowmap;
private GameObject child;
private Projector proj;
private Camera cam;
private int savedPixelLightCount;
private static string shadowMatString =
@"Shader ""Hidden/ShadowMat"" {
Properties {
_Color (""Color"", Color) = (0,0,0,0)
}
SubShader {
Pass {
ZTest Greater Cull Off ZWrite Off
Color [_Color]
SetTexture [_Dummy] { combine primary }
}
}
Fallback off
}";
static Material m_ShadowMaterial = null;
protected static Material shadowMaterial {
get {
if (m_ShadowMaterial == null)
m_ShadowMaterial = new Material (shadowMatString);
return m_ShadowMaterial;
}
}
private static string projectorMatString =
@" Shader ""Hidden/ShadowProjectorMultiply"" {
Properties {
_ShadowTex (""Cookie"", 2D) = ""white"" { TexGen ObjectLinear }
_FalloffTex (""FallOff"", 2D) = ""white"" { TexGen ObjectLinear }
}
Subshader {
Pass {
ZWrite off
Offset -1, -1
Fog { Color (1, 1, 1) }
AlphaTest Greater 0
ColorMask RGB
Blend DstColor Zero
SetTexture [_ShadowTex] {
combine texture, ONE - texture
Matrix [_Projector]
}
SetTexture [_FalloffTex] {
constantColor (1,1,1,0)
combine previous lerp (texture) constant
Matrix [_ProjectorClip]
}
}
}
}";
private Material projectorMaterial = new Material (projectorMatString);
void Start()
{
if( !target )
{
Debug.Log("No target assigned! Disabling CharacterShadow script");
enabled = false;
return;
}
if( ignoreLayer == 0 ) {
Debug.Log("Warning: target layer should use a separate layer (!=default)");
// still continue...
}
// create a child camera/projector object
child = new GameObject("ChildCamProjector");
cam = (Camera)child.AddComponent("Camera");
proj = (Projector)child.AddComponent("Projector");
child.AddComponent("CharacterShadowHelper");
if (blur) {
child.AddComponent("BlurEffect");
// adjust iterations as needed or better expose a property
((BlurEffect)child.GetComponent(typeof(BlurEffect))).iterations = blurIterations;
}
cam.clearFlags = CameraClearFlags.Color;
cam.backgroundColor = Color.white;
cam.cullingMask = targetLayer;
cam.isOrthoGraphic = true;
proj.isOrthoGraphic = true;
proj.orthoGraphicSize=1.0F;
proj.ignoreLayers = ignoreLayer;
proj.material = projectorMaterial;
proj.material.SetTexture("_FalloffTex", fadeoutTexture);
child.transform.parent = transform;
if (light.type!=LightType.Directional) {
child.transform.localPosition = Vector3.zero;
child.transform.localRotation = Quaternion.identity;
}
else {
proj.transform.rotation = transform.rotation;
}
}
void Update()
{
if (!shadowmap) {
shadowmap = new RenderTexture( textureSize, textureSize, 16 );
shadowmap.isPowerOfTwo = true;
shadowmap.wrapMode = TextureWrapMode.Clamp;
cam.targetTexture = shadowmap;
proj.material.SetTexture("_ShadowTex", shadowmap);
}
OrientToEncloseTarget();
}
void OnEnable()
{
if (proj)
proj.enabled = true;
}
void OnDisable()
{
if (proj)
proj.enabled = false;
}
public void OnPreRender()
{
savedPixelLightCount = Light.pixelLightCount;
}
public void OnPostRender()
{
shadowMaterial.color = new Color(lightness,lightness,lightness,lightness);
GL.PushMatrix();
GL.LoadOrtho();
// LoadOrtho loads -1..100 depth range in Unity's
// conventions. We invert it for OpenGL
// and pu the depth at the very far end.
const float depth = -99.99f;
for (int i = 0; i < shadowMaterial.passCount; i++)
{
shadowMaterial.SetPass (i);
GL.Begin (GL.QUADS);
GL.TexCoord2(0,0); GL.Vertex3( 0, 0, depth );
GL.TexCoord2(1,0); GL.Vertex3( 1, 0, depth );
GL.TexCoord2(1,1); GL.Vertex3( 1, 1, depth );
GL.TexCoord2(0,1); GL.Vertex3( 0, 1, depth );
GL.End();
}
GL.PopMatrix ();
Light.pixelLightCount = savedPixelLightCount;
}
private void OrientToEncloseTarget()
{
Vector3 center = target.transform.position;
// REMARK: radius fails if the mesh data is not found in the target (e.g. mesh is found in childs only)
float radius = 5.0f;
if( target.renderer ) {
Bounds b = target.renderer.bounds;
center = b.center;
radius = b.extents.magnitude;
}
if (blur)
radius *= 1.1f;
else
radius *= 1.05f;
if (light.type!=LightType.Directional) {
float distance = (center - transform.position).magnitude;
child.transform.LookAt( center );
cam.orthographicSize = radius;
cam.nearClipPlane = distance - radius;
cam.farClipPlane = distance + radius;
proj.orthoGraphicSize = radius;
proj.nearClipPlane = distance;
proj.farClipPlane = distance + castingDistance;
proj.material.SetTexture("_ShadowTex", shadowmap);
}
else { // directional
radius = 1.2F;
// der Projektor wird einfach mit dem target-Objekt mitgeführt
child.transform.position = target.transform.position;
child.transform.Translate(-transform.forward*directionalOffset);
cam.orthographicSize = radius;
cam.nearClipPlane = 0.01F;
cam.farClipPlane = castingDistance;
proj.orthoGraphicSize = radius;
proj.nearClipPlane = directionalOffset-0.2F; // capsule radius*2
proj.farClipPlane = castingDistance;
proj.material.SetTexture("_ShadowTex", shadowmap);
}
}
}
hahaha, alright, this ‘misunderstanding’ was my fault.
I should have been very specific :-).
I’m using the First Person Controller prefab for basic player movement. As well, I am using a single light source (a directional light) to simulate the sun. In my scene is a basic ground mesh and some props. Now, in editor, the directional light is casting shadows from these props onto my ground mesh and it looks great.
However, as soon as I press play or build the project and test it, as I move my player, all the shadows in the scene move - 3d objects shadows, not just the players shadows.
Does that make better sense? I’m trying to figure out why static objects shadows are moving when the player moves.
Sorry for the confusion and the great help so far!
Do they actually move across the ground like the object were moving or do they crawl/sparkle because of aliasing? I’ve seen that, you need to mess with the cascade settings and draw distance if that is the case to tune the shadows for the scene.
So it “moves” in a sense “the shadow just ran 10 meters!”, or “moves” in a sense “it stays in the same place, but there’s some crawling and shimmering”?
In the latter case, tweak shadow quality settings to get the resolution right for your scene size. Documentation here.
Sorry for the slow reply - they move as in, whoa, they just moved 10 meters. It doesn’t appear to be a graphical / shadow quality issues, as the shadows look great, but they move.
That is strange. Do a small project that reproduces the issue, and send it with Report Bug.app (found next to Unity application, or from Help menu in Unity).
This is going to sound simple, but… does the light source move? Rigidbody accidentally attached or a script you were playing around with once and forgot about? Or is it in the hierarchy of another object that moves somehow?
Probably not… but… it seems like the most likely possibility from what little I know here.
I guess it could be that your entire terrain is moving or something like that, too. I remember dealing with some physics tests and I was tilting my entire “floor” around just by moving a player across it. Might be subtle enough to not see the movement, and the shadows would be the most obvious place it’s noticed… especially if the camera follows the player.
And now, I will stop suggesting stuff that you probably already checked.
I ended up tweaking my camera clip plane settings to solve this. I was having all kinds of issues - skybox not showing, hall of mirrors effects, graphical oddities and moving shadows.
Thanks for everyone’s feedback. I guess the scale I’m using is smaller than intended as I’ve had to tweak a lot of defaults to get things looking right.
gosh… this post is so old… but it seems to be the only one explaining the exact issue i am facing…
all the worlds shadows are moving with the player/camera…
I tried playing with the cameras. turning all off but one, giving it full clipping range…
I tried turning all the lights off but one, played with its settings…
I checked that the light, nor my buildings/land/world are moving…
still having shadows moving all over the place…
since noone else is reporting this issue… i wonder what i am doing wrong…