- Home /
Pathfinding in 2d RPG
Hello, I am making a 2D RPG game, but I want it to be playable on mobile devices so you click on where you want the player to go but I don't want the player to go diagonally. That made a script that made the player go to the x axis first and then in the y axis.
using System.Collections; using System.Collections.Generic; using UnityEngine;
**public class PlayerController : MonoBehaviour { private Vector3 targetPos;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
targetPos = new Vector3 (Mathf.Round(mousePos.x), Mathf.Round(mousePos.y), 0);
ChackWay();
}
}
void ChackWay()
{
Vector3 positionDifference = targetPos - WayChecker.transform.position;
List<Vector3> moveProcess = new List<Vector3>();
//first in x
for (int i = 0; i < Mathf.Abs(positionDifference.x); i++)
{
if (positionDifference.x > 0)
{
WayChecker.transform.position += Vector3.right;
}
else
{
WayChecker.transform.position += Vector3.left;
}
}
//then in y
for (int i = 0; i < Mathf.Abs(positionDifference.y); i++)
{
if (positionDifference.y > 0)
{
WayChecker.transform.position += Vector3.up;
}
else
{
WayChecker.transform.position += Vector3.down;
}
}
}
}**
Then I started using trees and things I don't want the player to walk through, so I used tilemaps and tilemaps colliers, and changed the script so that if you click on somewhere the player can't go by the first way it won't move.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{ public Collider2D terrain; private Collider2D coll; private Vector3 targetPos;
// Start is called before the first frame update
void Start()
{
coll = GetComponent<Collider2D>();
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
targetPos = new Vector3 (Mathf.Round(mousePos.x), Mathf.Round(mousePos.y), 0);
StartCoroutine(ChackWay());
}
}
IEnumerator ChackWay()
{
Vector3 positionDifference = targetPos - transform.position;
Vector3 startPos = transform.position;
//first in x
for (int i = 0; i < Mathf.Abs(positionDifference.x); i++)
{
if (positionDifference.x > 0)
{
transform.position += Vector3.right;
}
else
{
transform.position += Vector3.left;
}
//waits until collisions are updated
yield return new WaitForFixedUpdate();
//if it is touching the terrain then it stops
if (coll.IsTouching(terrain))
{
transform.position = startPos;
yield break;
}
}
//then in y
for (int i = 0; i < Mathf.Abs(positionDifference.y); i++)
{
if (positionDifference.y > 0)
{
transform.position += Vector3.up;
}
else
{
transform.position += Vector3.down;
}
//wait until the collisions are updated
yield return new WaitForFixedUpdate();
//if it is touching the terrain then it stops
if (coll.IsTouching(terrain))
{
transform.position = startPos;
yield break;
}
}
}
}
The problem is checking if the player is touching the terrain needs to wait for a fixed update and that means you wait 0.02 seconds every time you check if the player is touching the terrain. I also want the player to find a way to go to the point the mouse has clicked and go through the best path, so I searched on the internet, and I found a video that said you use A* algorithm and something like a grid system (https://youtu.be/waEsGu--9P8 and https://youtu.be/alU04hvz6L4), but it is difficult to understand (if it is only that I should just watch it a lot of times) and I want to understand totally the things I use on my game. The point is I don't know how to implement it with the tilemap and I don't want the player to move diagonally.
I would like to use the simplest way possible, even if it doesn't use the way in the videos.