Last active
April 1, 2022 09:04
-
-
Save MadCoderr/b0282e030eb7fb7a18fc14fdd6a12cdb to your computer and use it in GitHub Desktop.
Unity3d Pacman like movement
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
Is there any reason the private vector _startPos is indented differently?
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
moving one grid per unit source was being taken from here http://wiki.unity3d.com/index.php/GridMove