I have a weird problem. I have a standard character but he moves through walls even though he has a RigidBody. The TileMap has a tilemap collider attached and my Movement is handled here:
But my character still moves thorugh it. If i attach a static rb to the Tilemap my character just pushes all the Tiles with the rigidbody. Can someone help me? (is trigger is UNchecked)
I had a similar issue and resolved it using a RayCastHit2D checking for anything on the blockingLayer between my player position and where my player was attempting to move and if it found anything between the player and where they were trying to move they couldn’t move there otherwise the movement was completed successfully.
using System.Collections.Generic;
public RaycastHit2D hit;
this.GetComponent<BoxCollider2D>().enabled = false; //Disables the BoxCollider so RayCastHit2D does not collide with it.
hit = Physics2D.Linecast (start, end, blockingLayer); //Stores the results of the RayCastHit2D between the start Vector2 and end Vector2 ie. did it hit anything on the attempted move path.
this.GetComponent<BoxCollider2D>().enabled = true; //Re-enables the BoxCollider to that trigger events can again occur.
if (hit.transform == null) //Returns null if the RayCastHit2D did not hit anything on the blockingLayer ie. the RayCastHit2d did not hit a wall.
{
//Moves the player in the intended direction.
startPosition = transform.position;
newPosition = new Vector2 (joystick.Horizontal * speed, joystick.Vertical * speed);
transform.position = (startPosition + newPosition);
}
that is the basis of what triggered the movement or not.
I am guessing you are using something similar to the game manager from the 2D roguelike tutorial which implements the blocking layer.
Attached is my player controller script for reference (note I control my player with an on screen joystick which is why my script utilizes joystick.Horizontal and joystick.Vertical but the script can be modified to account for keyboard input as well)
Hopefully you can make sense of my mess of comments and Frankenstein this to your purposes.
If you want any clarification on any of it feel free to ask
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
protected Joystick joystick; //requires the asset store add-on for Fixed Joystick.
public float speed; //Needs to be set in the inspector.
public Vector2 newPosition;
public Vector2 startPosition;
public BoxCollider2D boxCollider;
private Vector2 start;
private Vector2 end;
public RaycastHit2D hit;
public LayerMask blockingLayer;
public Vector2 endTest;
void Start ()
{
joystick = FindObjectOfType<Joystick> (); //This finds the on screen joystick as there is only one in this scene.
newPosition = transform.position; //This is just to store a Vector2 of the current position.
}
void Update()
{
//This checks for player input from the on screen joystick during each frame update.
if(joystick.Horizontal != 0 || joystick.Vertical != 0)
{
Vector2 endTest = new Vector2(joystick.Horizontal * speed, joystick.Vertical * speed); //Sets a Vector2 equal to where the player is attempting to move.
Vector2 start = transform.position; //Sets a Vector2 of where the player currently is.
Vector2 end = (start + endTest); //Sets a Vector2 of where the player will be when they complete the attempted movement.
this.GetComponent<BoxCollider2D>().enabled = false; //Disables the BoxCollider so RayCastHit2D does not collide with it.
hit = Physics2D.Linecast (start, end, blockingLayer); //Stores the results of the RayCastHit2D between the start Vector2 and end Vector2 ie. did it hit anything on the attempted move path.
this.GetComponent<BoxCollider2D>().enabled = true; //Re-enables the BoxCollider to that trigger events can again occur.
if (hit.transform == null) //Returns null if the RayCastHit2D did not hit anything on the blockingLayer ie. the RayCastHit2d did not hit a wall.
{
//Moves the player in the intended direction.
startPosition = transform.position;
newPosition = new Vector2 (joystick.Horizontal * speed, joystick.Vertical * speed);
transform.position = (startPosition + newPosition);
}
}
}
}
Also worth mentioning is for this to function correctly you need the RigidBody2D of the player to be set to “IsKinematic” and BoxCollider component to be set to “IsTrigger” as well as have the box colliders for the walls set to “is trigger” and the blocking layer and player box collider need to be assigned (drag and drop) in the inspector
Thanks for your answer ! I actually fixed it now by making the Rigidbody of the player Dynamic instead of Kinematic and setting the gravity scale to 0 and freeze rotation on the Z axis. Your solution works as well i just tested it. Thank you very much