252 lines
7.7 KiB
C#
252 lines
7.7 KiB
C#
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 bool isDop;
|
|
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;
|
|
|
|
List<Vertex> path;
|
|
|
|
if (!isDop)
|
|
path = _useBfs
|
|
? graph.GetPathBfs(agent.gameObject, targetMarker.gameObject)
|
|
: graph.GetPathDfs(agent.gameObject, targetMarker.gameObject);
|
|
else
|
|
path = graph.GetPathWeights(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);
|
|
}
|
|
}
|
|
} |