Skip to content

Instantly share code, notes, and snippets.

@MadCoderr
Last active April 1, 2022 09:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MadCoderr/b0282e030eb7fb7a18fc14fdd6a12cdb to your computer and use it in GitHub Desktop.
Save MadCoderr/b0282e030eb7fb7a18fc14fdd6a12cdb to your computer and use it in GitHub Desktop.
Unity3d Pacman like movement
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour {
[SerializeField] private float MoveSpeed = 5f;
[SerializeField] private float GridSize = 1f;
[SerializeField] private float CheckDistance = 0.005f;
[SerializeField] private LayerMask BlockLayer;
private enum MovementDirection { Up, Down, Left, Right, Zero };
private MovementDirection _direction;
private MovementDirection _previousDir;
private MovementDirection _nextDirection;
private Vector2 _startPos;
private Vector2 _endPos;
private bool _isMoving;
private float _time;
private float _width, _height;
private float _factor = 1f;
private bool _canMove = false;
private bool _blockLeft = false, _blockRight = false,
_blockUp = false, _blockDown= false;
private void Start() {
_direction = MovementDirection.Zero;
_previousDir = MovementDirection.Zero;
_nextDirection = MovementDirection.Zero;
_width = GetComponent<Collider2D>().bounds.extents.x + 0.1f;
_height = GetComponent<Collider2D>().bounds.extents.y + 0.2f;
}
private void Update() {
checkBlocks();
}
void LateUpdate() {
getInput();
if (_direction != MovementDirection.Zero)
_canMove = true;
if (!_isMoving) {
if (_canMove)
StartCoroutine(moveToNextGrid(transform.position));
}
}
private void getInput() {
if ((Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow))) { changeDirection(MovementDirection.Up); }
else if ((Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.DownArrow))) { changeDirection(MovementDirection.Down); }
else if ((Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.LeftArrow))) { changeDirection(MovementDirection.Left); }
else if ((Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.RightArrow))) { changeDirection(MovementDirection.Right); }
else { checkNextDirection(); }
}
private void changeDirection(MovementDirection dir) {
if (_previousDir == MovementDirection.Zero)
_previousDir = _direction;
_direction = dir;
_nextDirection = _direction;
}
IEnumerator moveToNextGrid(Vector2 position) {
_isMoving = true;
_startPos = position;
_time = 0;
checkDirection();
while (_time < 1f) {
_time += Time.deltaTime * (MoveSpeed / GridSize) * _factor;
transform.position = Vector2.Lerp(_startPos, _endPos, _time);
yield return null;
}
_isMoving = false;
yield return 0;
}
private void checkDirection() {
if (_direction == MovementDirection.Up && !_blockUp) {
_endPos = new Vector2(_startPos.x, _startPos.y + Mathf.Sign(1) * GridSize);
}
else if (_direction == MovementDirection.Down && !_blockDown) {
_endPos = new Vector2(_startPos.x, _startPos.y + Mathf.Sign(-1) * GridSize);
}
else if (_direction == MovementDirection.Right && !_blockRight) {
_endPos = new Vector2(_startPos.x + Mathf.Sign(1) * GridSize, _startPos.y);
}
else if (_direction == MovementDirection.Left && !_blockLeft) {
_endPos = new Vector2(_startPos.x + Mathf.Sign(-1) * GridSize, _startPos.y);
}
else {
checkPreviousDirection();
}
}
private void checkPreviousDirection() {
switch (_previousDir) {
case MovementDirection.Up: if (!_blockUp) { _direction = _previousDir; checkDirection(); } break;
case MovementDirection.Down: if (!_blockDown) { _direction = _previousDir; checkDirection(); } break;
case MovementDirection.Right: if (!_blockRight) { _direction = _previousDir; checkDirection(); } break;
case MovementDirection.Left: if (!_blockLeft) { _direction = _previousDir; checkDirection(); } break;
}
}
private void checkNextDirection() {
switch (_nextDirection) {
case MovementDirection.Up: if (!_blockUp) { _direction = _nextDirection; _nextDirection = MovementDirection.Zero; _previousDir = MovementDirection.Zero; } break;
case MovementDirection.Down: if (!_blockDown) { _direction = _nextDirection; _nextDirection = MovementDirection.Zero; _previousDir = MovementDirection.Zero; } break;
case MovementDirection.Right: if (!_blockRight) { _direction = _nextDirection; _nextDirection = MovementDirection.Zero; _previousDir = MovementDirection.Zero; } break;
case MovementDirection.Left: if (!_blockLeft) { _direction = _nextDirection; _nextDirection = MovementDirection.Zero; _previousDir = MovementDirection.Zero; } break;
}
}
private void checkBlocks() {
_blockUp = checkUpBlock();
_blockDown = checkDownBlock();
_blockRight = checkRightBlock();
_blockLeft = checkLeftBlock();
}
private bool checkUpBlock() {
bool hitMiddle = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y + _height),
Vector2.up, CheckDistance, BlockLayer);
bool hitLeft = Physics2D.Raycast(new Vector2(transform.position.x + (_width - 0.2f), transform.position.y + _height),
Vector2.up, CheckDistance, BlockLayer);
bool hitRight = Physics2D.Raycast(new Vector2(transform.position.x - (_width - 0.2f), transform.position.y + _height),
Vector2.up, CheckDistance, BlockLayer);
if (hitMiddle || hitLeft || hitRight) return true;
return false;
}
private bool checkDownBlock() {
bool hitMiddle = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y - _height),
Vector2.down, CheckDistance, BlockLayer);
bool hitLeft = Physics2D.Raycast(new Vector2(transform.position.x + (_width - 0.2f), transform.position.y - _height),
Vector2.down, CheckDistance, BlockLayer);
bool hitRight = Physics2D.Raycast(new Vector2(transform.position.x - (_width - 0.2f), transform.position.y - _height),
Vector2.down, CheckDistance, BlockLayer);
if (hitMiddle || hitLeft || hitRight) return true;
return false;
}
private bool checkRightBlock() {
bool hitMiddle = Physics2D.Raycast(new Vector2(transform.position.x + _height, transform.position.y),
Vector2.right, CheckDistance, BlockLayer);
bool hitLeft = Physics2D.Raycast(new Vector2(transform.position.x + _height, transform.position.y + (_width - 0.2f)),
Vector2.right, CheckDistance, BlockLayer);
bool hitRight = Physics2D.Raycast(new Vector2(transform.position.x + _height, transform.position.y - (_width - 0.2f)),
Vector2.right, CheckDistance, BlockLayer);
if (hitMiddle || hitLeft || hitRight) return true;
return false;
}
private bool checkLeftBlock() {
bool hitMiddle = Physics2D.Raycast(new Vector2(transform.position.x - _height, transform.position.y),
Vector2.left, CheckDistance, BlockLayer);
bool hitLeft = Physics2D.Raycast(new Vector2(transform.position.x - _height, transform.position.y + (_width - 0.2f)),
Vector2.left, CheckDistance, BlockLayer);
bool hitRight = Physics2D.Raycast(new Vector2(transform.position.x - _height, transform.position.y - (_width - 0.2f)),
Vector2.left, CheckDistance, BlockLayer);
if (hitMiddle || hitLeft || hitRight) return true;
return false;
}
}
@MadCoderr
Copy link
Author

moving one grid per unit source was being taken from here http://wiki.unity3d.com/index.php/GridMove

@nmcdougal94
Copy link

Is there any reason the private vector _startPos is indented differently?

@MadCoderr
Copy link
Author

The script has been updated, fixed some bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment