This commit is contained in:
MrTorex committed 2026-02-18 10:43:12 +03:00
1 parent 1b564e47e9
commit 7f65ead644
44 files changed
+4582 -2

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e6ed2809466848c8b1fbb7d87a465803
timeCreated: 1771392678
+42
View File
@@ -0,0 +1,42 @@
using System;
namespace Code.Lab6
{
[Serializable]
public class Edge : IComparable<Edge>
{
public float cost;
public readonly Vertex Vertex;
public Edge(Vertex vertex = null, float cost = 1f)
{
Vertex = vertex;
this.cost = cost;
}
public int CompareTo(Edge other)
{
var result = cost - other.cost;
var idA = Vertex.GetInstanceID();
var idB = other.Vertex.GetInstanceID();
if (idA == idB) return 0;
return (int)result;
}
public bool Equals(Edge other)
{
return other.Vertex.id == Vertex.id;
}
public override bool Equals(object obj)
{
var other = (Edge)obj;
return other != null && other.Vertex.id == Vertex.id;
}
public override int GetHashCode()
{
return Vertex.GetHashCode();
}
}
}
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d1cc93fbb8b74a3dbb53466e2ec007ad
timeCreated: 1771392690
+244
View File
@@ -0,0 +1,244 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Code.Lab6
{
public abstract class Graph : MonoBehaviour
{
public GameObject vertexPrefab;
protected List<Vertex> Vertices;
protected List<List<Vertex>> Neighbours;
protected List<List<float>> Costs;
public virtual void Start()
{
if (Application.isPlaying)
{
Load();
}
}
public virtual void Load() { }
public virtual int GetSize()
{
if (ReferenceEquals(Vertices, null)) return 0;
return Vertices.Count;
}
public virtual Vertex GetNearestVertex(Vector3 position)
{
return null;
}
public virtual Vertex GetVertexObj(int id)
{
if (ReferenceEquals(Vertices, null) || Vertices.Count == 0)
return null;
if (id < 0 || id >= Vertices.Count)
return null;
return Vertices[id];
}
public virtual Vertex[] GetNeighbours(Vertex v)
{
if (ReferenceEquals(Neighbours, null) || Neighbours.Count == 0 || v.id < 0 || v.id >= Neighbours.Count)
return Array.Empty<Vertex>();
return Neighbours[v.id].ToArray();
}
public virtual Edge[] GetEdges(Vertex v)
{
return v.neighbours == null ? Array.Empty<Edge>() : v.neighbours.ToArray();
}
public List<Vertex> GetPathBfs(GameObject srcObj, GameObject dstObj)
{
if (!srcObj || !dstObj)
return new List<Vertex>();
var src = GetNearestVertex(srcObj.transform.position);
var dst = GetNearestVertex(dstObj.transform.position);
if (!src || !dst)
{
Debug.LogWarning("Source or destination vertex is null");
return new List<Vertex>();
}
Debug.Log($"BFS from {src.id} to {dst.id}");
var previous = new Dictionary<int, int>();
var visited = new HashSet<int>();
var queue = new Queue<Vertex>();
visited.Add(src.id);
previous[src.id] = src.id;
queue.Enqueue(src);
while (queue.Count > 0)
{
var current = queue.Dequeue();
if (current.id == dst.id)
{
Debug.Log("BFS: Path found!");
return BuildPath(src.id, dst.id, previous);
}
var neighbours = GetNeighbours(current);
foreach (var neighbour in neighbours)
{
if (!neighbour) continue;
if (!visited.Add(neighbour.id)) continue;
previous[neighbour.id] = current.id;
queue.Enqueue(neighbour);
}
}
Debug.LogWarning("BFS: No path found");
return new List<Vertex>();
}
public List<Vertex> GetPathDfs(GameObject srcObj, GameObject dstObj)
{
if (!srcObj || !dstObj)
return new List<Vertex>();
var src = GetNearestVertex(srcObj.transform.position);
var dst = GetNearestVertex(dstObj.transform.position);
if (!src || !dst)
{
Debug.LogWarning("Source or destination vertex is null");
return new List<Vertex>();
}
Debug.Log($"DFS from {src.id} to {dst.id}");
var previous = new Dictionary<int, int>();
var visited = new HashSet<int>();
var stack = new Stack<Vertex>();
visited.Add(src.id);
previous[src.id] = src.id;
stack.Push(src);
while (stack.Count > 0)
{
var current = stack.Pop();
if (current.id == dst.id)
{
Debug.Log("DFS: Path found!");
return BuildPath(src.id, dst.id, previous);
}
var neighbours = GetNeighbours(current);
foreach (var neighbour in neighbours)
{
if (!neighbour) continue;
if (!visited.Add(neighbour.id)) continue;
previous[neighbour.id] = current.id;
stack.Push(neighbour);
}
}
Debug.LogWarning("DFS: No path found");
return new List<Vertex>();
}
private List<Vertex> BuildPath(int srcId, int dstId, Dictionary<int, int> previous)
{
var path = new List<Vertex>();
if (!previous.ContainsKey(dstId))
{
Debug.LogError("Destination not in previous dictionary");
return path;
}
var currentId = dstId;
while (currentId != srcId)
{
var currentVertex = GetVertexById(currentId);
if (!currentVertex)
{
Debug.LogError($"Vertex with id {currentId} not found");
break;
}
path.Add(currentVertex);
if (!previous.TryGetValue(currentId, out var previou))
{
Debug.LogError($"Previous not found for id {currentId}");
break;
}
currentId = previou;
}
var srcVertex = GetVertexById(srcId);
if (srcVertex is not null)
{
path.Add(srcVertex);
}
path.Reverse();
Debug.Log($"Path built with {path.Count} vertices");
return path;
}
private Vertex GetVertexById(int id)
{
return Vertices?.FirstOrDefault(v => v && v.id == id);
}
private List<Vertex> BuildPath(int srcId, int dstId, ref int[] prevList)
{
var path = new List<Vertex>();
var prev = dstId;
do
{
var v = GetVertexById(prev);
if (v == null)
{
Debug.LogError($"Vertex with id {prev} not found");
break;
}
path.Add(v);
if (prev < 0 || prev >= prevList.Length)
{
Debug.LogError($"Index {prev} out of range for prevList (size {prevList.Length})");
break;
}
prev = prevList[prev];
} while (prev != srcId && prev != -1);
if (prev != -1)
{
var srcV = GetVertexById(srcId);
if (srcV != null)
path.Add(srcV);
}
path.Reverse();
return path;
}
}
}
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d9a37e08f9ec46ab848036cca23dfbd4
timeCreated: 1771392722
+324
View File
@@ -0,0 +1,324 @@
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace Code.Lab6
{
public class GraphGrid : Graph
{
public GameObject obstaclePrefab;
public string mapName = "arena.map";
public bool get8Vicinity = false;
public float cellSize = 1f;
[Range(0, Mathf.Infinity)]
public float defaultCost = 1f;
private const string MapsDir = "Resources/Maps";
private int _numCols;
private int _numRows;
private GameObject[] _vertexObj;
private bool[,] _mapVertices;
private Dictionary<int, int> _gridIdToVertexIndex;
private int GridToId(int x, int y)
{
return _numCols * y + x;
}
private Vector2Int IdToGrid(int id)
{
return new Vector2Int(id % _numCols, id / _numCols);
}
private void LoadMap(string filename)
{
var path = Application.dataPath + "/" + MapsDir + "/" + filename;
try
{
var strmRdr = new StreamReader(path);
using (strmRdr)
{
strmRdr.ReadLine();
var line = strmRdr.ReadLine();
if (line != null && line.StartsWith("height"))
{
_numRows = int.Parse(line.Split(' ')[1]);
}
else
{
Debug.LogError("Invalid map format: height line not found");
return;
}
line = strmRdr.ReadLine();
if (line != null && line.StartsWith("width"))
{
_numCols = int.Parse(line.Split(' ')[1]);
}
else
{
Debug.LogError("Invalid map format: width line not found");
return;
}
strmRdr.ReadLine();
var totalCells = _numRows * _numCols;
Vertices = new List<Vertex>();
Neighbours = new List<List<Vertex>>();
Costs = new List<List<float>>();
_vertexObj = new GameObject[totalCells];
_mapVertices = new bool[_numRows, _numCols];
_gridIdToVertexIndex = new Dictionary<int, int>();
Debug.Log($"Loading map {_numRows}x{_numCols} (total cells: {totalCells})");
for (var row = 0; row < _numRows; row++)
{
line = strmRdr.ReadLine();
if (string.IsNullOrEmpty(line) || line.Length < _numCols)
{
Debug.LogError($"Map line {row} is too short or missing");
continue;
}
for (var col = 0; col < _numCols; col++)
{
var cellChar = line[col];
var isGround = (cellChar == '.' || cellChar == 'G' || cellChar == ' ');
_mapVertices[row, col] = isGround;
var position = new Vector3(col * cellSize, 0f, row * cellSize);
var gridId = GridToId(col, row);
GameObject obj;
if (isGround && vertexPrefab != null)
{
obj = Instantiate(vertexPrefab, position, Quaternion.identity);
}
else if (!isGround && obstaclePrefab != null)
{
obj = Instantiate(obstaclePrefab, position, Quaternion.identity);
}
else
{
obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
obj.transform.position = position;
var renderer1 = obj.GetComponent<Renderer>();
if (renderer1 != null)
{
renderer1.material.color = isGround ? Color.green : Color.red;
}
}
if (obj == null) continue;
obj.name = $"{(isGround ? "Ground" : "Obstacle")}_{gridId}";
obj.transform.parent = transform;
var scale = obj.transform.localScale;
scale.x = cellSize;
scale.z = cellSize;
scale.y = isGround ? 0.1f : 1f;
obj.transform.localScale = scale;
_vertexObj[gridId] = obj;
if (!isGround) continue;
var v = obj.GetComponent<Vertex>();
if (v == null)
v = obj.AddComponent<Vertex>();
v.id = gridId;
v.neighbours = new List<Edge>();
var vertexIndex = Vertices.Count;
Vertices.Add(v);
Neighbours.Add(new List<Vertex>());
Costs.Add(new List<float>());
_gridIdToVertexIndex[gridId] = vertexIndex;
}
}
Debug.Log($"Created {Vertices.Count} walkable vertices");
foreach (var kvp in _gridIdToVertexIndex)
{
var gridId = kvp.Key;
var vertexIndex = kvp.Value;
var gridPos = IdToGrid(gridId);
SetNeighbours(gridPos.x, gridPos.y, vertexIndex);
}
Debug.Log($"Map loaded successfully. {Vertices.Count} walkable vertices");
}
}
catch (Exception e)
{
Debug.LogError($"Failed to load map: {e.Message}");
Debug.LogException(e);
}
}
protected void SetNeighbours(int x, int y, int vertexIndex)
{
var currentVertex = Vertices[vertexIndex];
var gridId = currentVertex.id;
Neighbours[vertexIndex].Clear();
Costs[vertexIndex].Clear();
currentVertex.neighbours.Clear();
Vector2Int[] directions;
if (get8Vicinity)
{
directions = new[]
{
new Vector2Int(x, y - 1), new Vector2Int(x + 1, y - 1), new Vector2Int(x + 1, y), new Vector2Int(x + 1, y + 1), new Vector2Int(x, y + 1), new Vector2Int(x - 1, y + 1), new Vector2Int(x - 1, y), new Vector2Int(x - 1, y - 1)
};
}
else
{
directions = new[]
{
new Vector2Int(x, y - 1), new Vector2Int(x + 1, y), new Vector2Int(x, y + 1), new Vector2Int(x - 1, y)
};
}
var diagonalCost = defaultCost * 1.4f;
foreach (var dir in directions)
{
if (dir.x < 0 || dir.x >= _numCols || dir.y < 0 || dir.y >= _numRows)
continue;
if (!_mapVertices[dir.y, dir.x])
continue;
var neighbourGridId = GridToId(dir.x, dir.y);
if (!_gridIdToVertexIndex.TryGetValue(neighbourGridId, out var neighbourIndex))
continue;
var neighbourVertex = Vertices[neighbourIndex];
var cost = defaultCost;
if (dir.x != x && dir.y != y)
{
cost = diagonalCost;
}
Neighbours[vertexIndex].Add(neighbourVertex);
Costs[vertexIndex].Add(cost);
currentVertex.neighbours.Add(new Edge(neighbourVertex, cost));
}
}
public override void Load()
{
LoadMap(mapName);
}
public override Vertex GetNearestVertex(Vector3 position)
{
var col = Mathf.RoundToInt(position.x / cellSize);
var row = Mathf.RoundToInt(position.z / cellSize);
col = Mathf.Clamp(col, 0, _numCols - 1);
row = Mathf.Clamp(row, 0, _numRows - 1);
if (!_mapVertices[row, col])
{
return FindNearestWalkable(col, row);
}
var gridId = GridToId(col, row);
return _gridIdToVertexIndex.TryGetValue(gridId, out var vertexIndex) ? Vertices[vertexIndex] : null;
}
private Vertex FindNearestWalkable(int startCol, int startRow)
{
var queue = new Queue<Vector2Int>();
var explored = new HashSet<Vector2Int>();
queue.Enqueue(new Vector2Int(startCol, startRow));
explored.Add(new Vector2Int(startCol, startRow));
const int maxSearchRadius = 20;
var steps = 0;
while (queue.Count > 0 && steps < maxSearchRadius * maxSearchRadius)
{
var pos = queue.Dequeue();
if (_mapVertices[pos.y, pos.x])
{
var gridId = GridToId(pos.x, pos.y);
if (_gridIdToVertexIndex.TryGetValue(gridId, out var vertexIndex))
{
return Vertices[vertexIndex];
}
}
var neighbours = new[]
{
new Vector2Int(pos.x, pos.y - 1),
new Vector2Int(pos.x + 1, pos.y),
new Vector2Int(pos.x, pos.y + 1),
new Vector2Int(pos.x - 1, pos.y)
};
foreach (var n in neighbours)
{
if (n.x < 0 || n.x >= _numCols || n.y < 0 || n.y >= _numRows || !explored.Add(n)) continue;
queue.Enqueue(n);
}
steps++;
}
Debug.LogWarning($"No walkable vertex found near ({startCol}, {startRow})");
return Vertices.Count > 0 ? Vertices[0] : null;
}
public override Vertex[] GetNeighbours(Vertex v)
{
if (!v || Vertices == null || Neighbours == null || !_gridIdToVertexIndex.TryGetValue(v.id, out var vertexIndex) || vertexIndex < 0 || vertexIndex >= Neighbours.Count || Neighbours[vertexIndex] == null)
return Array.Empty<Vertex>();
return Neighbours[vertexIndex].ToArray();
}
public override Edge[] GetEdges(Vertex v)
{
if (!v || v.neighbours == null)
return Array.Empty<Edge>();
return v.neighbours.ToArray();
}
public override Vertex GetVertexObj(int id)
{
if (!_gridIdToVertexIndex.TryGetValue(id, out var vertexIndex)) return null;
if (vertexIndex >= 0 && vertexIndex < Vertices.Count)
return Vertices[vertexIndex];
return null;
}
}
}
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 507ba3373b14402a9205a88c6d3d7e94
timeCreated: 1771392736
+37
View File
@@ -0,0 +1,37 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Code.Lab6
{
[System.Serializable]
public class Vertex : MonoBehaviour
{
public int id = -1;
public List<Edge> neighbours;
[HideInInspector]
public Vertex prev;
private void Awake()
{
neighbours ??= new List<Edge>();
}
private void OnDrawGizmos()
{
Gizmos.color = Color.cyan;
Gizmos.DrawSphere(transform.position, 0.2f);
}
private void OnDrawGizmosSelected()
{
if (neighbours == null) return;
Gizmos.color = Color.yellow;
foreach (var edge in neighbours.Where(edge => edge?.Vertex != null))
{
Gizmos.DrawLine(transform.position, edge.Vertex.transform.position);
}
}
}
}
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 27d037f459ac450d9902f69b5b339d54
timeCreated: 1771392709
+198
View File
@@ -0,0 +1,198 @@
using Code.Base;
using System.Collections.Generic;
using Code.Lab1;
using UnityEngine;
namespace Code.Lab6
{
public class VertexPathFollower : Seek
{
private List<Vertex> _path;
private int _currentTargetIndex;
private bool _isFollowing;
public float waypointReachedDistance = 0.5f;
public bool loopPath;
public bool drawGizmos = true;
public float agentHeight = 1f;
public bool fixYPosition = true;
private float _startY;
public override void Awake()
{
base.Awake();
if (target == null)
{
target = new GameObject("PathFollower_Target");
}
_path = new List<Vertex>();
_isFollowing = false;
_startY = transform.position.y;
}
public void SetPath(List<Vertex> newPath)
{
if (newPath == null || newPath.Count == 0)
{
Debug.LogWarning("Path is empty!");
StopFollowing();
return;
}
_path = newPath;
_currentTargetIndex = 0;
_isFollowing = true;
Debug.Log($"Path set! Starting movement to {_path.Count} waypoints");
UpdateTargetPosition();
}
public void StopFollowing()
{
_isFollowing = false;
_path?.Clear();
}
private void UpdateTargetPosition()
{
if (!target || _path == null || _path.Count == 0)
return;
if (_currentTargetIndex < _path.Count && _path[_currentTargetIndex] != null)
{
var targetPos = _path[_currentTargetIndex].transform.position;
targetPos.y = agentHeight;
target.transform.position = targetPos;
}
}
public override Steering GetSteering()
{
if (!_isFollowing || _path == null || _path.Count == 0 || _currentTargetIndex >= _path.Count)
{
return new Steering();
}
if (fixYPosition)
{
var currentPos = transform.position;
currentPos.y = agentHeight;
transform.position = currentPos;
}
var distanceToTarget = Vector3.Distance(
new Vector3(transform.position.x, 0, transform.position.z),
new Vector3(target.transform.position.x, 0, target.transform.position.z)
);
if (distanceToTarget < waypointReachedDistance)
{
_currentTargetIndex++;
if (_currentTargetIndex >= _path.Count)
{
if (loopPath)
{
_currentTargetIndex = 0;
Debug.Log("Path completed! Looping...");
}
else
{
Debug.Log("Path completed! Stopping.");
StopFollowing();
return new Steering();
}
}
UpdateTargetPosition();
}
var steering = base.GetSteering();
steering.Linear = new Vector3(steering.Linear.x, 0, steering.Linear.z);
return steering;
}
private void FixedUpdate()
{
if (fixYPosition)
{
var pos = transform.position;
pos.y = agentHeight;
transform.position = pos;
}
}
public bool IsFollowing()
{
return _isFollowing && _path != null && _path.Count > 0 && _currentTargetIndex < _path.Count;
}
public Vertex GetCurrentTarget()
{
if (!_isFollowing || _path == null || _path.Count == 0 || _currentTargetIndex >= _path.Count)
return null;
return _path[_currentTargetIndex];
}
public int GetRemainingWaypoints()
{
if (!_isFollowing || _path == null)
return 0;
return Mathf.Max(0, _path.Count - _currentTargetIndex);
}
private void OnDrawGizmos()
{
if (!drawGizmos || _path == null) return;
Gizmos.color = Color.green;
for (var i = 0; i < _path.Count - 1; i++)
{
if (_path[i] != null && _path[i + 1] != null)
{
var start = _path[i].transform.position;
var end = _path[i + 1].transform.position;
start.y = agentHeight;
end.y = agentHeight;
Gizmos.DrawLine(start, end);
}
}
if (_isFollowing && _currentTargetIndex < _path.Count && _path[_currentTargetIndex] != null)
{
var targetPos = _path[_currentTargetIndex].transform.position;
targetPos.y = agentHeight;
Gizmos.color = Color.red;
Gizmos.DrawSphere(targetPos, 0.3f);
Gizmos.color = Color.yellow;
var agentPos = transform.position;
agentPos.y = agentHeight;
Gizmos.DrawLine(agentPos, targetPos);
}
#if UNITY_EDITOR
for (var i = 0; i < _path.Count; i++)
{
if (_path[i] == null) continue;
var labelPos = _path[i].transform.position;
labelPos.y = agentHeight + 0.5f;
UnityEditor.Handles.color = Color.white;
UnityEditor.Handles.Label(labelPos, $"#{i}");
}
#endif
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5347d94ded854559b5594b4ed46e03ee
timeCreated: 1771393841
+244
View File
@@ -0,0 +1,244 @@
using System.Collections.Generic;
using Code.Base;
using Code.Lab6;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
namespace Code.UI
{
public class Lab6Controller : MonoBehaviour
{
public Graph graph;
public Agent agent;
public Transform targetMarker;
public Button toMenuButton;
public Button resetButton;
public Button findPathButton;
public Button dfsButton;
public Button bfsButton;
public Button stopButton;
public LineRenderer pathLine;
public Color pathColor = Color.green;
public TextMeshProUGUI statusText;
private List<Vertex> _currentPath;
private VertexPathFollower _pathFollower;
private bool _useBfs = true;
private void Awake()
{
if (toMenuButton != null)
toMenuButton.onClick.AddListener(LoadMainMenu);
if (resetButton != null)
resetButton.onClick.AddListener(ResetScene);
if (findPathButton != null)
findPathButton.onClick.AddListener(FindPathToTarget);
if (dfsButton != null)
dfsButton.onClick.AddListener(() => SetAlgorithm(false));
if (bfsButton != null)
bfsButton.onClick.AddListener(() => SetAlgorithm(true));
if (stopButton != null)
stopButton.onClick.AddListener(StopAgent);
_pathFollower = agent?.GetComponent<VertexPathFollower>();
if (_pathFollower == null && agent != null)
{
_pathFollower = agent.gameObject.AddComponent<VertexPathFollower>();
}
if (pathLine != null)
{
pathLine.startColor = pathColor;
pathLine.endColor = pathColor;
pathLine.startWidth = 0.2f;
pathLine.endWidth = 0.2f;
}
_currentPath = new List<Vertex>();
}
private void Start()
{
if (graph == null)
graph = FindFirstObjectByType<Graph>();
if (agent == null)
agent = FindFirstObjectByType<Agent>();
if (targetMarker == null)
{
var marker = GameObject.CreatePrimitive(PrimitiveType.Sphere);
marker.name = "Target Marker";
marker.transform.position = new Vector3(5, 0.5f, 5);
marker.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
var renderer1 = marker.GetComponent<Renderer>();
renderer1.material.color = Color.red;
Destroy(marker.GetComponent<Collider>());
targetMarker = marker.transform;
}
if (agent == null) return;
var pos = agent.transform.position;
pos.y = 0.5f;
agent.transform.position = pos;
}
private void Update()
{
if (Input.GetMouseButtonDown(1))
{
if (Camera.main != null)
{
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
var targetPos = hit.point;
targetPos.y = 0.5f;
targetMarker.position = targetPos;
FindPathToTarget();
}
}
}
DrawPath();
UpdateStatusText();
}
private void UpdateStatusText()
{
if (!statusText) return;
var status = $"Algorithm: {(_useBfs ? "BFS" : "DFS")}\n";
if (_pathFollower && _pathFollower.IsFollowing())
{
status += $"Status: Moving to waypoint {_pathFollower.GetRemainingWaypoints()}/{_currentPath.Count}\n";
var currentTarget = _pathFollower.GetCurrentTarget();
if (currentTarget)
{
status += $"Target pos: {currentTarget.transform.position}\n";
}
}
else
{
status += "Status: Idle\n";
}
status += $"Path nodes: {_currentPath.Count}";
statusText.text = status;
}
public void SetAlgorithm(bool useBfs)
{
_useBfs = useBfs;
Debug.Log(useBfs ? "Using BFS algorithm" : "Using DFS algorithm");
if (targetMarker != null)
{
FindPathToTarget();
}
}
public void StopAgent()
{
if (_pathFollower != null)
{
_pathFollower.StopFollowing();
}
_currentPath.Clear();
}
public void FindPathToTarget()
{
if (!graph || !agent || !targetMarker)
{
Debug.LogError("Missing references!");
return;
}
var targetPos = targetMarker.position;
targetPos.y = 0.5f;
targetMarker.position = targetPos;
var path = _useBfs ? graph.GetPathBfs(agent.gameObject, targetMarker.gameObject) : graph.GetPathDfs(agent.gameObject, targetMarker.gameObject);
if (path is { Count: > 0 })
{
_currentPath = path;
Debug.Log($"Path found! Length: {path.Count} nodes");
if (_pathFollower)
{
_pathFollower.SetPath(path);
}
}
else
{
Debug.LogWarning("No path found!");
_currentPath.Clear();
if (_pathFollower)
{
_pathFollower.StopFollowing();
}
}
}
private void DrawPath()
{
if (!pathLine || _currentPath == null || _currentPath.Count < 2)
{
if (pathLine)
pathLine.positionCount = 0;
return;
}
pathLine.positionCount = _currentPath.Count;
for (var i = 0; i < _currentPath.Count; i++)
{
if (!_currentPath[i]) continue;
var pos = _currentPath[i].transform.position;
pos.y += 0.2f;
pathLine.SetPosition(i, pos);
}
}
private static void ResetScene()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
private static void LoadMainMenu()
{
SceneManager.LoadScene("MainMenu");
}
private void OnDestroy()
{
if (toMenuButton != null)
toMenuButton.onClick.RemoveListener(LoadMainMenu);
if (resetButton != null)
resetButton.onClick.RemoveListener(ResetScene);
if (findPathButton != null)
findPathButton.onClick.RemoveListener(FindPathToTarget);
if (dfsButton != null)
dfsButton.onClick.RemoveAllListeners();
if (bfsButton != null)
bfsButton.onClick.RemoveAllListeners();
if (stopButton != null)
stopButton.onClick.RemoveListener(StopAgent);
}
}
}
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 58f148e1e6954b1fb160c3279addc512
timeCreated: 1771392756