Exclude other players from climb probes and spread network spawns
Wall/ceiling/ground climb probes now skip any player collider (own and remote) instead of only the local hierarchy, so running into another chameleon no longer triggers the climb mechanic. New players are placed on a per-clientId ring at spawn (host stays at origin) to avoid stacking into one collision pile. Also persists the serialized defaults of the recent network fields into the Player prefab (incl. the spawnRingRadius inspector tuning) and a TMP dynamic-atlas reset artifact.
This commit is contained in:
1 parent
eedba5f0e6
commit
10f2518640
4 files changed
+1316
-13
No files matched your search
@@ -940,6 +940,16 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
private float WorldHalfHeight => _controller.height * 0.5f * CapsuleScale;
|
||||
private const float ProbeReachSlack = 0.5f; // extra ray length beyond the capsule surface (scale-1 units)
|
||||
|
||||
/// <summary>
|
||||
/// True if the collider belongs to ANY player avatar -- this one OR a networked remote. Every climb
|
||||
/// probe must skip players: avatars still collide physically (this player's CharacterController vs a
|
||||
/// remote's baked MeshCollider), but another chameleon's body must never register as a climbable
|
||||
/// wall/ceiling/ground. Replaces the old self-only IsChildOf check -- self is a player too, so it
|
||||
/// stays excluded. Finds the controller even on remotes, where the component is disabled (only the
|
||||
/// GameObject's active state gates GetComponentInParent, not the component's enabled flag).
|
||||
/// </summary>
|
||||
private static bool IsPlayerCollider(Collider c) => c.GetComponentInParent<PlayerCharacterController>();
|
||||
|
||||
/// <summary>
|
||||
/// Raycasts from the character center toward the surface (along -_wallNormal) to find the
|
||||
/// current normal and the gap (surface clearance) to it. The capsule's support distance
|
||||
@@ -963,7 +973,7 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
bool found = false;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (_wallProbe[i].collider.transform.IsChildOf(transform)) // skip our own colliders
|
||||
if (IsPlayerCollider(_wallProbe[i].collider)) // skip self and other player avatars
|
||||
continue;
|
||||
if (_wallProbe[i].distance < best)
|
||||
{
|
||||
@@ -1008,7 +1018,7 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
bool found = false;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (_wallProbe[i].collider.transform.IsChildOf(transform))
|
||||
if (IsPlayerCollider(_wallProbe[i].collider))
|
||||
continue;
|
||||
if (_wallProbe[i].normal.y >= CeilingNormalThreshold) // not a ceiling
|
||||
continue;
|
||||
@@ -1080,7 +1090,7 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
origin, -_wallNormal, _wallProbe, maxDist, ~0, QueryTriggerInteraction.Ignore);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (_wallProbe[i].collider.transform.IsChildOf(transform))
|
||||
if (IsPlayerCollider(_wallProbe[i].collider))
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
@@ -1106,7 +1116,7 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
bool found = false;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (_wallProbe[i].collider.transform.IsChildOf(transform))
|
||||
if (IsPlayerCollider(_wallProbe[i].collider))
|
||||
continue;
|
||||
if (_wallProbe[i].distance < best)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user