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
|
// Update is called once per frame
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
// Toggle cursor lock/unlock avec clic droit (disabled when keybind menu is open)
|
// Cursor lock: right-click unlocks, left-click re-locks (disabled when any UI panel is open)
|
||||||
if (!KeyBindingUI.IsVisible && Mouse.current != null && Mouse.current.rightButton.wasPressedThisFrame)
|
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.lockState = CursorLockMode.None;
|
||||||
Cursor.visible = true;
|
Cursor.visible = true;
|
||||||
Debug.Log("Cursor UNLOCKED");
|
|
||||||
}
|
}
|
||||||
else
|
else if (Cursor.lockState != CursorLockMode.Locked && Mouse.current.leftButton.wasPressedThisFrame)
|
||||||
{
|
{
|
||||||
Cursor.lockState = CursorLockMode.Locked;
|
Cursor.lockState = CursorLockMode.Locked;
|
||||||
Cursor.visible = false;
|
Cursor.visible = false;
|
||||||
Debug.Log("Cursor LOCKED");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,33 +372,19 @@ public class PlayerController : MonoBehaviour
|
|||||||
|
|
||||||
public void OnJump(InputAction.CallbackContext context)
|
public void OnJump(InputAction.CallbackContext context)
|
||||||
{
|
{
|
||||||
|
if (ChatUI.IsVisible) { isJumpPressed = false; jumpPressTime = 0f; return; }
|
||||||
|
|
||||||
if (context.started)
|
if (context.started)
|
||||||
{
|
{
|
||||||
isJumpPressed = true;
|
isJumpPressed = true;
|
||||||
jumpPressTime = 0f;
|
jumpPressTime = 0f;
|
||||||
StatsTracker.Instance?.RegisterJump();
|
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)
|
else if (context.canceled)
|
||||||
{
|
{
|
||||||
// Touche relâchée
|
|
||||||
float jumpForceFactor = Mathf.Clamp01(jumpPressTime / maxJumpHoldTime);
|
float jumpForceFactor = Mathf.Clamp01(jumpPressTime / maxJumpHoldTime);
|
||||||
if (IsGrounded())
|
if (IsGrounded())
|
||||||
{
|
|
||||||
PerformJump(jumpForceFactor * JumpForce);
|
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;
|
isJumpPressed = false;
|
||||||
jumpPressTime = 0f;
|
jumpPressTime = 0f;
|
||||||
}
|
}
|
||||||
@@ -424,75 +408,30 @@ public class PlayerController : MonoBehaviour
|
|||||||
|
|
||||||
public void OnForward(InputAction.CallbackContext context)
|
public void OnForward(InputAction.CallbackContext context)
|
||||||
{
|
{
|
||||||
if (context.started)
|
if (ChatUI.IsVisible) { isForwardHeld = false; return; }
|
||||||
{
|
if (context.started) isForwardHeld = true;
|
||||||
isForwardHeld = true;
|
else if (context.canceled) isForwardHeld = false;
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnBackwards(InputAction.CallbackContext context)
|
public void OnBackwards(InputAction.CallbackContext context)
|
||||||
{
|
{
|
||||||
if (context.started)
|
if (ChatUI.IsVisible) { isBackwardsHeld = false; return; }
|
||||||
{
|
if (context.started) isBackwardsHeld = true;
|
||||||
isBackwardsHeld = true;
|
else if (context.canceled) isBackwardsHeld = false;
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnLeft(InputAction.CallbackContext context)
|
public void OnLeft(InputAction.CallbackContext context)
|
||||||
{
|
{
|
||||||
if (context.started)
|
if (ChatUI.IsVisible) { isLeftHeld = false; return; }
|
||||||
{
|
if (context.started) isLeftHeld = true;
|
||||||
isLeftHeld = true;
|
else if (context.canceled) isLeftHeld = false;
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnRight(InputAction.CallbackContext context)
|
public void OnRight(InputAction.CallbackContext context)
|
||||||
{
|
{
|
||||||
if (context.started)
|
if (ChatUI.IsVisible) { isRightHeld = false; return; }
|
||||||
{
|
if (context.started) isRightHeld = true;
|
||||||
isRightHeld = true;
|
else if (context.canceled) isRightHeld = false;
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Bump collision with remote players ---
|
// --- Bump collision with remote players ---
|
||||||
@@ -564,6 +503,16 @@ public class PlayerController : MonoBehaviour
|
|||||||
_isSquashing = false;
|
_isSquashing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ResetInputs()
|
||||||
|
{
|
||||||
|
isForwardHeld = false;
|
||||||
|
isBackwardsHeld = false;
|
||||||
|
isLeftHeld = false;
|
||||||
|
isRightHeld = false;
|
||||||
|
isJumpPressed = false;
|
||||||
|
jumpPressTime = 0f;
|
||||||
|
}
|
||||||
|
|
||||||
void OnDestroy()
|
void OnDestroy()
|
||||||
{
|
{
|
||||||
// Clean up name label (it's not parented to the ball)
|
// 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.OnMessage<ChatUI.ChatMessage>("chat", msg => { ChatUI.Instance?.ReceiveChatMessage(msg); });
|
||||||
_room.OnLeave += OnRoomLeave;
|
_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();
|
OnConnected?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,11 +264,14 @@ public class NetworkManager : MonoBehaviour
|
|||||||
PlayerCount = _room.State.players?.Count ?? 0;
|
PlayerCount = _room.State.players?.Count ?? 0;
|
||||||
|
|
||||||
if (sessionId == LocalSessionId) return;
|
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);
|
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]}";
|
remoteBall.name = $"RemotePlayer_{player.name}_{sessionId[..6]}";
|
||||||
|
|
||||||
var controller = remoteBall.GetComponent<RemotePlayerController>()
|
var controller = remoteBall.GetComponent<RemotePlayerController>()
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ public class ChatUI : MonoBehaviour
|
|||||||
_pollTimer = POLL_INTERVAL; // poll immediately
|
_pollTimer = POLL_INTERVAL; // poll immediately
|
||||||
Cursor.lockState = CursorLockMode.None;
|
Cursor.lockState = CursorLockMode.None;
|
||||||
Cursor.visible = true;
|
Cursor.visible = true;
|
||||||
|
// Release held movement keys so the ball doesn't keep moving while typing
|
||||||
|
FindFirstObjectByType<PlayerController>()?.ResetInputs();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user