Scale the hero cutout with the player's PlayerScaler

The cutout cone's radius and feather are now multiplied by the hero target's
uniform world scale (lossyScale.x, the same body-scale source the orbit input
uses). The authored values are the scale-1 sizes, so the see-through hole and
its soft edge keep the same on-screen proportion for a small hider or a large
hunter, and a mid-match conversion tracks live since lossyScale is read every
frame.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 4.8 committed 2026-06-30 21:32:25 +02:00
1 parent c29cd172bf
commit b22d2ed342
1 file changed
+12 -3
+12 -3
View File
@@ -47,11 +47,15 @@ public class HeroCutout : MonoBehaviour
public bool replaceDeoccluderPullIn = true;
[Header("Cutout cone")]
[Tooltip("Radius of the see-through cone AT THE PLAYER, in metres. The cone tapers to nothing at the " +
[Tooltip("Radius of the see-through cone AT THE PLAYER, in metres, AT PLAYER SCALE 1. The live radius is " +
"multiplied by the hero target's uniform world scale (PlayerScaler) so the hole keeps the same " +
"on-screen size for a small hider or a large hunter. The cone also tapers to nothing at the " +
"camera, so the hole keeps a constant on-screen size at every occluder depth.")]
[Range(0.05f, 3f)] public float radius = 0.5f;
[Tooltip("Soft-edge width of the cone wall at the player, in metres (also tapers toward the camera).")]
[Tooltip("Soft-edge width of the cone wall at the player, in metres, AT PLAYER SCALE 1 (also tapers " +
"toward the camera). Like the radius, the live value is multiplied by the hero target's uniform " +
"world scale (PlayerScaler) so the soft edge keeps the same on-screen proportion at any size.")]
[Range(0f, 1f)] public float feather = 0.15f;
[Tooltip("Soft depth band (m) straddling the player: instead of stopping at a hard plane at the " +
@@ -134,6 +138,11 @@ public class HeroCutout : MonoBehaviour
Vector3 heroPos = target.position + Vector3.up * heightOffset;
Vector3 camPos = cam.transform.position;
// Body-relative cone: the authored radius is the scale-1 size, scaled by the hero's uniform world
// size so the hole stays the same on screen for a small hider or a large hunter. lossyScale captures
// the full hierarchy (PlayerScaler drives localScale); reading it live tracks a mid-match conversion.
float bodyScale = Mathf.Max(1e-4f, target.lossyScale.x);
// Only punch the tube when something actually stands between the player and the camera; with a
// clear view the occluders stay solid. A short hold after the last blocked frame avoids flicker
// when the single ray grazes an occluder edge.
@@ -142,7 +151,7 @@ public class HeroCutout : MonoBehaviour
// Same hero point feeds the ray and the cone axis, so the gate and the cut volume agree.
Shader.SetGlobalVector(TargetId, new Vector4(heroPos.x, heroPos.y, heroPos.z, 1f));
Shader.SetGlobalVector(ParamsId, new Vector4(Mathf.Max(0f, radius), Mathf.Max(1e-4f, feather), Mathf.Max(1e-4f, depthFeather), 0f));
Shader.SetGlobalVector(ParamsId, new Vector4(Mathf.Max(0f, radius * bodyScale), Mathf.Max(1e-4f, feather * bodyScale), Mathf.Max(1e-4f, depthFeather), 0f));
}
/// <summary>