Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411613 Posts in 69390 Topics- by 58447 Members - Latest Member: sinsofsven

May 09, 2024, 05:10:31 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Physics2D and Collisions are driving us crazy
Pages: [1]
Print
Author Topic: Physics2D and Collisions are driving us crazy  (Read 2448 times)
Little Miracles Games
Level 0
**



View Profile WWW
« on: July 28, 2016, 12:52:19 PM »

Hi!

We're developing a 2D one-button platformer. The player’s character runs forward all the time, and pressing a key makes him jump. It's not an endless runner, though. When the player collides with a wall, it turns over and continues running in the opposite direction. After a lot of developing and testing, we’ve detected some bugs in our collision system (we’re using Unity).

Our character has a 2D circle collider. We have different types of rectangle colliders in the levels: walls to turn around, ground to let him jump when he’s standing on it and default to just don't let him pass through, used mainly in ceilings. Sometimes, because of the constant player movement, the character collides with more than one type of collider, for example in wall-ground corners. Using other kinds of colliders for the player (rectangles and so) makes the problem even worse, since hard pointy edge intersections tend to get stuck in places.

Talking about coding. We’re using the Physics2D.IsTouchingLayers() to detect the ground and the wall.

So, we're interested in the community point of view. How would you make this collision nightmare work? Any clues, alternatives or possible solutions?

Thanks!
Logged

quantumpotato
Quantum Potato
Level 10
*****



View Profile WWW
« Reply #1 on: July 28, 2016, 02:14:38 PM »

Can you flag the wall colliders with an attribute or a "turn around on collision" component and only turn the monster around when they reach that one?

I wonder if having a "last collided with" and "last collided at" could help you prevent multiple collisions from happening with the same wall. Like if you re-collide with the same object ID within .01 seconds, ignore.
Logged

bateleur
Level 10
*****



View Profile
« Reply #2 on: July 29, 2016, 02:49:00 AM »

The setup you've described sounds fine. Multiple collisions at once aren't a problem as such - just process each one separately as you would if it happened in isolation.

You may need to sanity check some outcomes to make sure there are no cases where the character you can do something you didn't intend. No one method will always work for that, though, because what you need to catch depends on your level design. For example, you can imagine a lobster-pot sort of thing where the character falls in and then finds itself wedged between two walls of slightly less than its own width apart. No reasonable algorithm is going to rescue that situation, so you need to limit the level design to things you can handle.
Logged

ThemsAllTook
Administrator
Level 10
******



View Profile WWW
« Reply #3 on: July 29, 2016, 07:39:13 AM »

Does your collision detector give you a normal vector? I'd probably fix this by using dot product to determine whether the angle of collision is vertical enough to count as a wall.
Logged

Reyn
Level 0
***



View Profile
« Reply #4 on: August 03, 2016, 08:46:58 AM »

The Unity video tutorials have a solution for your problem but I cant seem to find the video...

Anyway their solution is to use Physics2D.Overlap functions like this:

bool IsOnWallRight = Physics2D.OverlapCircle (wallcheck_1.position, 0.01f, layerMask);
bool IsOnWallLeft = Physics2D.OverlapCircle (wallcheck_2.position, 0.01f, layerMask);


The green diamonds are the wallcheck transforms, the orange ones are for detecting floor collisions, I havent had any problems implementing jumps, walljumps and grabbing on ledges this way.
In your case I guess you can switch directions when it goes from false to true (not every frame it stays true).

https://docs.unity3d.com/ScriptReference/Physics2D.html


ThemAllTook solution doesnt work that well with circle colliders, but you can just change you character collider for a box and it will work fine.


Logged
eerr
Level 0
***


View Profile
« Reply #5 on: August 03, 2016, 07:25:13 PM »

Code:
bool IsOnWallRight = Physics2D.OverlapCircle (wallcheck_1.position, 0.01f, layerMask);
bool IsOnWallLeft = Physics2D.OverlapCircle (wallcheck_2.position, 0.01f, layerMask);
As someone who doesn't know what they're doing,
That really helps! I've been dabbling to make smooth platformer physics for ages.
Logged
readyplaygames
Level 2
**


View Profile WWW
« Reply #6 on: August 04, 2016, 11:07:01 AM »

The Unity video tutorials have a solution for your problem but I can't seem to find the video...

I couldn't find the video either. Thanks for posting the answer.
Logged
Marc Marfà
Level 0
*


View Profile
« Reply #7 on: August 24, 2016, 11:14:14 AM »

Thank you very much everyone for the contributions.
We've decided to use raycast to detect the ground and walls. The results have improved a lot.
Logged
0xDEADBAAD
Level 0
**

Hooker with a penis


View Profile WWW
« Reply #8 on: August 25, 2016, 11:04:01 AM »

Sounds like your circle collider is overlapping your walls deeper than the distance you move the next frame after you change your direction, so in the next frame Collider.IsTouchingLayers() is still true.

There are many ways to solve this, but I believe the simplest is to just set your player's rigidbody collision detection to "Continous". This is, of course, more costly but I don't think it'll be a problem.

You could also use raycasts or manually move the player out of the wall when you touch it but, as I said, continuous collision detection should be enough Smiley.
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic