@@ -344,6 +344,10 @@ public static void RenderMeshSettings(bool forceLodToZero,int layer,int skinnedM
344344 {
345345 return ;
346346 }
347+ if ( FindHeadAndCreateShadowHead )
348+ {
349+ RemoveOldShadowClones ( ) ;
350+ }
347351
348352 for ( int index = 0 ; index < skinnedMeshRendererLength ; index ++ )
349353 {
@@ -373,40 +377,67 @@ public static void RenderMeshSettings(bool forceLodToZero,int layer,int skinnedM
373377 }
374378 }
375379 }
376-
380+ public static List < SkinnedMeshRenderer > LocalShadowClones = new List < SkinnedMeshRenderer > ( ) ;
381+ private static void RemoveOldShadowClones ( )
382+ {
383+ int count = LocalShadowClones . Count ;
384+ for ( int Index = 0 ; Index < count ; Index ++ )
385+ {
386+ SkinnedMeshRenderer Renderer = LocalShadowClones [ Index ] ;
387+ if ( Renderer != null )
388+ {
389+ GameObject . Destroy ( Renderer . gameObject ) ;
390+ }
391+ }
392+ LocalShadowClones . Clear ( ) ;
393+ }
377394 private static void EnsureShadowOnlyClone ( SkinnedMeshRenderer source , int layer )
378395 {
396+ if ( source . enabled && source . gameObject . activeSelf )
397+ {
398+ // Create clone object as sibling (keeps hierarchy simple)
399+ var cloneGO = new GameObject ( source . gameObject . name + "_ShadowOnly" ) ;
400+ var sourcetransform = source . transform ;
401+ var clonetransform = cloneGO . transform ;
402+ clonetransform . SetParent ( sourcetransform . parent , worldPositionStays : false ) ;
403+ sourcetransform . GetPositionAndRotation ( out UnityEngine . Vector3 position , out Quaternion rotation ) ;
404+ clonetransform . SetPositionAndRotation ( position , rotation ) ;
405+ clonetransform . localScale = sourcetransform . localScale ;
406+ cloneGO . layer = layer ;
407+ // Clone SMR setup
408+ var LocalShadowClone = cloneGO . AddComponent < SkinnedMeshRenderer > ( ) ;
409+ LocalShadowClones . Add ( LocalShadowClone ) ;
410+ // The whole point:
411+ LocalShadowClone . shadowCastingMode = ShadowCastingMode . ShadowsOnly ;
412+ LocalShadowClone . receiveShadows = false ;
413+
414+ if ( source . sharedMesh != null )
415+ {
416+ LocalShadowClone . sharedMesh = source . sharedMesh ;
417+ }
418+ if ( source . sharedMaterials != null )
419+ {
420+ LocalShadowClone . sharedMaterials = source . sharedMaterials ;
421+ }
422+ if ( source . bones != null )
423+ {
424+ LocalShadowClone . bones = source . bones ;
425+ }
426+ if ( source . rootBone != null )
427+ {
428+ LocalShadowClone . rootBone = source . rootBone ;
429+ }
430+ // Keep it stable/offscreen-safe if needed (usually not required, but harmless)
431+ LocalShadowClone . updateWhenOffscreen = true ;
379432
433+ // Optional: copy key renderer flags that can affect bounds/skin updates
434+ LocalShadowClone . quality = source . quality ;
435+ LocalShadowClone . skinnedMotionVectors = source . skinnedMotionVectors ;
436+ LocalShadowClone . allowOcclusionWhenDynamic = source . allowOcclusionWhenDynamic ;
380437
381- // Create clone object as sibling (keeps hierarchy simple)
382- var cloneGO = new GameObject ( source . gameObject . name + "_ShadowOnly" ) ;
383- cloneGO . transform . SetParent ( source . transform . parent , worldPositionStays : false ) ;
384- cloneGO . transform . SetPositionAndRotation ( source . transform . position , source . transform . rotation ) ;
385- cloneGO . transform . localScale = source . transform . localScale ;
386- cloneGO . layer = layer ;
387-
388- // Clone SMR setup
389- var shadowSMR = cloneGO . AddComponent < SkinnedMeshRenderer > ( ) ;
390- shadowSMR . sharedMesh = source . sharedMesh ;
391- shadowSMR . sharedMaterials = source . sharedMaterials ;
392-
393- shadowSMR . bones = source . bones ;
394- shadowSMR . rootBone = source . rootBone ;
395-
396- // Keep it stable/offscreen-safe if needed (usually not required, but harmless)
397- shadowSMR . updateWhenOffscreen = true ;
398-
399- // The whole point:
400- shadowSMR . shadowCastingMode = ShadowCastingMode . ShadowsOnly ;
401- shadowSMR . receiveShadows = false ;
402-
403- // Optional: copy key renderer flags that can affect bounds/skin updates
404- shadowSMR . quality = source . quality ;
405- shadowSMR . skinnedMotionVectors = source . skinnedMotionVectors ;
406- shadowSMR . allowOcclusionWhenDynamic = source . allowOcclusionWhenDynamic ;
407-
408- // Optional: bounds (helps if your bounds are tiny and shadows pop)
409- shadowSMR . localBounds = source . localBounds ;
438+ // Optional: bounds (helps if your bounds are tiny and shadows pop)
439+ LocalShadowClone . localBounds = source . localBounds ;
440+ }
410441 }
411442
412443 private static bool TryGetFirstColor ( Material mat , out Color value , out string foundProp )
0 commit comments