fix: chat input isolation, mouse lock, multi spawn
- PlayerController: block WASD/jump callbacks when ChatUI is open - PlayerController: clic droit = unlock souris, clic gauche = re-lock (n'est plus un toggle) - PlayerController: ajoute ResetInputs() appelé à l'ouverture du chat - ChatUI: appelle ResetInputs() quand le panel s'ouvre pour éviter les touches collées - NetworkManager: seed les joueurs déjà présents dans la room à la connexion (les OnAdd Colyseus peuvent être manqués si l'état est décodé avant l'enregistrement des callbacks) - NetworkManager: garde anti-doublon dans OnPlayerAdd - NetworkManager: fallback sphere si remotePlayerPrefab est null Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -180,20 +180,18 @@ public class PlayerController : MonoBehaviour
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
// Toggle cursor lock/unlock avec clic droit (disabled when keybind menu is open)
|
||||
if (!KeyBindingUI.IsVisible && Mouse.current != null && Mouse.current.rightButton.wasPressedThisFrame)
|
||||
// Cursor lock: right-click unlocks, left-click re-locks (disabled when any UI panel is open)
|
||||
if (!ChatUI.IsVisible && !KeyBindingUI.IsVisible && Mouse.current != null)
|
||||
{
|
||||
if (Cursor.lockState == CursorLockMode.Locked)
|
||||
if (Cursor.lockState == CursorLockMode.Locked && Mouse.current.rightButton.wasPressedThisFrame)
|
||||
{
|
||||
Cursor.lockState = CursorLockMode.None;
|
||||
Cursor.visible = true;
|
||||
Debug.Log("Cursor UNLOCKED");
|
||||
}
|
||||
else
|
||||
else if (Cursor.lockState != CursorLockMode.Locked && Mouse.current.leftButton.wasPressedThisFrame)
|
||||
{
|
||||
Cursor.lockState = CursorLockMode.Locked;
|
||||
Cursor.visible = false;
|
||||
Debug.Log("Cursor LOCKED");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,33 +372,19 @@ public class PlayerController : MonoBehaviour
|
||||
|
||||
public void OnJump(InputAction.CallbackContext context)
|
||||
{
|
||||
if (ChatUI.IsVisible) { isJumpPressed = false; jumpPressTime = 0f; return; }
|
||||
|
||||
if (context.started)
|
||||
{
|
||||
isJumpPressed = true;
|
||||
jumpPressTime = 0f;
|
||||
StatsTracker.Instance?.RegisterJump();
|
||||
Debug.Log("Jump Started");
|
||||
}
|
||||
else if (context.performed)
|
||||
{
|
||||
// Action validée (utile pour saut immédiat aussi)
|
||||
Debug.Log("Jump Performed");
|
||||
}
|
||||
else if (context.canceled)
|
||||
{
|
||||
// Touche relâchée
|
||||
float jumpForceFactor = Mathf.Clamp01(jumpPressTime / maxJumpHoldTime);
|
||||
if (IsGrounded())
|
||||
{
|
||||
PerformJump(jumpForceFactor * JumpForce);
|
||||
Debug.Log($"Jump Released after {jumpPressTime}s -> Force factor: {jumpForceFactor}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Jump Released but not grounded.");
|
||||
}
|
||||
|
||||
// Reset jump state so gauge goes back to 0
|
||||
isJumpPressed = false;
|
||||
jumpPressTime = 0f;
|
||||
}
|
||||
@@ -424,75 +408,30 @@ public class PlayerController : MonoBehaviour
|
||||
|
||||
public void OnForward(InputAction.CallbackContext context)
|
||||
{
|
||||
if (context.started)
|
||||
{
|
||||
isForwardHeld = true;
|
||||
Debug.Log("Forward Action Started");
|
||||
}
|
||||
else if (context.performed)
|
||||
{
|
||||
// Forward action performed
|
||||
Debug.Log("Forward Action Performed");
|
||||
}
|
||||
else if (context.canceled)
|
||||
{
|
||||
isForwardHeld = false;
|
||||
Debug.Log("Forward Action Canceled");
|
||||
}
|
||||
if (ChatUI.IsVisible) { isForwardHeld = false; return; }
|
||||
if (context.started) isForwardHeld = true;
|
||||
else if (context.canceled) isForwardHeld = false;
|
||||
}
|
||||
|
||||
public void OnBackwards(InputAction.CallbackContext context)
|
||||
{
|
||||
if (context.started)
|
||||
{
|
||||
isBackwardsHeld = true;
|
||||
Debug.Log("Backwards Action Started");
|
||||
}
|
||||
else if (context.performed)
|
||||
{
|
||||
Debug.Log("Backwards Action Performed");
|
||||
}
|
||||
else if (context.canceled)
|
||||
{
|
||||
isBackwardsHeld = false;
|
||||
Debug.Log("Backwards Action Canceled");
|
||||
}
|
||||
if (ChatUI.IsVisible) { isBackwardsHeld = false; return; }
|
||||
if (context.started) isBackwardsHeld = true;
|
||||
else if (context.canceled) isBackwardsHeld = false;
|
||||
}
|
||||
|
||||
public void OnLeft(InputAction.CallbackContext context)
|
||||
{
|
||||
if (context.started)
|
||||
{
|
||||
isLeftHeld = true;
|
||||
Debug.Log("Left Action Started");
|
||||
}
|
||||
else if (context.performed)
|
||||
{
|
||||
Debug.Log("Left Action Performed");
|
||||
}
|
||||
else if (context.canceled)
|
||||
{
|
||||
isLeftHeld = false;
|
||||
Debug.Log("Left Action Canceled");
|
||||
}
|
||||
if (ChatUI.IsVisible) { isLeftHeld = false; return; }
|
||||
if (context.started) isLeftHeld = true;
|
||||
else if (context.canceled) isLeftHeld = false;
|
||||
}
|
||||
|
||||
public void OnRight(InputAction.CallbackContext context)
|
||||
{
|
||||
if (context.started)
|
||||
{
|
||||
isRightHeld = true;
|
||||
Debug.Log("Right Action Started");
|
||||
}
|
||||
else if (context.performed)
|
||||
{
|
||||
Debug.Log("Right Action Performed");
|
||||
}
|
||||
else if (context.canceled)
|
||||
{
|
||||
isRightHeld = false;
|
||||
Debug.Log("Right Action Canceled");
|
||||
}
|
||||
if (ChatUI.IsVisible) { isRightHeld = false; return; }
|
||||
if (context.started) isRightHeld = true;
|
||||
else if (context.canceled) isRightHeld = false;
|
||||
}
|
||||
|
||||
// --- Bump collision with remote players ---
|
||||
@@ -564,6 +503,16 @@ public class PlayerController : MonoBehaviour
|
||||
_isSquashing = false;
|
||||
}
|
||||
|
||||
public void ResetInputs()
|
||||
{
|
||||
isForwardHeld = false;
|
||||
isBackwardsHeld = false;
|
||||
isLeftHeld = false;
|
||||
isRightHeld = false;
|
||||
isJumpPressed = false;
|
||||
jumpPressTime = 0f;
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
// Clean up name label (it's not parented to the ball)
|
||||
|
||||
@@ -163,6 +163,13 @@ public class NetworkManager : MonoBehaviour
|
||||
_room.OnMessage<ChatUI.ChatMessage>("chat", msg => { ChatUI.Instance?.ReceiveChatMessage(msg); });
|
||||
_room.OnLeave += OnRoomLeave;
|
||||
|
||||
// Seed players already present in the room (state decoded before callbacks were registered)
|
||||
if (_room.State.players != null)
|
||||
{
|
||||
foreach (var kvp in _room.State.players)
|
||||
OnPlayerAdd(kvp.Key, kvp.Value);
|
||||
}
|
||||
|
||||
OnConnected?.Invoke();
|
||||
}
|
||||
|
||||
@@ -257,11 +264,14 @@ public class NetworkManager : MonoBehaviour
|
||||
PlayerCount = _room.State.players?.Count ?? 0;
|
||||
|
||||
if (sessionId == LocalSessionId) return;
|
||||
if (_remotePlayers.ContainsKey(sessionId)) return; // prevent duplicate spawn
|
||||
|
||||
if (remotePlayerPrefab != null)
|
||||
{
|
||||
Vector3 spawnPos = new Vector3(player.x, player.y, player.z);
|
||||
GameObject remoteBall = Instantiate(remotePlayerPrefab, spawnPos, Quaternion.identity);
|
||||
GameObject remoteBall = remotePlayerPrefab != null
|
||||
? Instantiate(remotePlayerPrefab, spawnPos, Quaternion.identity)
|
||||
: GameObject.CreatePrimitive(PrimitiveType.Sphere);
|
||||
remoteBall.transform.position = spawnPos;
|
||||
remoteBall.name = $"RemotePlayer_{player.name}_{sessionId[..6]}";
|
||||
|
||||
var controller = remoteBall.GetComponent<RemotePlayerController>()
|
||||
|
||||
@@ -76,6 +76,8 @@ public class ChatUI : MonoBehaviour
|
||||
_pollTimer = POLL_INTERVAL; // poll immediately
|
||||
Cursor.lockState = CursorLockMode.None;
|
||||
Cursor.visible = true;
|
||||
// Release held movement keys so the ball doesn't keep moving while typing
|
||||
FindFirstObjectByType<PlayerController>()?.ResetInputs();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user