diff --git a/.idea/.idea.Sea_battle/.idea/encodings.xml b/.idea/.idea.Sea_battle/.idea/encodings.xml index 34adeb39..a82c02d3 100644 --- a/.idea/.idea.Sea_battle/.idea/encodings.xml +++ b/.idea/.idea.Sea_battle/.idea/encodings.xml @@ -6,12 +6,15 @@ + + + diff --git a/Assets/Prefabs/ship/1_Tartan.prefab b/Assets/Prefabs/ship/1_Tartan.prefab index 645554fe..77cd27f1 100644 --- a/Assets/Prefabs/ship/1_Tartan.prefab +++ b/Assets/Prefabs/ship/1_Tartan.prefab @@ -1017,11 +1017,11 @@ MonoBehaviour: rotationAmountX: 2 rotationSpeedZ: 2 rotationAmountZ: 2 - sinkingSpeed: 0.5 + sinkingSpeed: 1 sinkEndOffsets: - - {x: 0, y: -0.3, z: 0} - - {x: 0, y: -0.3, z: -0.5} - - {x: -0.5, y: -0.3, z: 0} + - {x: 0, y: -1.5, z: 0} + - {x: 0, y: -1.5, z: -1.5} + - {x: -0.8, y: -1.5, z: 0} sinkEndRotationsEuler: - {x: 0, y: 0, z: 0} - {x: 20, y: 0, z: 0} diff --git a/Assets/Prefabs/ship/2_Galeon_test.prefab b/Assets/Prefabs/ship/2_Galeon_test.prefab index 86fac171..cc2b3ec7 100644 --- a/Assets/Prefabs/ship/2_Galeon_test.prefab +++ b/Assets/Prefabs/ship/2_Galeon_test.prefab @@ -1018,10 +1018,10 @@ MonoBehaviour: rotationAmountZ: 2 sinkingSpeed: 0.2 sinkEndOffsets: - - {x: 0, y: -0.5, z: 0} - - {x: 0, y: -0.5, z: 0.5} - - {x: 0.5, y: -0.5, z: 0} - - {x: 0, y: -0.5, z: -1} + - {x: 0, y: -0.8, z: 0} + - {x: 0, y: -0.8, z: 0.5} + - {x: 0.5, y: -0.8, z: 0} + - {x: 0, y: -0.8, z: -1} sinkEndRotationsEuler: - {x: 0, y: 0, z: 0} - {x: 0, y: 0, z: 20} diff --git a/Assets/Prefabs/ship/2_Sloop _test.prefab b/Assets/Prefabs/ship/2_Sloop _test.prefab index ef162e24..5a47e21b 100644 --- a/Assets/Prefabs/ship/2_Sloop _test.prefab +++ b/Assets/Prefabs/ship/2_Sloop _test.prefab @@ -218,6 +218,7 @@ Transform: m_LocalScale: {x: 4, y: 4, z: 4} m_ConstrainProportionsScale: 0 m_Children: + - {fileID: 8359583415847336211} - {fileID: 6435084559715987784} m_Father: {fileID: 1162319415148144713} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -1262,8 +1263,8 @@ MonoBehaviour: - {fileID: 1423532895168835702, guid: e45c31cb2ebda31439060b705d8380a9, type: 3} - {fileID: 2180637233693737021, guid: a8e105ce9987c3245898956221117bd2, type: 3} - {fileID: 7073132335079459726, guid: 96f54650cc4140043996d93b80ed0bf7, type: 3} - debrisCount: 10 - spawnRadius: 1 + debrisCount: 15 + spawnRadius: 5 minExplosionForce: 15 maxExplosionForce: 60 mastsContainer: {fileID: 6985298276910783020} @@ -1295,8 +1296,8 @@ MonoBehaviour: rotationAmountZ: 1 sinkingSpeed: 0.2 sinkEndOffsets: - - {x: 0, y: -0.7, z: 0.5} - - {x: 0, y: -0.7, z: -0.5} + - {x: 0, y: -2, z: 0.5} + - {x: 0, y: -1.5, z: -0.5} sinkEndRotationsEuler: - {x: 0, y: 0, z: 0} - {x: 0, y: 0, z: 90} @@ -1876,11 +1877,11 @@ Transform: m_GameObject: {fileID: 5254029589121660938} serializedVersion: 2 m_LocalRotation: {x: -0.000000026692538, y: 0.7071068, z: -0.000000026692538, w: -0.7071068} - m_LocalPosition: {x: -0.047136307, y: -0.7857026, z: -0.5183008} + m_LocalPosition: {x: -0.45347857, y: -0.4301314, z: -0} m_LocalScale: {x: 0.0019999999, y: 0.0019999999, z: 0.0019999999} m_ConstrainProportionsScale: 0 m_Children: [] - m_Father: {fileID: 5076732976100659974} + m_Father: {fileID: 5831099337584467131} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &3805225092690876828 MeshFilter: @@ -2747,7 +2748,6 @@ Transform: - {fileID: 8532906577082464844} - {fileID: 5342643454630709713} - {fileID: 8513761139304901918} - - {fileID: 8359583415847336211} - {fileID: 8806108968044347987} - {fileID: 2632539959676126641} - {fileID: 6581711230572120705} diff --git a/Assets/Prefabs/ship/3_Frigate_test.prefab b/Assets/Prefabs/ship/3_Frigate_test.prefab index 7d032a5a..2376dea3 100644 --- a/Assets/Prefabs/ship/3_Frigate_test.prefab +++ b/Assets/Prefabs/ship/3_Frigate_test.prefab @@ -648,9 +648,9 @@ MonoBehaviour: rotationAmountZ: 2 sinkingSpeed: 0.3 sinkEndOffsets: - - {x: 0, y: -0.7, z: 0.5} - - {x: 0, y: -0.7, z: -0.5} - - {x: 0.5, y: -0.9, z: 0} + - {x: 0, y: -3, z: 0.5} + - {x: 0, y: -3, z: -0.5} + - {x: 0.5, y: -2.2, z: 0} sinkEndRotationsEuler: - {x: 0, y: 0, z: 0} - {x: 40, y: 0, z: 0} diff --git a/Assets/Prefabs/ship/4_sch_test2.prefab b/Assets/Prefabs/ship/4_sch_test2.prefab index 3f3e6491..45a42cac 100644 --- a/Assets/Prefabs/ship/4_sch_test2.prefab +++ b/Assets/Prefabs/ship/4_sch_test2.prefab @@ -8120,12 +8120,12 @@ MonoBehaviour: rotationAmountX: 1 rotationSpeedZ: 1 rotationAmountZ: 2 - sinkingSpeed: 0.2 + sinkingSpeed: 0.1 sinkEndOffsets: - - {x: 0, y: -1.8, z: 0} - - {x: 0, y: -1.8, z: -0.5} - - {x: 0.5, y: -1.8, z: 0} - - {x: -0.5, y: -1.8, z: 0.3} + - {x: 0, y: -2.5, z: 0} + - {x: 0, y: -2.5, z: -0.5} + - {x: 0.5, y: -2.5, z: 0} + - {x: -0.5, y: -2.5, z: 0.3} sinkEndRotationsEuler: - {x: 0, y: 0, z: 0} - {x: 0, y: 0, z: 20} diff --git a/Assets/Scenes/Recovery.unity b/Assets/Scenes/Recovery.unity index ca530b75..401c9e9e 100644 --- a/Assets/Scenes/Recovery.unity +++ b/Assets/Scenes/Recovery.unity @@ -18541,10 +18541,6 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: e35d3ce2464469c4b8841fb1b13ecbcd, type: 3} m_Name: m_EditorClassIdentifier: - shipPlacementCameraPosition: {fileID: 1873263836} - mainMenuCameraPosition: {fileID: 844331937} - gameplayCameraPosition: {fileID: 671549654} - shipPlacementPivotPoint: {fileID: 1634635834} isReady: 0 opponentManager: {fileID: 709017262} battery: {fileID: 3827054704053395659} @@ -18559,10 +18555,10 @@ MonoBehaviour: enemyShips: 0 playerId: 1 playerCamera: {fileID: 1666900993} - cameraPivot: {fileID: 1823975341} currentBotLevel: 0 enemyManager: {fileID: 1082318119} fortInitializer: {fileID: 161689628} + cameraController: {fileID: 1666900995} inactionTimer: 360 mainMenuVideoIdleDelay: 30 timerBackToMenu: 0 @@ -18574,7 +18570,6 @@ MonoBehaviour: bossLevelConfig: {fileID: 11400000, guid: 1986dd5b80a713e42a0e6c8ef2d25cf7, type: 2} gameMode: 1 botDifficulty: 4 - cameraMoveDuration: 1 --- !u!114 &159966420 MonoBehaviour: m_ObjectHideFlags: 0 @@ -23236,7 +23231,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!224 &224990383 RectTransform: m_ObjectHideFlags: 0 @@ -62428,7 +62423,7 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 21300000, guid: 566f8179b986411429ce94ddb475e927, type: 3} + m_Sprite: {fileID: 21300000, guid: 900121fa327790a4da24ecb591bed11f, type: 3} m_Type: 0 m_PreserveAspect: 0 m_FillCenter: 1 @@ -64515,10 +64510,6 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: e35d3ce2464469c4b8841fb1b13ecbcd, type: 3} m_Name: m_EditorClassIdentifier: - shipPlacementCameraPosition: {fileID: 849152746} - mainMenuCameraPosition: {fileID: 1001098613} - gameplayCameraPosition: {fileID: 2103039880} - shipPlacementPivotPoint: {fileID: 30081209} isReady: 0 opponentManager: {fileID: 159966419} battery: {fileID: 511875351} @@ -64533,10 +64524,10 @@ MonoBehaviour: enemyShips: 0 playerId: 2 playerCamera: {fileID: 2088812084} - cameraPivot: {fileID: 1521149900} currentBotLevel: 0 enemyManager: {fileID: 1514025423} fortInitializer: {fileID: 1221878237} + cameraController: {fileID: 2088812088} inactionTimer: 360 mainMenuVideoIdleDelay: 30 timerBackToMenu: 0 @@ -64548,7 +64539,6 @@ MonoBehaviour: bossLevelConfig: {fileID: 11400000, guid: 1986dd5b80a713e42a0e6c8ef2d25cf7, type: 2} gameMode: 1 botDifficulty: 4 - cameraMoveDuration: 1 --- !u!114 &709017263 MonoBehaviour: m_ObjectHideFlags: 0 @@ -87086,7 +87076,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!224 &992521663 RectTransform: m_ObjectHideFlags: 0 @@ -90896,7 +90886,7 @@ RectTransform: m_Father: {fileID: 982214768} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 0.1} m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 20, y: 20} m_Pivot: {x: 0.5, y: 0.5} @@ -135276,7 +135266,7 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 21300000, guid: 566f8179b986411429ce94ddb475e927, type: 3} + m_Sprite: {fileID: 21300000, guid: 900121fa327790a4da24ecb591bed11f, type: 3} m_Type: 0 m_PreserveAspect: 0 m_FillCenter: 1 @@ -150377,6 +150367,7 @@ GameObject: - component: {fileID: 1666900993} - component: {fileID: 1666900992} - component: {fileID: 1666900994} + - component: {fileID: 1666900995} m_Layer: 0 m_Name: PL1_Camera m_TagString: MainCamera @@ -150470,6 +150461,31 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d236899b5d0974d49a62287f9f8aabfb, type: 3} m_Name: m_EditorClassIdentifier: +--- !u!114 &1666900995 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1666900990} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2227656a6dd2612449553ba37dd212a1, type: 3} + m_Name: + m_EditorClassIdentifier: + pivot: {fileID: 1823975341} + gameManager: {fileID: 159966419} + shipPlacementCameraPosition: {fileID: 1873263836} + mainMenuCameraPosition: {fileID: 844331937} + gameplayCameraPosition: {fileID: 671549654} + rotateLeftKey: 4 + rotateRightKey: 5 + rotateSpeed: 90 + returnSpeed: 120 + turnHoldThreshold: 0.3 + cameraMoveDuration: 1 + doubleTapWindow: 0.4 + shipPlacementPivotPoint: {fileID: 1634635834} --- !u!1001 &1667078630 PrefabInstance: m_ObjectHideFlags: 0 @@ -152441,7 +152457,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 0dd0ee481eff66d4da75667b099fca0f, type: 3} m_Name: m_EditorClassIdentifier: - inputType: 0 + inputType: 1 --- !u!114 &1708824042 MonoBehaviour: m_ObjectHideFlags: 0 @@ -164294,7 +164310,7 @@ MonoBehaviour: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1825536551} - m_Enabled: 1 + m_Enabled: 0 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: dba75e1696b242e6a6008ce7b2fb53e4, type: 3} m_Name: @@ -180184,7 +180200,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!224 &2001023440 RectTransform: m_ObjectHideFlags: 0 @@ -189925,6 +189941,7 @@ GameObject: - component: {fileID: 2088812084} - component: {fileID: 2088812086} - component: {fileID: 2088812085} + - component: {fileID: 2088812088} m_Layer: 0 m_Name: PL2_Camera m_TagString: MainCamera @@ -190018,6 +190035,31 @@ Transform: m_Children: [] m_Father: {fileID: 1635561316} m_LocalEulerAnglesHint: {x: 0, y: 270, z: 0} +--- !u!114 &2088812088 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2088812083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2227656a6dd2612449553ba37dd212a1, type: 3} + m_Name: + m_EditorClassIdentifier: + pivot: {fileID: 1521149900} + gameManager: {fileID: 709017262} + shipPlacementCameraPosition: {fileID: 849152746} + mainMenuCameraPosition: {fileID: 1001098613} + gameplayCameraPosition: {fileID: 2103039880} + rotateLeftKey: 12 + rotateRightKey: 13 + rotateSpeed: 90 + returnSpeed: 120 + turnHoldThreshold: 0.3 + cameraMoveDuration: 1 + doubleTapWindow: 0.4 + shipPlacementPivotPoint: {fileID: 30081209} --- !u!1001 &2089067222 PrefabInstance: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/CameraController.cs b/Assets/Scripts/CameraController.cs new file mode 100644 index 00000000..a61521e1 --- /dev/null +++ b/Assets/Scripts/CameraController.cs @@ -0,0 +1,214 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class CameraController : MonoBehaviour +{ + [Header("Refs")] + public Transform pivot; // если не задан — возьмём свой transform + public GameManager gameManager; // чтобы блокировать в UI + + public Transform shipPlacementCameraPosition; + public Transform mainMenuCameraPosition; + public Transform gameplayCameraPosition; + + [Header("Input")] + public ButtonPinMapping rotateLeftKey; + public ButtonPinMapping rotateRightKey; + + [Header("Speeds")] + public float rotateSpeed = 90f; // ручное вращение + public float returnSpeed = 120; // возврат в "домой" + + private Quaternion _homeRotation; + + private float _turnHoldTime = 0f; + [Tooltip("Секунд удержания до включения вращения камеры")] + public float turnHoldThreshold = 0.3f; + + public float cameraMoveDuration = 1.0f; // Время перемещения в секундах + + private int countDown = 0; + private float lastTapTime = 0f; + [Tooltip("Окно времени для распознавания двойного нажатия (сек)")] + public float doubleTapWindow = 0.4f; + private bool isReturning = false; + + [Tooltip("Центр вращения камеры во время расстановки кораблей (пустой GO у поля игрока)")] + [SerializeField] private Transform shipPlacementPivotPoint; + /// Исходная мировая позиция cameraPivot — восстанавливается вне режима расстановки. + private Vector3 _defaultPivotPosition; + + + + public void CaptureHomeNow() => _homeRotation = pivot.rotation; + + void Awake() + { + if (!pivot) pivot = transform; + // по умолчанию "дом" — текущий поворот на старте + _homeRotation = this.transform.rotation; + } + + + void Start() + { + if (pivot != null) + _defaultPivotPosition = pivot.position; + } + + + void Update() + { + + float dir = 0f; + // задержка при расстановке кораблей + if (gameManager.currentState == GameState.ShipPlacement) + { + if (In.GetButton(rotateLeftKey) || In.GetButton(rotateRightKey)) + { + _turnHoldTime += Time.deltaTime; + + if (_turnHoldTime < turnHoldThreshold) return; + + if (In.GetButton(rotateRightKey)) + { + dir -= 1f; + } + + if (In.GetButton(rotateLeftKey)) + { + dir += 1f; + } + + if (dir != 0f && pivot) + pivot.Rotate(Vector3.up, dir * rotateSpeed * Time.deltaTime, Space.World); + + return; + } + else _turnHoldTime = 0f; + } + + + if(gameManager != null && (gameManager.currentInputMode == GameManager.InputMode.UI + || gameManager.currentInputMode == GameManager.InputMode.Settings)) + return; + + // Обнаружение двойного нажатия (time-window) + if (In.GetButtonDown(rotateLeftKey) || In.GetButtonDown(rotateRightKey)) + { + if (Time.time - lastTapTime <= doubleTapWindow) + { + countDown++; + } + else + { + countDown = 1; + } + lastTapTime = Time.time; + if (countDown >= 2) + { + isReturning = true; + countDown = 0; + } + } + + // Если в режиме возврата — двигаем камеру к дому + if (isReturning) + { + pivot.rotation = Quaternion.RotateTowards(pivot.rotation, _homeRotation, returnSpeed * Time.deltaTime); + if (Quaternion.Angle(pivot.rotation, _homeRotation) < 0.01f) + { + // Vector3 dir = pivot.rotation.eulerAngles; + // if (targetCursor != null) targetCursor.SwitchButton(dir); + isReturning = false; + } + } + if (In.GetButton(rotateRightKey)) + { + dir -= 1f; + } + + if (In.GetButton(rotateLeftKey)) + { + dir += 1f; + } + + if (dir != 0f && pivot) + pivot.Rotate(Vector3.up, dir * rotateSpeed * Time.deltaTime, Space.World); + + } + + public void MoveCameraToMainMenu() => MoveCameraTo(mainMenuCameraPosition); + + public void MoveCameraToShipPlacement() => MoveCameraTo(shipPlacementCameraPosition); + + public void MoveCameraToGameplay() => MoveCameraTo(gameplayCameraPosition); + + public void MoveCameraTo(Transform target) + { + if (target != null) + { + StopAllCoroutines(); + StartCoroutine(MoveCameraSmoothly(target)); + } + } + + + + private IEnumerator MoveCameraSmoothly(Transform target) + { + Transform cam = this.transform; + + // Отсоединяем камеру от пивота на время перемещения — + // иначе поворот пивота кнопками во время полёта камеры сдвигает её конечную позицию + cam.SetParent(null); + + Vector3 startPos = cam.position; + Quaternion startRot = cam.rotation; + + Vector3 endPos = target.position; + Quaternion endRot = target.rotation; + + float elapsed = 0f; + + while (elapsed < cameraMoveDuration) + { + float t = elapsed / cameraMoveDuration; + cam.position = Vector3.Lerp(startPos, endPos, t); + cam.rotation = Quaternion.Slerp(startRot, endRot, t); + elapsed += Time.deltaTime; + yield return null; + } + + cam.position = endPos; + cam.rotation = endRot; + + // Сбрасываем пивот и возвращаем камеру обратно как дочерний объект + if (pivot != null) + { + pivot.rotation = Quaternion.identity; + + // Перемещаем пивот: во время расстановки кораблей — к полю игрока, + // в остальных состояниях — обратно на дефолтную позицию + bool isShipPlacement = (target == shipPlacementCameraPosition); + if (isShipPlacement && shipPlacementPivotPoint != null) + pivot.position = shipPlacementPivotPoint.position; + else + pivot.position = _defaultPivotPosition; + + // worldPositionStays: true — локальные координаты пересчитаются под новый пивот + cam.SetParent(pivot, true); + + CaptureHomeNow(); + + } + } + + + + + + + +} diff --git a/Assets/Scripts/CameraPivotController.cs b/Assets/Scripts/CameraPivotController.cs index 879db61f..c19af5fe 100644 --- a/Assets/Scripts/CameraPivotController.cs +++ b/Assets/Scripts/CameraPivotController.cs @@ -1,5 +1,9 @@ using UnityEngine; +/// +/// устаревший функционал, сейчас используется CameraController +/// + public class CameraPivotController : MonoBehaviour { [Header("Refs")] @@ -8,8 +12,8 @@ public class CameraPivotController : MonoBehaviour [Header("Input")] - public ButtonPinMapping rotateLeftKey = ButtonPinMapping.left1; - public ButtonPinMapping rotateRightKey = ButtonPinMapping.right1; + public ButtonPinMapping rotateLeftKey; + public ButtonPinMapping rotateRightKey; [Header("Speeds")] @@ -61,8 +65,8 @@ void Update() return; // Не вращать камеру при расстановке, если игрок не удерживает кнопку поворота - if (targetCursor != null && targetCursor.isPlacingShips && !targetCursor.IsCameraRotMode) - return; + // if (targetCursor != null && targetCursor.isPlacingShips && !targetCursor.IsCameraRotMode) + // return; // Обнаружение двойного нажатия (time-window) if (In.GetButtonDown(rotateLeftKey) || In.GetButtonDown(rotateRightKey)) diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index ccf05db3..caec7f22 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -9,19 +9,9 @@ public class GameManager : MonoBehaviour public event System.Action OnInputModeChanged; private IBotAI bot; - public Transform shipPlacementCameraPosition; - public Transform mainMenuCameraPosition; - public Transform gameplayCameraPosition; - - [Tooltip("Центр вращения камеры во время расстановки кораблей (пустой GO у поля игрока)")] - [SerializeField] private Transform shipPlacementPivotPoint; - /// Исходная мировая позиция cameraPivot — восстанавливается вне режима расстановки. - private Vector3 _defaultPivotPosition; - public bool isReady = false; // Готов ли игрок (расставил ли корабли) public GameManager opponentManager; // Противник (если есть) - - + public CannonBattery battery; public CannonBattery enemyBattery; @@ -42,13 +32,13 @@ public class GameManager : MonoBehaviour public int playerId = 1; // 1 - первый игрок, 2 - второй игрок и т.д. public Camera playerCamera; - public Transform cameraPivot; - + public int currentBotLevel = 0; public EnemyManager enemyManager; public FortInitializer fortInitializer; - + + public CameraController cameraController; [Header("Время бездействия")] [SerializeField] float inactionTimer = 360f; @@ -100,13 +90,12 @@ public enum BotDifficulty public BotDifficulty botDifficulty = BotDifficulty.Level1; - public float cameraMoveDuration = 1.0f; // Время перемещения в секундах + void Start() { // Запоминаем исходную позицию пивота (центр карты) - if (cameraPivot != null) - _defaultPivotPosition = cameraPivot.position; + var player = GetComponentInParent(); if (player != null) @@ -198,8 +187,8 @@ public void HideBattlePause() battlePauseShown = false; battleIdleTimer = 0f; uiManager.ShowOverlay("BattlePause", false); - // Восстанавливаем режим ввода: если ход игрока — Battle, иначе UI - SetInputMode(isPlayerTurn ? InputMode.Battle : InputMode.UI); + + SetInputMode(InputMode.Battle); } // ===== Панель правил ===== @@ -374,15 +363,15 @@ public void SetState(GameState newState) switch (newState) { case GameState.MainMenu: - MoveCameraTo(mainMenuCameraPosition); + cameraController.MoveCameraToMainMenu(); break; case GameState.ShipPlacement: - MoveCameraTo(shipPlacementCameraPosition); + cameraController.MoveCameraToShipPlacement(); break; case GameState.Playing: - MoveCameraTo(gameplayCameraPosition); + cameraController.MoveCameraToGameplay(); break; } } @@ -497,7 +486,7 @@ public void StartBattle() SetState(GameState.Playing); } - + SetInputMode(InputMode.Battle); StartPlayerTurn(); } @@ -509,7 +498,7 @@ public void InitTargetCursor(bool isPlacingShips = false) return; targetCursorInstance = Instantiate(targetCursorPrefab); TargetCursor cursorScript = targetCursorInstance.GetComponent(); - cursorScript.Initialize(this, playerId, isPlacingShips); + cursorScript.Initialize(this, cameraController.pivot, playerId, isPlacingShips); targetCursorInstance.SetActive(isPlacingShips); // по дефолту скрыт } @@ -1066,11 +1055,12 @@ private void InitBot() public void StartPlayerTurn() { + isPlayerTurn = true; uiManager.ShowTimer(true); if (targetCursorInstance != null) targetCursorInstance.SetActive(true); - SetInputMode(InputMode.Battle); + } public void EndPlayerTurn() @@ -1140,69 +1130,10 @@ public IEnumerator BotTurn() } - public void MoveCameraTo(Transform target) - { - if (playerCamera != null && target != null) - { - StopAllCoroutines(); - StartCoroutine(MoveCameraSmoothly(target)); - } - } - private IEnumerator MoveCameraSmoothly(Transform target) - { - Transform cam = playerCamera.transform; - // Отсоединяем камеру от пивота на время перемещения — - // иначе поворот пивота кнопками во время полёта камеры сдвигает её конечную позицию - cam.SetParent(null); - - Vector3 startPos = cam.position; - Quaternion startRot = cam.rotation; - - Vector3 endPos = target.position; - Quaternion endRot = target.rotation; - - float elapsed = 0f; - - while (elapsed < cameraMoveDuration) - { - float t = elapsed / cameraMoveDuration; - cam.position = Vector3.Lerp(startPos, endPos, t); - cam.rotation = Quaternion.Slerp(startRot, endRot, t); - elapsed += Time.deltaTime; - yield return null; - } - - cam.position = endPos; - cam.rotation = endRot; - - // Сбрасываем пивот и возвращаем камеру обратно как дочерний объект - if (cameraPivot != null) - { - cameraPivot.rotation = Quaternion.identity; - - // Перемещаем пивот: во время расстановки кораблей — к полю игрока, - // в остальных состояниях — обратно на дефолтную позицию - bool isShipPlacement = (target == shipPlacementCameraPosition); - if (isShipPlacement && shipPlacementPivotPoint != null) - cameraPivot.position = shipPlacementPivotPoint.position; - else - cameraPivot.position = _defaultPivotPosition; - - // worldPositionStays: true — локальные координаты пересчитаются под новый пивот - cam.SetParent(cameraPivot, true); - - // Фиксируем новый "дом" и синхронизируем квадрант курсора - var camCtrl = cameraPivot.GetComponent(); - if (camCtrl != null) - { - camCtrl.CaptureHomeNow(); - camCtrl.TargetCursor?.SwitchButton(cameraPivot.rotation.eulerAngles); - } - } - } + /// /// Сбрасывает игровое состояние - очищает поля, удаляет курсор, сбрасывает переменные diff --git a/Assets/Scripts/PlayerCursorUI.cs b/Assets/Scripts/PlayerCursorUI.cs index 5c282c8d..7fa37d6c 100644 --- a/Assets/Scripts/PlayerCursorUI.cs +++ b/Assets/Scripts/PlayerCursorUI.cs @@ -17,6 +17,10 @@ public class PlayerCursorUI : MonoBehaviour private ButtonPinMapping rightKey; private ButtonPinMapping selectKey; + // дублирующие кнопки для перключения влево вправо по UI + private ButtonPinMapping leftKey2; + private ButtonPinMapping rightKey2; + private bool useJoystick = false; // Cache UIManager for active panel tracking @@ -63,10 +67,12 @@ void BindControls() { if (playerId == 1) { - upKey = ButtonPinMapping.up1; + upKey = ButtonPinMapping.up1 ; downKey = ButtonPinMapping.down1; leftKey = ButtonPinMapping.left1; rightKey = ButtonPinMapping.right1; + leftKey2 = ButtonPinMapping.turnLeft1; + rightKey2 = ButtonPinMapping.turnRight1; selectKey = ButtonPinMapping.action1; } else @@ -75,6 +81,8 @@ void BindControls() downKey = ButtonPinMapping.down2; leftKey = ButtonPinMapping.left2; rightKey = ButtonPinMapping.right2; + leftKey2 = ButtonPinMapping.turnLeft2; + rightKey2 = ButtonPinMapping.turnRight2; selectKey = ButtonPinMapping.action2; } } @@ -188,7 +196,7 @@ void Update() gridRow = (gridRow + 1) % grid.RowCount; moved = true; } - if (In.GetButtonDown(leftKey)) + if (In.GetButtonDown(leftKey) || In.GetButtonDown(leftKey2)) { bool overlayActive = uiManager != null && uiManager.GetActiveOverlay() != null; if (gameManager.currentState == GameState.ShipPlacement && !overlayActive) @@ -200,7 +208,7 @@ void Update() int cols = grid.ColCount(gridRow); if (cols > 0) { gridCol = (gridCol - 1 + cols) % cols; moved = true; } } - if (In.GetButtonDown(rightKey)) + if (In.GetButtonDown(rightKey) || In.GetButtonDown(rightKey2)) { int cols = grid.ColCount(gridRow); if (cols > 0) { gridCol = (gridCol + 1) % cols; moved = true; } @@ -219,6 +227,12 @@ void Update() } else { + if (gameManager.currentState != GameState.ShipPlacement) + { + if(In.GetButtonDown(leftKey2)){MoveNext(-1);moved = true;} + if(In.GetButtonDown(rightKey2)){MoveNext(1);moved = true;} + } + // --- Старая линейная навигация (все экраны без ButtonGridLayout) --- if (In.GetButtonDown(upKey)) { MoveNext(-1); moved = true; } if (In.GetButtonDown(downKey)) { MoveNext(1); moved = true; } diff --git a/Assets/Scripts/ShipsMuved.cs b/Assets/Scripts/ShipsMuved.cs index b6adabb6..df10de6e 100644 --- a/Assets/Scripts/ShipsMuved.cs +++ b/Assets/Scripts/ShipsMuved.cs @@ -77,7 +77,9 @@ public void Sink() int index = Random.Range(0, Mathf.Min(sinkEndOffsets.Length, sinkEndRotationsEuler.Length)); - sinkTargetPosition = sinkStartPosition + sinkEndOffsets[index]; + Vector3 scaledOffset = Vector3.Scale(sinkEndOffsets[index], transform.localScale); + sinkTargetPosition = sinkStartPosition + scaledOffset; + sinkTargetRotation = sinkStartRotation * Quaternion.Euler(sinkEndRotationsEuler[index]); } diff --git a/Assets/Scripts/TargetCursor.cs b/Assets/Scripts/TargetCursor.cs index 972cd905..4ac1b987 100644 --- a/Assets/Scripts/TargetCursor.cs +++ b/Assets/Scripts/TargetCursor.cs @@ -1,3 +1,4 @@ +using System; using UnityEngine; public class TargetCursor : MonoBehaviour @@ -5,6 +6,8 @@ public class TargetCursor : MonoBehaviour public GameManager gameManager; public GameObject cursorVisual; public CursorAnimator cursorAnimator; + + private CameraController cameraController; private bool isShootingInProgress = false; public bool isPlacingShips = false; @@ -16,21 +19,9 @@ public class TargetCursor : MonoBehaviour private int height; private Direction currentDirection = Direction.Right; - - // Óäåðæàíèå êíîïîê ïîâîðîòà â ðåæèìå ðàññòàíîâêè: - // êîðîòêîå íàæàòèå (< ïîðîãà) — ïîâîðîò êîðàáëÿ - // óäåðæàíèå (>= ïîðîãà) — âðàùåíèå êàìåðû - private float _turnHoldTime = 0f; - [Tooltip("Ñåêóíä óäåðæàíèÿ äî âêëþ÷åíèÿ âðàùåíèÿ êàìåðû")] - public float turnHoldThreshold = 0.3f; - private bool _cameraRotMode = false; - - /// - /// True êîãäà êíîïêà ïîâîðîòà óäåðæèâàåòñÿ äîñòàòî÷íî äîëãî — - /// CameraPivotController äîëæåí âðàùàòü êàìåðó. - /// - public bool IsCameraRotMode => isPlacingShips && _cameraRotMode; - + + + // áèíäèíã êíîïîê private PlayerKeySet player1Keys = new PlayerKeySet { Up = ButtonPinMapping.up1, @@ -95,12 +86,10 @@ private ButtonPinMapping GetKeyForDirection(int dx, int dy) public Transform cameraPivot; - public float rotateSpeed = 90f; private int playerId; - private int enemyId; - public void Initialize(GameManager gm, int playerId = 1, bool isPlacingShips = false) + public void Initialize(GameManager gm, Transform pivotTransform, int playerId = 1, bool isPlacingShips = false) { this.isPlacingShips = isPlacingShips; gameManager = gm; @@ -118,31 +107,10 @@ public void Initialize(GameManager gm, int playerId = 1, bool isPlacingShips = f BindKeys(playerId); - if (cameraPivot == null) - { - cameraPivot = gameManager.cameraPivot; - // SetParent ÍÅ äåëàåì çäåñü — ýòèì óïðàâëÿåò MoveCameraSmoothly - // ÷òîáû íå êîíôëèêòîâàòü ñ êîðóòèíîé ïåðåìåùåíèÿ êàìåðû - } - - // âñåãäà íàñòðàèâàåì êîíòðîëëåð - var camCtrl = cameraPivot.GetComponent(); - if (camCtrl == null) camCtrl = cameraPivot.gameObject.AddComponent(); - camCtrl.Setup( - gameManager, - cameraPivot, - turnLeftKey, - turnRightKey, - rotateSpeed, - this // àðãóìåíò åñòü â ñèãíàòóðå, íî âíóòðè íå èñïîëüçóåòñÿ - ); - - enemyId = gameManager.opponentManager.playerId; - - this.playerId = playerId; - - Debug.Log("Ðîäèëñÿ"); + cameraPivot = pivotTransform; + + UpdateCursorPosition(); // Ìãíîâåííî âûñòàâèòü ñîñòîÿíèå êóðñîðà ïîä ñòàðòîâîé ïîçèöèåé @@ -172,15 +140,15 @@ public void SwitchButton(Vector3 rotate) float y = rotate.y; if (y > 180) y -= 360; - - Debug.Log($"Y rotation = {y}"); - + if (y >= -45 && y < 45) cameraQuadrant = 0; // âïåð¸ä else if (y >= 45 && y < 135) cameraQuadrant = 1; // âïðàâî else if (y >= 135 || y < -135) cameraQuadrant = 2; // íàçàä else cameraQuadrant = 3; // âëåâî } + + void Update() { if (isShootingInProgress) return; @@ -191,52 +159,31 @@ void Update() // --- Ïîâîðîò êîðàáëÿ / êàìåðû â ðåæèìå ðàññòàíîâêè --- if (isPlacingShips) { - bool leftHeld = In.GetButton(turnLeftKey); - bool rightHeld = In.GetButton(turnRightKey); - bool leftUp = In.GetButtonUp(turnLeftKey); - bool rightUp = In.GetButtonUp(turnRightKey); - - // Ïîêà êíîïêà çàæàòà — êîïèì âðåìÿ - if (leftHeld || rightHeld) - { - _turnHoldTime += Time.deltaTime; - if (_turnHoldTime >= turnHoldThreshold) - _cameraRotMode = true; - } - // Êíîïêà îòïóùåíà - else if (leftUp || rightUp) - { - if (_cameraRotMode) - { - if (cameraPivot != null) - SwitchButton(cameraPivot.eulerAngles); - } - else - { - if (leftUp) - currentDirection = (Direction)(((int)currentDirection + 3) % 4); - else - currentDirection = (Direction)(((int)currentDirection + 1) % 4); - UpdateCursorPosition(); - } - - _turnHoldTime = 0f; - _cameraRotMode = false; - } - else - { - // Íè îäíà êíîïêà íå çàæàòà è íå îòïóñêàëàñü â ýòîì êàäðå — - // ñòðàõîâî÷íûé ñáðîñ íà ñëó÷àé åñëè GetButtonUp áûë ïðîïóùåí - _turnHoldTime = 0f; - _cameraRotMode = false; - } + if (In.GetButtonDown(turnLeftKey)) + currentDirection = (Direction)(((int)currentDirection + 3) % 4); + else if (In.GetButtonDown(turnRightKey)) + currentDirection = (Direction)(((int)currentDirection + 1) % 4); + UpdateCursorPosition(); } + // if (In.GetButtonUp(turnRightKey) || In.GetButtonUp(turnLeftKey)) SwitchButton(cameraPivot.rotation.eulerAngles); + // + // --- Òîëüêî â ñâîé õîä --- if (!isPlacingShips && (gameManager.currentState != GameState.Playing || !gameManager.isPlayerTurn)) return; // --- Äâèæåíèå êóðñîðà --- + + bool anyMove = In.GetButtonDown(activeKeys.Up) || + In.GetButtonDown(activeKeys.Down) || + In.GetButtonDown(activeKeys.Left) || + In.GetButtonDown(activeKeys.Right); + + if (anyMove) + SwitchButton(cameraPivot.rotation.eulerAngles); // ? + + bool moved = false; if (In.GetButtonDown(GetKeyForDirection( 0, -1))) { MoveCursor( 0, -1); moved = true; } if (In.GetButtonDown(GetKeyForDirection( 0, 1))) { MoveCursor( 0, 1); moved = true; } @@ -326,10 +273,7 @@ void TryPlaceCurrentShip() if (placed) gameManager.AddShipPlayer(); } - void RotateDirection() - { - currentDirection = (Direction)(((int)currentDirection + 1) % 4); - } + void MoveCursor(int dx, int dy) {