I am working on a project where I want the player which is the white circle, to walk on the tilemap grid by grid when pressing WASD, and stop when there is a wall in front of the direction it is walking. But when i run the game and try to move the player around, it just goes through the wall. I have been solving this question for a while and i have no idea what i done wrong.
I have try to remove composite collider 2d, the player will get block by the wall. However sometimes when the player is running into the wall, it will get ricocheted off the side of the wall . For example, when the player is walking into the left side of the wall, it will get shoot off to the left and end up on the left of the wall. I try to reduce the speed of the player’s movement by reducing the moveTimePerGrid in my Player Movement Script and it does not work. I have also set layer for the player and walls, and set them to be able to collider with each other on the collider matrix but it does not work.
(https://i.sstatic.net/bmRXpIcU.png)
(https://i.sstatic.net/pBk8d02f.png)
(https://i.sstatic.net/ripO0jkZ.png)
user26436276 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1
Since you set the object’s position repeatedly to make the object move, unity’s collision resolution system does not work. If you want grid by grid movement that has collisions you will have to check for and resolve the collisions inside the MovePlayer function. You could use raycasts by putting something like this in the MovePlayer function:
if (Physics2D.Raycast(transform.position, direction, (transform.position
- targetPosition).magnitude) == 0){
// move the player because the raycast found no object in front of
// the player
transform.position = targetPosition;
}
else{
// player should not move because of an object in the way.
transform.position = playerPosition;
}
Kevin Ghossoub is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Moving a rigidbody has to be done within FixedUpdate
and you cannot use transform.position
, otherwise collisions will not be resolved.
For this though, I’d just use your rigidbody’s velocity
property, which will move for you. Your code should instead be something like:
[SerializeField] private Rigidbody2D body;
float movementEndTime;
void FixedUpdate() {
if (Time.time > movementEndTime) {
if (Input.GetKeyDown(KeyCode.W)) {
body.velocity = Vector2.up * (1f / moveTimePerGrid);
movementEndTime = moveTimePerGrid;
} else if (Input.GetKeyDown(KeyCode.A)) {
body.velocity = Vector2.left * (1f / moveTimePerGrid);
movementEndTime = moveTimePerGrid;
} else if (Input.GetKeyDown(KeyCode.S)) {
body.velocity = Vector2.down * (1f / moveTimePerGrid);
movementEndTime = moveTimePerGrid;
} else if (Input.GetKeyDown(KeyCode.D)) {
body.velocity = Vector2.right * (1f / moveTimePerGrid);
movementEndTime = moveTimePerGrid;
}
}
}