- Home /
Simple top-down 2D collision
I'm trying to build my first game using the 2D features in Unity. I've got character movement working for now, but I'm having trouble implementing player collision with the blocking layer (walls, etc). This is the code I've tried so far:
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
public float Speed = 2.0f;
public LayerMask BlockingLayer;
private BoxCollider2D _BoxCollider;
private Rigidbody2D _Rigidbody;
private Animator _Animator;
// Use this for initialization
void Start ()
{
this._BoxCollider = this.GetComponent<BoxCollider2D>();
this._Rigidbody = this.GetComponent<Rigidbody2D>();
this._Animator = this.GetComponent<Animator> ();
}
// Update is called once per frame
void Update ()
{
int horizontal = (int) Input.GetAxisRaw("Horizontal");
int vertical = (int) Input.GetAxisRaw ("Vertical");
if (vertical != 0)
{
horizontal = 0;
}
if (horizontal != 0 || vertical != 0)
{
this.Move (horizontal, vertical);
}
else
{
this.Idle();
}
}
private void Move(int horizontal, int vertical)
{
this.AnimateMovement(horizontal, vertical);
this.Move(new Vector2(horizontal, vertical));
}
private void Move(Vector2 direction)
{
/*if (this._BoxCollider.IsTouchingLayers(this.BlockingLayer))
{
return;
}*/
//this._Rigidbody.velocity = direction * this.Speed * Time.deltaTime;
Vector2 start = this.transform.position;
Vector2 end = start + direction * this.Speed * Time.deltaTime;
RaycastHit2D hit = Physics2D.Linecast (start, end, BlockingLayer);
if (this._BoxCollider.IsTouchingLayers(this.BlockingLayer) && null != hit)
{
return;
}
Vector3 newPosition = new Vector3(end.x, end.y, 0f);
this._Rigidbody.MovePosition (newPosition);
/*if (this._BoxCollider.IsTouchingLayers(this.BlockingLayer))
{
this._Rigidbody.MovePosition (start);
}*/
}
void OnCollision2D(Collision2D collision)
{
/*if (collision.gameObject.layer == this.BlockingLayer)
{
this._Rigidbody.velocity = Vector2.zero;
}*/
}
void OnTriggerEnter(Collider other)
{
//if (collision.gameObject.layer != this.BlockingLayer)
//{
// return;
//}
//this._Rigidbody.velocity = Vector2.zero;
}
void OnTriggerStay(Collider collider)
{
//this._Rigidbody.velocity = Vector2.zero;
}
private void AnimateMovement(int horizontal, int vertical)
{
int direction = 0;
if (vertical > 0)
{
direction = 2;
}
else if (vertical < 0)
{
direction = 4;
}
else if (horizontal > 0)
{
direction = 1;
}
else if (horizontal < 0)
{
direction = 3;
}
this._Animator.SetInteger ("Direction", direction);
}
private void Idle()
{
this._Rigidbody.velocity = Vector2.zero;
this._Animator.SetInteger("Direction", 0);
}
}
Both the character and the walls have both a kinematic Rigidbody2D and a BoxCollider2D. Currently what happens is that the player is correctly blocked by walls, but then they are no longer able to move at all after the collision. Is there a standard solution for doing this sort of collision?
Answer by Cherno · Jun 23, 2015 at 10:03 AM
Is there any reason why you are using kinematic rigidbodies? These only register trigger collisions and don't block movement correctly. Your code behaves as expected: If a trigger (wall collider) is touched, the rigidbody completely stops moving. What should probably happen is that it can't go any further into the wall, but otherwise move in any direction, including "scraping" along the wall. To achieve this, set the rigidbodies to be not kinematic, and their colliders to not be triggers (player and walls). Also, it's uncommon to let the walls, or any other static colliders, have rigidbodies. Normally, a collider for such objects is enough. Only if the wall itself should behavor physically realistic does it really need a rigidbody, but since it should just sit there and block collisions by actors, that's not needed and also helps performance.
So, basically... what lloladin said ;)
Answer by lloladin · Jun 23, 2015 at 09:06 AM
you acheiv this without any code really by just applying a rigibody and 2collider to youre player and boxcollider to youre wall
here is a link where someone explains how to make a 2d game really well
https://www.youtube.com/watch?v=86Bgt--Ww7w&list=PLiyfvmtjWC_Up8XNvM3OSqgbJoMQgHkVz
Shouldn't matter because the only things different are gravity and axis orientation.