/
arti4
/
Diplom
Обзор
Документация
Войти
/
arti4
/
Diplom
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Scripts/Other/Map/BigMapController.cs
682 строки
20 KB
arti4
Загрузка всех скриптов
17 май 2026, 09:08
Верифицирован
17 май 2026, 09:08
cc2e1cd
Код
Авторство
О чём код?
using UnityEngine; using System.Collections.Generic; public class BigMapController : MonoBehaviour { [Header("Слои")] [SerializeField] private string mapEnemyArrowLayer = "MapEnemyArrow"; [SerializeField] private string mapPlayerArrowLayer = "MapPlayerArrow"; [Header("Префабы")] [SerializeField] private GameObject bigMapPlayerArrowPrefab; [SerializeField] private GameObject bigMapEnemyArrowPrefab; [Header("Настройки камеры")] [SerializeField] private float defaultOrthographicSize = 400f; [SerializeField] private float minOrthographicSize = 10f; [SerializeField] private float maxOrthographicSize = 100f; [SerializeField] private float zoomSpeed = 5f; [SerializeField] private float panSpeed = 0.1f; [SerializeField] private float initialCameraHeight = 500f; [Header("Настройки стрелок")] [SerializeField] private float arrowHeight = 10f; [SerializeField] private float arrowScaleFactor = 1f; [Header("Настройки мира")] [SerializeField] private float worldMapSize = 1000f; [Header("Ссылки")] [SerializeField] private MiniMapController miniMapController; [Header("Маркеры")] [SerializeField] private GameObject bigMapMarkerContainer; [Header("Маркеры гонок")] [SerializeField] private string mapRaceLayer = "MapEnemyArrow"; [Header("Настройки масштабирования")] [SerializeField] private float minArrowScale = 0.5f; [SerializeField] private float maxArrowScale = 2f; [SerializeField] private AnimationCurve scaleCurve = AnimationCurve.Linear(0, 0, 1, 1); private List<RaceMarker> raceMarkers = new List<RaceMarker>(); private Camera bigMapCamera; private Transform playerTransform; private GameObject playerArrow; private List<GameObject> enemyArrows; private Transform arrowsContainer; private float currentArrowScale = 1f; public float CurrentArrowScale => currentArrowScale; private bool isDragging = false; private Vector3 dragStartMousePosition; private Vector3 dragStartCameraPosition; private bool isInitialized = false; private float currentOrthographicSize; void Start() { Invoke("ForceRefreshRaceMarkers", 0.5f); } void Awake() { bigMapCamera = GetComponent<Camera>(); enemyArrows = new List<GameObject>(); currentOrthographicSize = defaultOrthographicSize; } void OnEnable() { ShowAllRaceMarkers(); ForceUpdateMarkersScale(); ForceRegisterAllMarkersFromContainer(); ForceRefreshRaceMarkers(); SynchronizeAllMarkers(); } void ShowAllRaceMarkers() { foreach (RaceMarker marker in raceMarkers) { if (marker != null) { var method = marker.GetType().GetMethod("SetBigMapMarkerVisible"); if (method != null) { method.Invoke(marker, new object[] { true }); } } } } void OnDisable() { HideAllRaceMarkers(); } void HideAllRaceMarkers() { foreach (RaceMarker marker in raceMarkers) { if (marker != null) { var method = marker.GetType().GetMethod("SetBigMapMarkerVisible"); if (method != null) { method.Invoke(marker, new object[] { false }); } } } } public Transform GetPlayerTransform() { if (playerTransform != null) return playerTransform; if (miniMapController != null) { playerTransform = miniMapController.GetPlayerTransform(); if (playerTransform != null) return playerTransform; } if (miniMapController == null) { miniMapController = FindFirstObjectByType<MiniMapController>(); if (miniMapController != null) { playerTransform = miniMapController.GetPlayerTransform(); return playerTransform; } } GameObject player = GameObject.FindGameObjectWithTag("Player"); if (player != null) { playerTransform = player.transform; return playerTransform; } return null; } public void InitializeBigMap() { CleanupBigMap(); playerTransform = GetPlayerTransform(); if (playerTransform == null) { Debug.LogWarning("Трансформ игрока еще не создан. Большая карта будет инициализирована при следующем обновлении."); return; } SetupCamera(); CreateArrowsContainer(); CreatePlayerArrow(); CreateEnemyArrows(); UpdateArrowsPosition(); UpdateArrowsScale(); isInitialized = true; } public void UpdateRaceMarkersScale() { } void SetupCamera() { if (playerTransform != null && bigMapCamera != null) { Vector3 playerPos = playerTransform.position; transform.position = new Vector3(playerPos.x, initialCameraHeight, playerPos.z); transform.rotation = Quaternion.Euler(90f, 0f, 0f); bigMapCamera.orthographic = true; bigMapCamera.orthographicSize = currentOrthographicSize; SetupCameraLayers(); } } void SetupCameraLayers() { if (bigMapCamera == null) return; int enemyLayer = LayerMask.NameToLayer(mapEnemyArrowLayer); int playerLayer = LayerMask.NameToLayer(mapPlayerArrowLayer); } void CreatePlayerArrow() { if (bigMapPlayerArrowPrefab == null || arrowsContainer == null) { Debug.LogWarning("Префаб стрелки игрока или контейнер не назначен!"); return; } GameObject arrowObj = Instantiate(bigMapPlayerArrowPrefab, arrowsContainer); arrowObj.name = "BigMapPlayerArrow"; playerArrow = arrowObj; int playerLayer = LayerMask.NameToLayer(mapPlayerArrowLayer); if (playerLayer != -1) { SetLayerRecursively(arrowObj.transform, playerLayer); } UpdatePlayerArrowPosition(); } void CreateEnemyArrows() { if (bigMapEnemyArrowPrefab == null || arrowsContainer == null) { Debug.LogWarning("Префаб стрелки врага или контейнер не назначен!"); return; } List<Transform> enemies = miniMapController.GetEnemiesList(); if (enemies == null) { Debug.LogWarning("Список врагов пуст!"); return; } int enemyLayer = LayerMask.NameToLayer(mapEnemyArrowLayer); if (enemyLayer == -1) { Debug.LogWarning($"Слой {mapEnemyArrowLayer} не найден!"); return; } foreach (Transform enemy in enemies) { if (enemy == null) continue; GameObject arrowObj = Instantiate(bigMapEnemyArrowPrefab, arrowsContainer); arrowObj.name = $"BigMapEnemyArrow_{enemy.name}"; SetLayerRecursively(arrowObj.transform, enemyLayer); Renderer renderer = arrowObj.GetComponent<Renderer>(); if (renderer != null) { renderer.material.color = Color.red; } enemyArrows.Add(arrowObj); } } void SetLayerRecursively(Transform obj, int layerIndex) { obj.gameObject.layer = layerIndex; foreach (Transform child in obj) { SetLayerRecursively(child, layerIndex); } } void Update() { if (!isInitialized) { if (playerTransform == null) { playerTransform = GetPlayerTransform(); } if (playerTransform != null) { InitializeBigMap(); } return; } if (!gameObject.activeInHierarchy) return; HandleZoom(); HandlePan(); UpdateArrowsPosition(); } void HandleZoom() { float scroll = Input.GetAxis("Mouse ScrollWheel"); if (Mathf.Abs(scroll) > 0.01f) { currentOrthographicSize -= scroll * zoomSpeed; currentOrthographicSize = Mathf.Clamp(currentOrthographicSize, minOrthographicSize, maxOrthographicSize); if (bigMapCamera != null) { bigMapCamera.orthographicSize = currentOrthographicSize; } UpdateArrowsScale(); } } void HandlePan() { if (Input.GetMouseButtonDown(0)) { isDragging = true; dragStartMousePosition = Input.mousePosition; dragStartCameraPosition = transform.position; } if (Input.GetMouseButtonUp(0)) { isDragging = false; } if (isDragging && Input.GetMouseButton(0)) { Vector3 currentMousePos = Input.mousePosition; Vector3 mouseDelta = currentMousePos - dragStartMousePosition; Vector3 cameraMove = new Vector3(-mouseDelta.x, 0, -mouseDelta.y) * panSpeed * (currentOrthographicSize / defaultOrthographicSize); transform.Translate(cameraMove, Space.World); LimitCameraPosition(); dragStartMousePosition = currentMousePos; } } void UpdateArrowsPosition() { if (playerTransform == null || playerArrow == null) return; UpdatePlayerArrowPosition(); List<Transform> enemies = miniMapController.GetEnemiesList(); if (enemies == null || enemies.Count != enemyArrows.Count) return; for (int i = 0; i < enemies.Count; i++) { if (enemies[i] == null || i >= enemyArrows.Count || enemyArrows[i] == null) continue; UpdateEnemyArrowPosition(enemies[i], enemyArrows[i]); } } void UpdatePlayerArrowPosition() { if (playerTransform == null || playerArrow == null) return; Vector3 playerWorldPos = playerTransform.position; playerArrow.transform.position = new Vector3( playerWorldPos.x, arrowHeight, playerWorldPos.z ); playerArrow.transform.rotation = Quaternion.Euler(90f, playerTransform.eulerAngles.y, 0f); } void UpdateEnemyArrowPosition(Transform enemy, GameObject arrow) { if (enemy == null || arrow == null) return; Vector3 enemyWorldPos = enemy.position; arrow.transform.position = new Vector3( enemyWorldPos.x, arrowHeight, enemyWorldPos.z ); arrow.transform.rotation = Quaternion.Euler(90f, enemy.eulerAngles.y, 0f); } void UpdateArrowsScale() { if (!isInitialized) return; currentArrowScale = CalculateArrowScale(currentOrthographicSize); if (playerArrow != null) { playerArrow.transform.localScale = Vector3.one * currentArrowScale * 7f; } foreach (GameObject enemyArrow in enemyArrows) { if (enemyArrow != null) { enemyArrow.transform.localScale = Vector3.one * currentArrowScale * 7f; } } foreach (RaceMarker raceMarker in raceMarkers) { if (raceMarker != null) { raceMarker.UpdateBigMapMarkerScale(); } } } public void ForceUpdateMarkersScale() { if (!isInitialized) { currentArrowScale = CalculateArrowScale(defaultOrthographicSize); } else { UpdateArrowsScale(); } } public void ForceFindAndRegisterMarkers() { Transform markersContainer = GetBigMapMarkerContainer(); if (markersContainer != null) { RaceMarker[] markersInContainer = markersContainer.GetComponentsInChildren<RaceMarker>(); foreach (RaceMarker marker in markersInContainer) { if (marker != null && !raceMarkers.Contains(marker)) { raceMarkers.Add(marker); marker.UpdateBigMapMarkerScale(); marker.SetBigMapMarkerVisible(true); } } } RaceMarker[] allMarkers = FindObjectsByType<RaceMarker>(FindObjectsSortMode.None); foreach (RaceMarker marker in allMarkers) { if (marker != null && !raceMarkers.Contains(marker)) { raceMarkers.Add(marker); } } } public void CleanupBigMap() { if (playerArrow != null) { Destroy(playerArrow); playerArrow = null; } foreach (GameObject arrow in enemyArrows) { if (arrow != null) { Destroy(arrow); } } enemyArrows.Clear(); if (arrowsContainer != null) { foreach (Transform child in arrowsContainer) { Destroy(child.gameObject); } } if (bigMapCamera != null) { bigMapCamera.orthographicSize = defaultOrthographicSize; } isInitialized = false; } public void ResetMapPosition() { if (!isInitialized) return; if (playerTransform != null) { Vector3 playerPos = playerTransform.position; transform.position = new Vector3(playerPos.x, initialCameraHeight, playerPos.z); currentOrthographicSize = defaultOrthographicSize; if (bigMapCamera != null) { bigMapCamera.orthographicSize = currentOrthographicSize; } UpdateArrowsScale(); } } public void CenterOnPlayer() { if (!isInitialized) return; if (playerTransform == null) return; Vector3 playerPos = playerTransform.position; transform.position = new Vector3(playerPos.x, initialCameraHeight, playerPos.z); } void LimitCameraPosition() { Vector3 pos = transform.position; float halfMapSize = worldMapSize / 2f; pos.x = Mathf.Clamp(pos.x, -halfMapSize, halfMapSize); pos.z = Mathf.Clamp(pos.z, -halfMapSize, halfMapSize); transform.position = pos; } public void ForceRefreshRaceMarkers() { Transform container = GetBigMapMarkerContainer(); if (container != null) { RaceMarker[] markersInContainer = container.GetComponentsInChildren<RaceMarker>(true); foreach (RaceMarker marker in markersInContainer) { if (marker != null && !raceMarkers.Contains(marker)) { raceMarkers.Add(marker); marker.UpdateBigMapMarkerScale(); marker.SetBigMapMarkerVisible(true); } } } RaceMarker[] allMarkers = FindObjectsByType<RaceMarker>(FindObjectsSortMode.None); foreach (RaceMarker marker in allMarkers) { if (marker != null && !raceMarkers.Contains(marker)) { raceMarkers.Add(marker); } } } public float CalculateArrowScale(float orthographicSize) { float t = (orthographicSize - minOrthographicSize) / (maxOrthographicSize - minOrthographicSize); t = Mathf.Clamp01(t); float curveValue = scaleCurve.Evaluate(t); float scale = Mathf.Lerp(minArrowScale, maxArrowScale, curveValue) * arrowScaleFactor; return scale; } public void SynchronizeAllMarkers() { Transform container = GetBigMapMarkerContainer(); if (container == null) { Debug.LogError("Не удалось получить контейнер маркеров"); return; } raceMarkers.Clear(); RaceMarker[] markersInContainer = container.GetComponentsInChildren<RaceMarker>(true); foreach (RaceMarker marker in markersInContainer) { if (marker != null && !raceMarkers.Contains(marker)) { raceMarkers.Add(marker); marker.UpdateBigMapMarkerScale(); marker.SetBigMapMarkerVisible(gameObject.activeInHierarchy); } } } void CreateArrowsContainer() { arrowsContainer = MarkerContainersManager.Instance.GetBigMapArrowsContainer(); } public Transform GetBigMapMarkerContainer() { return MarkerContainersManager.Instance.GetBigMapMarkersContainer(); } public void ForceRegisterAllMarkersFromContainer() { Transform container = GetBigMapMarkerContainer(); if (container == null) { Debug.LogError("Не удалось получить контейнер маркеров большой карты"); return; } RaceMarker[] markersInContainer = container.GetComponentsInChildren<RaceMarker>(true); int registeredCount = 0; foreach (RaceMarker marker in markersInContainer) { if (marker != null && !raceMarkers.Contains(marker)) { raceMarkers.Add(marker); marker.UpdateBigMapMarkerScale(); marker.SetBigMapMarkerVisible(true); registeredCount++; } } } public void RegisterRaceMarker(RaceMarker raceMarker) { if (raceMarker == null) { Debug.LogWarning("Попытка зарегистрировать null маркер"); return; } if (raceMarkers.Contains(raceMarker)) { return; } raceMarkers.Add(raceMarker); raceMarker.UpdateBigMapMarkerScale(); raceMarker.SetBigMapMarkerVisible(true); } public void UnregisterRaceMarker(RaceMarker raceMarker) { if (raceMarkers.Contains(raceMarker)) { raceMarkers.Remove(raceMarker); } } public Vector3 GetWorldPositionUnderCursor() { if (bigMapCamera == null || !bigMapCamera.gameObject.activeInHierarchy) return Vector3.zero; Ray ray = bigMapCamera.ScreenPointToRay(Input.mousePosition); Plane groundPlane = new Plane(Vector3.up, Vector3.zero); float distance; if (groundPlane.Raycast(ray, out distance)) { Vector3 point = ray.GetPoint(distance); RaycastHit hit; Vector3 rayStart = point + Vector3.up * 1000f; if (Physics.Raycast(rayStart, Vector3.down, out hit, Mathf.Infinity)) { point.y = hit.point.y; } return point; } return Vector3.zero; } }