Hello everyone, I’m having a little bit of trouble with a pathfiding system which I saw in a tutorial. So far I have achieved that my player builds a path and even follow it. Everything seems to work just fine while the player is able to move in all directions as soon as the connections of these paths are enabled. The problem I have is, I’d like my player to move only either horizontal or vertically. In this sense if I click in a position which is diagonal to the player (in the grid he would move creating a “L”) I’d like the player to ignore it and only move if the clicked position is either in a straight line (in front or back) or perpendicular to the player (sort of like a rook in chess).
Here is the code I hope I can get some help:
public class AnotherPlayerController : MonoBehaviour
{
public bool walking = false;
[Space]
public Transform currentCube;
public Transform clickedCube;
public Transform indicator;
[Space]
public List<Transform> finalPath = new List<Transform>();
private int targetIndex;
IEnumerator currentRoutine;
void Start()
{
RayCastDown();
}
void Update()
{
//GET CURRENT CUBE (UNDER PLAYER)
RayCastDown();
// CLICK ON CUBE
if(walking != true)
{
if (Input.GetMouseButtonDown(0))
{
Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit mouseHit;
if (Physics.Raycast(mouseRay, out mouseHit))
{
if (mouseHit.transform.GetComponent<Walkable>() != null)
{
clickedCube = mouseHit.transform;
finalPath.Clear();
FindPath();
}
}
}
}
}
void FindPath()
{
List<Transform> nextCubes = new List<Transform>();
List<Transform> pastCubes = new List<Transform>();
foreach (WalkPath path in currentCube.GetComponent<Walkable>().possiblePaths)
{
if (path.active)
{
nextCubes.Add(path.target);
path.target.GetComponent<Walkable>().previousBlock = currentCube;
}
}
pastCubes.Add(currentCube);
ExploreCube(nextCubes, pastCubes);
BuildPath();
}
void ExploreCube(List<Transform> nextCubes, List<Transform> visitedCubes)
{
Transform current = nextCubes.First();
nextCubes.Remove(current);
if (current == clickedCube)
{
return;
}
foreach (WalkPath path in current.GetComponent<Walkable>().possiblePaths)
{
if (!visitedCubes.Contains(path.target) && path.active)
{
nextCubes.Add(path.target);
path.target.GetComponent<Walkable>().previousBlock = current;
}
}
visitedCubes.Add(current);
if (nextCubes.Any())
{
ExploreCube(nextCubes, visitedCubes);
}
}
void BuildPath()
{
Transform cube = clickedCube;
while (cube != currentCube)
{
finalPath.Add(cube);
if (cube.GetComponent<Walkable>().previousBlock != null)
cube = cube.GetComponent<Walkable>().previousBlock;
else
return;
}
finalPath.Insert(0, clickedCube);
finalPath.Reverse();
if(currentRoutine != null)
{
StopCoroutine(currentRoutine);
}
currentRoutine = FollowPath();
StartCoroutine(currentRoutine);
}
IEnumerator FollowPath()
{
walking = true;
while (true)
{
if (Vector3.Distance(finalPath[targetIndex].GetComponent<Walkable>().GetWalkPoint() + transform.up / 2f, transform.position) < 0.1f)
{
targetIndex++;
if (targetIndex >= finalPath.Count - 1)
{
targetIndex = 0;
Clear();
yield break;
}
}
transform.position = Vector3.MoveTowards(transform.position, finalPath[targetIndex].GetComponent<Walkable>().GetWalkPoint() + transform.up / 2f, 3f * Time.deltaTime);
yield return null;
}
}
public void Clear()
{
foreach (Transform t in finalPath)
{
t.GetComponent<Walkable>().previousBlock = null;
}
finalPath.Clear();
walking = false;
}
public void RayCastDown()
{
Ray playerRay = new Ray(transform.position, -transform.up);
RaycastHit playerHit;
if (Physics.Raycast(playerRay, out playerHit))
{
if (playerHit.transform.GetComponent<Walkable>() != null)
{
currentCube = playerHit.transform;
}
}
}
private void OnDrawGizmos()
{
Gizmos.color = Color.blue;
Ray ray = new Ray(transform.position, -transform.up);
Gizmos.DrawRay(ray);
}
}