diff --git a/Assets/Scripts/Gameplay/UserInput/ClientInputSender.cs b/Assets/Scripts/Gameplay/UserInput/ClientInputSender.cs index 0603616e..9b33afa4 100644 --- a/Assets/Scripts/Gameplay/UserInput/ClientInputSender.cs +++ b/Assets/Scripts/Gameplay/UserInput/ClientInputSender.cs @@ -13,6 +13,10 @@ using UnityEngine.AI; using UnityEngine.Assertions; using UnityEngine.EventSystems; using UnityEngine.Serialization; +using CnControls; + +//#if UNITY_ANDROID || UNITY_IOS +//#endif namespace Unity.BossRoom.Gameplay.UserInput { @@ -45,10 +49,9 @@ namespace Unity.BossRoom.Gameplay.UserInput RaycastHitComparer m_RaycastHitComparer; [SerializeField] private StaminaManager staminaManager; - private bool isSprinting = false; + private bool isSprinting; [SerializeField] ServerCharacter m_ServerCharacter; - /// /// This event fires at the time when an action request is sent to the server. /// @@ -146,10 +149,17 @@ namespace Unity.BossRoom.Gameplay.UserInput { if (m_InputAllower) { +#if UNITY_ANDROID || UNITY_IOS + HandleMobileSprint(); + HandleMobileSwapInput(); + HandleMobileAbilityInput(); + HandleMobileMovementInput(); +#else HandleSprint(); HandleSwapInput(); HandleAbilityInput(); HandleMovementInput(); +#endif //CursorUpdate(); } } @@ -286,12 +296,13 @@ namespace Unity.BossRoom.Gameplay.UserInput if (m_MoveRequest) { m_MoveRequest = false; - if ((Time.time - m_LastSentMove) > k_MoveSendRateSeconds) +#if UNITY_ANDROID || UNITY_IOS + if (Input.touchCount > 0) { - m_LastSentMove = Time.time; - var ray = m_MainCamera.ScreenPointToRay(UnityEngine.Input.mousePosition); + Vector3 screenPosition = Input.GetTouch(0).position; + var ray = m_MainCamera.ScreenPointToRay(screenPosition); - var groundHits = Physics.RaycastNonAlloc(ray, + int groundHits = Physics.RaycastNonAlloc(ray, k_CachedHit, k_MouseInputRaycastDistance, m_GroundLayerMask); @@ -311,12 +322,37 @@ namespace Unity.BossRoom.Gameplay.UserInput NavMesh.AllAreas)) { m_ServerCharacter.ServerSendCharacterInputRpc(hit.position); - - //Send our client only click request ClientMoveEvent?.Invoke(hit.position); } } } +#else + var ray = m_MainCamera.ScreenPointToRay(UnityEngine.Input.mousePosition); + + int groundHits = Physics.RaycastNonAlloc(ray, + k_CachedHit, + k_MouseInputRaycastDistance, + m_GroundLayerMask); + + if (groundHits > 0) + { + if (groundHits > 1) + { + // sort hits by distance + Array.Sort(k_CachedHit, 0, groundHits, m_RaycastHitComparer); + } + + // verify point is indeed on navmesh surface + if (NavMesh.SamplePosition(k_CachedHit[0].point, + out var hit, + k_MaxNavMeshDistance, + NavMesh.AllAreas)) + { + m_ServerCharacter.ServerSendCharacterInputRpc(hit.position); + ClientMoveEvent?.Invoke(hit.position); + } + } +#endif } } @@ -511,7 +547,7 @@ namespace Unity.BossRoom.Gameplay.UserInput bool SwapKeyPressed = false; private void HandleSwapInput() { - if (Input.GetKeyDown(KeyCode.Q)) + if (Input.GetKeyDown(KeyCode.Q) || CnInputManager.GetButtonDown("Swap")) { if (CanActivateSwapMode()) { @@ -532,7 +568,8 @@ namespace Unity.BossRoom.Gameplay.UserInput private void HandleAbilityInput() { - if (Input.GetKeyDown(KeyCode.E)) // Dash'N'Crash + //if (Input.GetKeyDown(KeyCode.E)) // Dash'N'Crash + if (CnInputManager.GetButtonDown(GameDataSource.Instance.DashNCrashAbilityKey) || Input.GetKeyDown(KeyCode.E)) // Dash'N'Crash { if (!m_ServerCharacter.IsCrow) { @@ -541,20 +578,15 @@ namespace Unity.BossRoom.Gameplay.UserInput } ActivateAbilityIfAllowed(GameDataSource.Instance.DashNCrashAbilityKey, "Abilities are only for crow"); } - if (Input.GetKeyDown(KeyCode.R)) // Freeze Throw + if (CnInputManager.GetButtonDown(GameDataSource.Instance.FreezeThrowAbilityKey) || Input.GetKeyDown(KeyCode.R)) // Freeze Throw { ActivateAbilityIfAllowed(GameDataSource.Instance.FreezeThrowAbilityKey); } - if (Input.GetKeyDown(KeyCode.F)) // Vector Wall + if (CnInputManager.GetButtonDown("VectorWall") || Input.GetKeyDown(KeyCode.F)) // Vector Wall { - //if (m_ServerCharacter.IsCrow) - //{ - // m_UIMessageFeed.DisplayMessage("Ability not available for crow"); - // return; - //} ActivateAbilityIfAllowed(GameDataSource.Instance.VectorWallAbilityKey); } - if (Input.GetKeyDown(KeyCode.C)) // The Executioner + if (CnInputManager.GetButtonDown(GameDataSource.Instance.TheExecutionerKey) || Input.GetKeyDown(KeyCode.C)) // The Executioner { if (m_ServerCharacter.IsCrow) { @@ -563,7 +595,7 @@ namespace Unity.BossRoom.Gameplay.UserInput } ActivateAbilityIfAllowed(GameDataSource.Instance.TheExecutionerKey); } - if (Input.GetKeyDown(KeyCode.V)) // Crow's Foresight + if (CnInputManager.GetButtonDown(GameDataSource.Instance.CrowsForesightKey) || Input.GetKeyDown(KeyCode.V)) // Crow's Foresight { if (!m_ServerCharacter.IsCrow) { @@ -571,12 +603,12 @@ namespace Unity.BossRoom.Gameplay.UserInput return; } ActivateAbilityIfAllowed(GameDataSource.Instance.CrowsForesightKey); - } + } } private void HandleSprint() { - if(m_ServerCharacter.IsCrow) return; - if (Input.GetKey(KeyCode.LeftShift)) + if (m_ServerCharacter.IsCrow) return; + if (CnInputManager.GetButtonDown("Sprint") || Input.GetKey(KeyCode.LeftShift)) { float staminaCost = 50f * Time.deltaTime; @@ -584,27 +616,22 @@ namespace Unity.BossRoom.Gameplay.UserInput { if (!isSprinting) { - isSprinting = true; StartSprintServerRPC(); } } else { - isSprinting = false; StopSprintServerRPC(); staminaManager.StopConsuming(); // Allows regen after delay } } else if (isSprinting) // Sprint key released { - isSprinting = false; StopSprintServerRPC(); staminaManager.StopConsuming(); // Allows regen after delay } } - - [ServerRpc] private void StartSprintServerRPC() { @@ -617,8 +644,6 @@ namespace Unity.BossRoom.Gameplay.UserInput m_ServerCharacter.Movement.SetSpeedModifier(1f); } - - private void ActivateAbilityIfAllowed(string abilityKey, string errorMessage = null) { if (IsSwapModeActive) @@ -626,7 +651,6 @@ namespace Unity.BossRoom.Gameplay.UserInput Debug.Log("Cannot activate ability mode while swap mode is active."); return; } - m_UIMessageFeed.DisplayMessage("Activated Ability mode"); m_AbilitySystem.ActivateAbilityByKey(abilityKey); } @@ -643,9 +667,12 @@ namespace Unity.BossRoom.Gameplay.UserInput { m_ServerCharacter.Movement.CancelMove(); } - if (IsSwapModeActive && Input.GetMouseButtonDown(0)) // Left-click to request swap + if (!EventSystem.current.IsPointerOverGameObject() && m_CurrentSkillInput == null) { - HandleSwapRequest(); + if (IsSwapModeActive && Input.GetMouseButtonDown(0)) // Left-click to request swap + { + HandleSwapRequest(); + } } } @@ -694,7 +721,6 @@ namespace Unity.BossRoom.Gameplay.UserInput /// /// Handles the swap request when in swap mode. /// - private void HandleSwapRequest() { var ray = m_MainCamera.ScreenPointToRay(Input.mousePosition); @@ -710,13 +736,10 @@ namespace Unity.BossRoom.Gameplay.UserInput if (targetNetObj.TryGetComponent(out ServerCharacter targetCharacter)) { // Initiate the swap - targetCharacter.NotifySwapRequestRpc(m_ServerCharacter.NetworkObjectId, m_ServerCharacter.uIStateDisplayHandler.m_UIState.playerName); Debug.Log($"Swap request sent to {targetCharacter.name}."); GameStateManager.Instance.ChangeState(CursorState.Default); IsSwapModeActive = false; // Automatically deactivate swap mode after a successful request - - //AddMultiplier(targetCharacter); return; } } @@ -725,7 +748,6 @@ namespace Unity.BossRoom.Gameplay.UserInput Debug.LogWarning("No valid target found for swapping."); } - void UpdateAction1() { var isHoldingNetworkObject = @@ -739,7 +761,6 @@ namespace Unity.BossRoom.Gameplay.UserInput if (isHoldingNetworkObject) { // show drop! - actionState1.actionID = GameDataSource.Instance.DropActionPrototype.ActionID; } else if ((m_ServerCharacter.TargetId.Value != 0 @@ -748,7 +769,6 @@ namespace Unity.BossRoom.Gameplay.UserInput ) { // special case: targeting a pickup-able item or holding a pickup object - actionState1.actionID = GameDataSource.Instance.PickUpActionPrototype.ActionID; } else if (m_ServerCharacter.TargetId.Value != 0 @@ -760,7 +780,6 @@ namespace Unity.BossRoom.Gameplay.UserInput // special case: when we have a player selected, we change the meaning of the basic action // we have another player selected! In that case we want to reflect that our basic Action is a Revive, not an attack! // But we need to know if the player is alive... if so, the button should be disabled (for better player communication) - actionState1.actionID = GameDataSource.Instance.ReviveActionPrototype.ActionID; isSelectable = charState.NetLifeState.LifeState.Value != LifeState.Alive; } @@ -786,5 +805,109 @@ namespace Unity.BossRoom.Gameplay.UserInput selectable = isSelectable; } } + +#if UNITY_ANDROID || UNITY_IOS + // Mobile-specific input handlers using CNInputControls and touch input + + private void HandleMobileSprint() + { + //if (m_ServerCharacter.IsCrow) return; + if (CnInputManager.GetButton(GameDataSource.Instance.SprintButtonKey)) + { + float staminaCost = 50f * Time.deltaTime; + if (staminaManager.TryConsume(staminaCost)) + { + if (!isSprinting) + { + StartSprintServerRPC(); + isSprinting = true; + } + } + else + { + StopSprintServerRPC(); + staminaManager.StopConsuming(); + isSprinting = false; + } + } + else if (isSprinting) // Sprint button released + { + StopSprintServerRPC(); + staminaManager.StopConsuming(); + isSprinting = false; + } + } + + private void HandleMobileSwapInput() + { + if (CnInputManager.GetButtonDown(GameDataSource.Instance.SwapButtonKey)) + { + if (CanActivateSwapMode()) + { + ToggleSwapMode(); + } + else + { + m_UIMessageFeed.DisplayMessage("Not on a platform or not a player"); + Debug.Log("Cannot activate swap mode while ability mode is active."); + } + } + } + + private void HandleMobileAbilityInput() + { + if (CnInputManager.GetButtonDown(GameDataSource.Instance.DashNCrashAbilityKey)) + { + if (!m_ServerCharacter.IsCrow) + { + m_UIMessageFeed.DisplayMessage("You must be the Crow to activate this ability"); + return; + } + ActivateAbilityIfAllowed(GameDataSource.Instance.DashNCrashAbilityKey, "Abilities are only for crow"); + } + if (CnInputManager.GetButtonDown(GameDataSource.Instance.FreezeThrowAbilityKey)) + { + ActivateAbilityIfAllowed(GameDataSource.Instance.FreezeThrowAbilityKey); + } + if (CnInputManager.GetButtonDown("VectorWall")) + { + ActivateAbilityIfAllowed(GameDataSource.Instance.VectorWallAbilityKey); + } + if (CnInputManager.GetButtonDown(GameDataSource.Instance.TheExecutionerKey)) + { + if (m_ServerCharacter.IsCrow) + { + m_UIMessageFeed.DisplayMessage("Ability not available for crow"); + return; + } + ActivateAbilityIfAllowed(GameDataSource.Instance.TheExecutionerKey); + } + if (CnInputManager.GetButtonDown(GameDataSource.Instance.CrowsForesightKey)) + { + if (!m_ServerCharacter.IsCrow) + { + m_UIMessageFeed.DisplayMessage("You must be the Crow to activate this ability"); + return; + } + ActivateAbilityIfAllowed(GameDataSource.Instance.CrowsForesightKey); + } + } + + private void HandleMobileMovementInput() + { + if (!m_AbilitySystem.isAbilityActive) + { + if (Input.touchCount > 0) + { + Touch touch = Input.GetTouch(0); + if (touch.phase == TouchPhase.Began && !EventSystem.current.IsPointerOverGameObject(touch.fingerId)) + { + CancelActiveModes(); + m_MoveRequest = true; + } + } + } + } +#endif } }