Unity tilemaps are a really fast way to set up an environment. I wanted to try my hand at working out a top-down 2D game with grid movement using said Tilemaps. Tried taking some inspiration from the original NES Zelda for thematic style.
Each scene has a Grid with at least 2 tilemaps: Ground and Obstacles. The grid has a tile checking script attached to it to return what type of collider is currently placed in each square in the grid using raycasts when a character attempts to move to it.
Collider2D CheckTargetPosition(Vector2 targetPos)
{
RaycastHit2D hit;
hit = Physics2D.Linecast(targetPos, targetPos);
return hit.collider;
}
public TileBase getCell(Tilemap tilemap, Vector2 worldPos)
{
return tilemap.GetTile(tilemap.WorldToCell(worldPos));
}
Right now the collision check is based on custom tags for specific items; namely Player, Enemy, Door and Chest. This way can it be easily expanded upon. The check returns true/false based on what object is there. Then a coroutine is used to either handle smooth movement or blocked movement.
IEnumerator SmoothMovement(Vector3 t)
{
_isMoving = true;
float sqrRemainingDistance = (transform.position - t).sqrMagnitude;
float inverseMoveTime = 1 / moveTime;
while (sqrRemainingDistance > float.Epsilon)
{
Vector3 newPosition = Vector3.MoveTowards(transform.position, t, inverseMoveTime * Time.deltaTime);
transform.position = newPosition;
sqrRemainingDistance = (transform.position - t).sqrMagnitude;
yield return null;
}
_isMoving = false;
}
Since this video I've gone through a few iterations of the movement script so that both the player and enemies can draw from it.
public IEnumerator BlockedMovement(Vector3 end)
{
_isMoving = true;
Vector3 originalPos = transform.position;
end = transform.position + ((end - transform.position) / 4);
float sqrRemainingDistance = (transform.position - end).sqrMagnitude;
float inverseMoveTime = (1 / (moveTime * 2));
while (sqrRemainingDistance > float.Epsilon)
{
Vector3 newPosition = Vector3.MoveTowards(transform.position, end, inverseMoveTime * Time.deltaTime);
transform.position = newPosition;
sqrRemainingDistance = (transform.position - end).sqrMagnitude;
yield return null;
}
sqrRemainingDistance = (transform.position - originalPos).sqrMagnitude;
while (sqrRemainingDistance > float.Epsilon)
{
Vector3 newPosition = Vector3.MoveTowards(transform.position, originalPos, inverseMoveTime * Time.deltaTime);
transform.position = newPosition;
sqrRemainingDistance = (transform.position - originalPos).sqrMagnitude;
yield return null;
}
_isMoving = false;
}
Comments
Post a Comment