Fix players colliding with the idle FreeCamera capsule
The FreeCamera's CharacterController stayed enabled permanently, so its invisible capsule sat in the play area at (0,1,0) and blocked players even when the freecam was not in use: the controller script disables only itself in Awake, not the independent CharacterController collider. Keep the capsule out of the physics world unless the freecam is actually flying: disable it in Awake and toggle it with SetActive (enabled before the teleport in SyncToCurrentView, which preserves the current enabled state). Also ignore collision against all live players instead of just the first on each activation, since Physics.IgnoreCollision is reset when the capsule is toggled off and back on. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
d867452dcb
commit
0c0a250015
1 file changed
+13
-8
@@ -60,7 +60,6 @@ public class FreeCamController : MonoBehaviour
|
||||
SmoothedLook _look; // yaw/pitch accumulator + smoothing shared with first person
|
||||
Vector3 _moveVelocity; // smoothed world-space flight velocity
|
||||
Vector3 _moveVelocityRef;
|
||||
bool _ignoredPlayer;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
@@ -71,7 +70,10 @@ public class FreeCamController : MonoBehaviour
|
||||
else
|
||||
_vcam.Priority = inactivePriority;
|
||||
|
||||
// Dormant until FreeCamMode enters; nothing reads input or moves the rig meanwhile.
|
||||
// Dormant until FreeCamMode enters: disable the capsule too, otherwise it lingers as a live
|
||||
// collider sitting in the play area and blocks players who walk into it (a CharacterController
|
||||
// stays a physics collider on its own, independent of this self-disabled script).
|
||||
_controller.enabled = false;
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
@@ -82,6 +84,11 @@ public class FreeCamController : MonoBehaviour
|
||||
if (_vcam)
|
||||
_vcam.Priority = active ? activePriority : inactivePriority;
|
||||
|
||||
// Only a flying freecam needs its capsule; keep it out of the physics world otherwise so it
|
||||
// never blocks players. Must be enabled before SyncToCurrentView, whose teleport preserves the
|
||||
// current enabled state around the position write.
|
||||
_controller.enabled = active;
|
||||
|
||||
if (active)
|
||||
{
|
||||
IgnorePlayerCollision();
|
||||
@@ -141,14 +148,12 @@ public class FreeCamController : MonoBehaviour
|
||||
_moveVelocityRef = Vector3.zero;
|
||||
}
|
||||
|
||||
/// <summary>Stop the freecam capsule from being blocked by the (frozen) player's capsule.</summary>
|
||||
/// <summary>Stop the freecam capsule from being blocked by the frozen players' capsules. Re-runs on
|
||||
/// every activation on purpose: Physics.IgnoreCollision is reset when the freecam capsule is toggled
|
||||
/// off/on, and the roster of live players can differ between spectate sessions.</summary>
|
||||
void IgnorePlayerCollision()
|
||||
{
|
||||
if (_ignoredPlayer) return;
|
||||
_ignoredPlayer = true;
|
||||
|
||||
var player = FindFirstObjectByType<PlayerCharacterController>();
|
||||
if (player)
|
||||
foreach (var player in FindObjectsByType<PlayerCharacterController>(FindObjectsSortMode.None))
|
||||
{
|
||||
var playerCC = player.GetComponent<CharacterController>();
|
||||
// Only an enabled capsule can take part in a collision-ignore (a spectator's body has its CC
|
||||
|
||||
Reference in new issue
Block a user