This commit is contained in:
yastreb 2026-05-15 13:02:11 +03:00
parent 9c0b78ead5
commit 9983e2a86c
13 changed files with 378 additions and 224 deletions

View File

@ -6,12 +6,15 @@
<file url="file://$PROJECT_DIR$/Assets/Scripts/GameManager.cs" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/Assets/Scripts/GamePole.cs" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/Assets/Scripts/Pirate/FortInitializer.cs" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/Assets/Scripts/PlayerCursorUI.cs" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/Assets/Scripts/Settings/SettingOption.cs" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/Assets/Scripts/Settings/SettingsData.cs" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/Assets/Scripts/Settings/SettingsInput.cs" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/Assets/Scripts/ShipsMuved.cs" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/Assets/Scripts/TargetCursor.cs" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/Assets/Scripts/Tests/TestHandShake.cs" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/Assets/Scripts/UI/AdminContactsController.cs" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/Assets/Scripts/UI/Animation/SimpleCharacterExample.cs" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/Assets/Scripts/UI/Animation/UIAnimatedMover.cs" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/Assets/Scripts/UI/Coin/Coin.cs" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/Assets/Scripts/UI/Coin/CoinUI.cs" charset="windows-1251" />

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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

View File

@ -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;
/// <summary>Исходная мировая позиция cameraPivot — восстанавливается вне режима расстановки.</summary>
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();
}
}
}

View File

@ -1,5 +1,9 @@
using UnityEngine;
/// <summary>
/// устаревший функционал, сейчас используется CameraController
/// </summary>
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))

View File

@ -9,19 +9,9 @@ public class GameManager : MonoBehaviour
public event System.Action<InputMode> OnInputModeChanged;
private IBotAI bot;
public Transform shipPlacementCameraPosition;
public Transform mainMenuCameraPosition;
public Transform gameplayCameraPosition;
[Tooltip("Центр вращения камеры во время расстановки кораблей (пустой GO у поля игрока)")]
[SerializeField] private Transform shipPlacementPivotPoint;
/// <summary>Исходная мировая позиция cameraPivot — восстанавливается вне режима расстановки.</summary>
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<Player>();
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<TargetCursor>();
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<CameraPivotController>();
if (camCtrl != null)
{
camCtrl.CaptureHomeNow();
camCtrl.TargetCursor?.SwitchButton(cameraPivot.rotation.eulerAngles);
}
}
}
/// <summary>
/// Сбрасывает игровое состояние - очищает поля, удаляет курсор, сбрасывает переменные

View File

@ -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; }

View File

@ -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]);
}

View File

@ -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;
/// <summary>
/// True êîãäà êíîïêà ïîâîðîòà óäåðæèâàåòñÿ äîñòàòî÷íî äîëãî —
/// CameraPivotController äîëæåí âðàùàòü êàìåðó.
/// </summary>
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<CameraPivotController>();
if (camCtrl == null) camCtrl = cameraPivot.gameObject.AddComponent<CameraPivotController>();
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)
{