Prevent Player from passing through walls
I swear I've looked all over for solutions to this problem before posting. I know the solution exists somewhere because this appears to be a common problem and it can't possibly have an incredibly complex solution, but I just haven't found it yet and I need help.
I'm making a 2d game in Unity. I have two "Sprite" game objects, one that represents the player with a circle collider, a kinematic rigidbody2D and one that is an obstacle with a square collider. My intent is for the
I'm moving the player via transform.position by getting input from the arrow keys to determine a destination vector and Lerping from the current position towards the intended direction. Movement through this method works exactly as intended on its own.
When the player object encounters any other game object, it passes through as though the obstacle is in the foreground and the player is in the background. These obstacles are intended to be static colliders.
Based on Unity's manual, a kinematic rigidbody doesn't provide a collision with a static collider, but it does produce a trigger. However, when the obstacles are set to "Is Trigger," the player still passes through. All objects have the same Z values (they aren't actually passing underneath each other).
I can make them collide if I give the obstacles rigidbodies, but then they are no longer stationary. They are effected by gravity and are moved when the player runs into them. Setting gravity scale to 0 fixes the gravity problem, but no matter how high the mass is, the player still moves them on contact. If make the obstacle's rigidbody2D kinematic, then it goes back to not colliding.
So I seem to have one of two problems:
How do I use OnTriggerEnter2D to enforce the boundaries of an object programmatically?
How do I move the player as a non-kinematic, totally regular rigidbody2D with the arrow keys based on player input?
I don't know which is actually my problem or how to solve either one.
Answer by Trigary · Jan 30, 2016 at 07:01 AM
Triggers aren't colliders. Think of them as lasers. If something steps into them, they will detect it, but won't stop it from colliding. You only need basic colliders to solve your issue.
You seem to move the object by modifying its position, right? You don't want to do that, physics don't like it. You can add a force to the object to make it move (AddForce), or you can set a velocity vector (Vector2 velocity). I think the second one is the easier, but some people say it's not correct to modify the velocity of an object directly, only in some cases, but feel free to use it :)
Here's a script :
Put this below MonoBehaviour:
private Rigidbody2D PlayerObject;
This goes to the "Start" "section":
PlayerObject = GetComponent<Rigidbody2D>();
This to the FixedUpdate:
float inputX = Input.GetAxisRaw ("Horizontal");
float inputY = Input.GetAxisRaw ("Vertical");
//GetAxisRaw is 0 or 1, GetAxis changes from 0 to 1, from 1 to 0, not instantly.
if (inputX != 0 && inputY != 0) {
PlayerObject.velocity = transform.up * speed.y * inputY + transform.right * speed.x * inputX;
}
Ooups, forgot the arrow keys, here you go: http://docs.unity3d.com/ScriptReference/Input.GetKey.html