Trying to collide in grid like movement
Haven't played around with Unity in a while, this is probably simple, but I haven't tried the tutorials in a while. I'm trying to make a small FF/Dragon Quest like RPG. I'm trying to get a character to move, in a grid-like way, which I succeded thanks to a youtube tutorial. I'm having dificulties getting my character to not go through walls. This is a 2D project, I imported a map with Tiled2Unity, so the walls are Polygon Collider 2D. This is my PlayerMovement script so far.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum DIRECTION { UP, DOWN, LEFT, RIGHT }
public class PlayerMovement : MonoBehaviour {
public int speed = 5;
private int buttonCooldown = 0;
private bool canMove = true;
private bool moving = false;
private DIRECTION dir = DIRECTION.DOWN;
private Vector3 pos;
// Use this for initialization
void Start () {
}
void OnTriggerEnter2D(Collider2D other){
if (other.tag == "Wall")
canMove = false;
}
// Update is called once per frame
void Update () {
buttonCooldown--;
if (canMove) {
pos = transform.position;
move ();
}
if (moving) {
if (transform.position == pos) {
moving = false;
canMove = true;
move ();
}
transform.position = Vector3.MoveTowards (transform.position, pos, Time.deltaTime * speed);
}
}
private void move(){
if (buttonCooldown <= 0) {
if (Input.GetKey (KeyCode.UpArrow)) {
if (dir != DIRECTION.UP) {
buttonCooldown = 5;
dir = DIRECTION.UP;
} else {
canMove = false;
moving = true;
pos += Vector3.up;
}
} else if (Input.GetKey (KeyCode.DownArrow)) {
if (dir != DIRECTION.DOWN) {
buttonCooldown = 5;
dir = DIRECTION.DOWN;
} else {
canMove = false;
moving = true;
pos += Vector3.down;
}
} else if (Input.GetKey (KeyCode.LeftArrow)) {
if (dir != DIRECTION.LEFT) {
buttonCooldown = 5;
dir = DIRECTION.LEFT;
} else {
canMove = false;
moving = true;
pos += Vector3.left;
}
} else if (Input.GetKey (KeyCode.RightArrow)) {
if (dir != DIRECTION.RIGHT) {
buttonCooldown = 5;
dir = DIRECTION.RIGHT;
} else {
canMove = false;
moving = true;
pos += Vector3.right;
}
}
}
}
}
So, once my character hits a wall, he can't move anymore. It's probably really simple, just haven't worked with this in a while, trying to get some more training in the summer, so appreciate the help.
Answer by Catralitos · Jul 11, 2018 at 09:07 AM
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum DIRECTION { UP, DOWN, LEFT, RIGHT }
public class PlayerMovement : MonoBehaviour {
public int speed = 5;
private int buttonCooldown = 0;
private bool canMove = true;
private bool moving = false;
private DIRECTION dir = DIRECTION.DOWN;
private Vector3 pos;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
buttonCooldown--;
if (canMove) {
pos = transform.position;
move ();
}
if (moving) {
if (transform.position == pos) {
moving = false;
canMove = true;
move ();
}
transform.position = Vector3.MoveTowards (transform.position, pos, Time.deltaTime * speed);
}
}
private void move(){
if (buttonCooldown <= 0) {
if (Input.GetKey (KeyCode.UpArrow)) {
if (dir != DIRECTION.UP) {
buttonCooldown = 5;
dir = DIRECTION.UP;
} else if (noWall(DIRECTION.UP)){
canMove = false;
moving = true;
pos += Vector3.up;
}
} else if (Input.GetKey (KeyCode.DownArrow)) {
if (dir != DIRECTION.DOWN) {
buttonCooldown = 5;
dir = DIRECTION.DOWN;
} else if (noWall(DIRECTION.DOWN)){
canMove = false;
moving = true;
pos += Vector3.down;
}
} else if (Input.GetKey (KeyCode.LeftArrow)) {
if (dir != DIRECTION.LEFT) {
buttonCooldown = 5;
dir = DIRECTION.LEFT;
} else if (noWall(DIRECTION.LEFT)) {
canMove = false;
moving = true;
pos += Vector3.left;
}
} else if (Input.GetKey (KeyCode.RightArrow)) {
if (dir != DIRECTION.RIGHT) {
buttonCooldown = 5;
dir = DIRECTION.RIGHT;
} else if (noWall(DIRECTION.RIGHT)){
canMove = false;
moving = true;
pos += Vector3.right;
}
}
}
}
private bool noWall(DIRECTION dir){
RaycastHit2D hitUp = Physics2D.Raycast(transform.position, Vector2.up, 1);
RaycastHit2D hitDown = Physics2D.Raycast(transform.position, Vector2.down, 1);
RaycastHit2D hitRight = Physics2D.Raycast(transform.position, Vector2.right, 1);
RaycastHit2D hitLeft = Physics2D.Raycast(transform.position, Vector2.left, 1);
if (dir == DIRECTION.UP && hitUp.collider == null){
return true;
}
if (dir == DIRECTION.DOWN && hitDown.collider == null){
return true;
}
if (dir == DIRECTION.LEFT && hitLeft.collider == null){
return true;
}
if (dir == DIRECTION.RIGHT && hitRight.collider == null){
return true;
}
return false;
}
}
This fixed the problem. Just mae sure to disable the Collider so the Raycast will work.
Why do you execute all the raycasts if u only need it for one direction?
private bool noWall(DIRECTION dir)
{
RaycastHit2D hit;
if (dir == DIRECTION.UP)
{
hit = Physics2D.Raycast(transform.position, Vector2.up, 1);
return hit.collider == null;
}
if (dir == DIRECTION.DOWN)
{
hit = Physics2D.Raycast(transform.position, Vector2.down, 1);
return hit.collider == null;
}
if (dir == DIRECTION.LEFT)
{
hit = Physics2D.Raycast(transform.position, Vector2.left, 1);
return hit.collider == null;
}
if (dir == DIRECTION.RIGHT)
{
hit = Physics2D.Raycast(transform.position, Vector2.right, 1);
return hit.collider == null;
}
return false;
}
To be honest, not a raycast expert, just adapted another script I found online for a simillar iusse. Gonna chaage to this, it is better thank you.
Your answer
Follow this Question
Related Questions
2D: Destroy object with dynamic collider after exiting object with static collider 1 Answer
Circle Collider2D Stuck ob Box Collider2D at the corner :( 0 Answers
Inconsistent 2d collider hit registration 3 Answers
2D colliders doesnt work with Gravity Scale = 0 0 Answers
Sprite 2d passes through the ground 0 Answers