/
Tracnuk
/
Test_9
Обзор
Документация
Войти
/
Tracnuk
/
Test_9
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Assets/Scripts/UnitController.cs
436 строк
13 KB
Tracnuk
add moving units with color path and choosing them with color helps(not working Ai enemy)
25 окт 2025, 11:43
25 окт 2025, 11:43
eb318db
Код
Авторство
О чём код?
using UnityEngine; using System.Collections; using System.Collections.Generic; using UnityEngine.Tilemaps; public class UnitController : MonoBehaviour { [Header("Settings")] public float moveSpeed = 3f; public LayerMask wallLayer; [Header("Sprites for Directions")] public Sprite upSprite; public Sprite downSprite; public Sprite rightSprite; public Sprite leftSprite; [Header("Tilemap Reference")] public Tilemap floorTilemap; [Header("Path Visualization")] public GameObject pathIndicatorPrefab; public Color pathColor = Color.blue; public Color blockedPathColor = Color.red; public Color selectedColor = Color.green; public Color canSelectColor = Color.yellow; public Color alreadyMovedColor = Color.magenta; // 🟣 Фиолетовый для походивших private bool isMoving = false; private SpriteRenderer spriteRenderer; private bool isSelected = false; private List<Vector3> pathPoints = new List<Vector3>(); private int currentPathIndex = 0; private bool playerControlEnabled = false; private List<GameObject> pathIndicators = new List<GameObject>(); private LineRenderer pathLineRenderer; void Start() { spriteRenderer = GetComponent<SpriteRenderer>(); pathLineRenderer = gameObject.AddComponent<LineRenderer>(); pathLineRenderer.material = new Material(Shader.Find("Sprites/Default")); pathLineRenderer.startColor = pathColor; pathLineRenderer.endColor = pathColor; pathLineRenderer.startWidth = 0.1f; pathLineRenderer.endWidth = 0.1f; pathLineRenderer.positionCount = 0; SnapToGrid(); SetNormalColor(); } void OnMouseEnter() { if (TurnManager.Instance.currentState == TurnManager.TurnState.SelectingUnit) { if (isSelected) { // Уже выбран - остается зеленым spriteRenderer.color = selectedColor; } else if (HasAlreadyMoved()) { // Уже походил - фиолетовый 🟣 spriteRenderer.color = alreadyMovedColor; } else { // Можно выбрать - желтый 🟡 spriteRenderer.color = canSelectColor; } } } void OnMouseExit() { if (!isSelected) { SetNormalColor(); } } void OnMouseDown() { if (TurnManager.Instance.currentState == TurnManager.TurnState.SelectingUnit) { TurnManager.Instance.OnUnitClicked(this); } } void Update() { if (isSelected && playerControlEnabled && !isMoving) { Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition); Vector3Int targetCell = floorTilemap.WorldToCell(mouseWorldPos); Vector3 targetWorldPos = floorTilemap.GetCellCenterWorld(targetCell); ShowPathPreview(targetWorldPos); if (Input.GetMouseButtonDown(0)) { RaycastHit2D hitUnit = Physics2D.Raycast(mouseWorldPos, Vector2.zero); if (hitUnit.collider != null && hitUnit.collider.GetComponent<UnitController>() != null) return; if (Physics2D.OverlapPoint(targetWorldPos, wallLayer)) return; Vector3 currentGridPos = GetCurrentGridPosition(); if (targetWorldPos == currentGridPos) return; if (!floorTilemap.HasTile(targetCell)) return; FindStraightPath(targetWorldPos); } if (Input.GetMouseButtonDown(1)) { Deselect(); } } else { ClearPathPreview(); } // Обновляем цвет в реальном времени (на случай если статус изменился) UpdateVisualState(); } // Проверяем походил ли уже этот юнит bool HasAlreadyMoved() { return TurnManager.Instance != null && TurnManager.Instance.HasUnitMoved(this); } // Обновляем визуальное состояние юнита void UpdateVisualState() { if (!isSelected && !IsMouseOver()) { if (HasAlreadyMoved()) { spriteRenderer.color = alreadyMovedColor; } else { SetNormalColor(); } } } // Проверяем находится ли мышь над объектом bool IsMouseOver() { RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero); return hit.collider != null && hit.collider.gameObject == gameObject; } public void SelectUnit() { isSelected = true; spriteRenderer.color = selectedColor; Debug.Log($"🎯 {name} выбран для движения"); } public void Deselect() { isSelected = false; SetNormalColor(); ClearPathPreview(); } public void SetPlayerControl(bool enabled) { playerControlEnabled = enabled; if (!enabled) { Deselect(); ClearPathPreview(); } } void SetNormalColor() { if (HasAlreadyMoved()) { spriteRenderer.color = alreadyMovedColor; } else { spriteRenderer.color = Color.white; } } // Остальные методы без изменений... void ShowPathPreview(Vector3 target) { ClearPathPreview(); Vector3 start = GetCurrentGridPosition(); Vector3Int startCell = floorTilemap.WorldToCell(start); Vector3Int targetCell = floorTilemap.WorldToCell(target); List<Vector3> previewPath = FindPathStraight(startCell, targetCell); if (previewPath != null && previewPath.Count > 1) { pathLineRenderer.positionCount = previewPath.Count; pathLineRenderer.SetPositions(previewPath.ToArray()); pathLineRenderer.startColor = pathColor; pathLineRenderer.endColor = pathColor; for (int i = 1; i < previewPath.Count; i++) { CreatePathIndicator(previewPath[i], pathColor); } } else { pathLineRenderer.positionCount = 2; pathLineRenderer.SetPosition(0, start); pathLineRenderer.SetPosition(1, target); pathLineRenderer.startColor = blockedPathColor; pathLineRenderer.endColor = blockedPathColor; CreatePathIndicator(target, blockedPathColor); } } void CreatePathIndicator(Vector3 position, Color color) { if (pathIndicatorPrefab != null) { GameObject indicator = Instantiate(pathIndicatorPrefab, position, Quaternion.identity); SpriteRenderer indicatorRenderer = indicator.GetComponent<SpriteRenderer>(); if (indicatorRenderer != null) { indicatorRenderer.color = color; } pathIndicators.Add(indicator); } else { GameObject indicator = new GameObject("PathIndicator"); indicator.transform.position = position; SpriteRenderer sr = indicator.AddComponent<SpriteRenderer>(); sr.sprite = Sprite.Create(Texture2D.whiteTexture, new Rect(0, 0, 1, 1), Vector2.one * 0.5f); sr.color = color; sr.sortingOrder = 5; indicator.transform.localScale = Vector3.one * 0.3f; pathIndicators.Add(indicator); } } void ClearPathPreview() { pathLineRenderer.positionCount = 0; foreach (GameObject indicator in pathIndicators) { if (indicator != null) Destroy(indicator); } pathIndicators.Clear(); } void FindStraightPath(Vector3 target) { ClearPathPreview(); Vector3 start = GetCurrentGridPosition(); Vector3Int startCell = floorTilemap.WorldToCell(start); Vector3Int targetCell = floorTilemap.WorldToCell(target); pathPoints.Clear(); pathPoints.Add(start); List<Vector3> foundPath = FindPathStraight(startCell, targetCell); if (foundPath != null && foundPath.Count > 1) { pathPoints = foundPath; currentPathIndex = 1; StopAllCoroutines(); StartCoroutine(FollowPath()); } else { Debug.Log("Путь заблокирован стенами!"); } } List<Vector3> FindPathStraight(Vector3Int start, Vector3Int target) { List<Vector3> path = new List<Vector3>(); path.Add(floorTilemap.GetCellCenterWorld(start)); Vector3Int current = start; while (current.x != target.x) { Vector3Int nextCell = current; nextCell.x += (target.x > current.x) ? 1 : -1; if (!CanMoveBetweenCells(current, nextCell)) return null; path.Add(floorTilemap.GetCellCenterWorld(nextCell)); current = nextCell; } while (current.y != target.y) { Vector3Int nextCell = current; nextCell.y += (target.y > current.y) ? 1 : -1; if (!CanMoveBetweenCells(current, nextCell)) return null; path.Add(floorTilemap.GetCellCenterWorld(nextCell)); current = nextCell; } return path; } bool CanMoveBetweenCells(Vector3Int fromCell, Vector3Int toCell) { Vector3 fromWorld = floorTilemap.GetCellCenterWorld(fromCell); Vector3 toWorld = floorTilemap.GetCellCenterWorld(toCell); if (!IsCellWalkable(toCell)) return false; Vector3 direction = (toWorld - fromWorld).normalized; float distance = Vector3.Distance(fromWorld, toWorld); RaycastHit2D hit = Physics2D.Raycast(fromWorld, direction, distance, wallLayer); if (hit.collider != null) return false; return true; } bool IsCellWalkable(Vector3Int cell) { if (!floorTilemap.HasTile(cell)) return false; Vector3 worldPos = floorTilemap.GetCellCenterWorld(cell); if (Physics2D.OverlapPoint(worldPos, wallLayer)) return false; return true; } Vector3 GetCurrentGridPosition() { Vector3Int currentCell = floorTilemap.WorldToCell(transform.position); return floorTilemap.GetCellCenterWorld(currentCell); } void SnapToGrid() { Vector3 snappedPos = GetCurrentGridPosition(); transform.position = snappedPos; } IEnumerator FollowPath() { isMoving = true; ClearPathPreview(); while (currentPathIndex < pathPoints.Count) { Vector3 currentTarget = pathPoints[currentPathIndex]; LookAtTarget(currentTarget); while (Vector3.Distance(transform.position, currentTarget) > 0.001f) { transform.position = Vector3.MoveTowards(transform.position, currentTarget, moveSpeed * Time.deltaTime); yield return null; } transform.position = currentTarget; currentPathIndex++; yield return null; } isMoving = false; pathPoints.Clear(); if (TurnManager.Instance != null) TurnManager.Instance.OnUnitFinishedAction(); } void LookAtTarget(Vector3 target) { Vector3 direction = target - transform.position; transform.rotation = Quaternion.identity; spriteRenderer.flipX = false; if (Mathf.Abs(direction.x) > Mathf.Abs(direction.y)) { if (direction.x > 0.1f) { if (rightSprite != null) spriteRenderer.sprite = rightSprite; else spriteRenderer.flipX = false; } else if (direction.x < -0.1f) { if (leftSprite != null) spriteRenderer.sprite = leftSprite; else spriteRenderer.flipX = true; } } else { if (direction.y > 0.1f) { if (upSprite != null) spriteRenderer.sprite = upSprite; } else if (direction.y < -0.1f) { if (downSprite != null) spriteRenderer.sprite = downSprite; } } } }