Search code examples
c#xnacollisionsliding

Sliding with collision using OBB


In my C# 3D game: I have a OBB (orientated bounding box) for my wall. My player is another tiny obb. I have good collision detection use SAT (separating axis theorem). When the collision occurs I have the old position of the player (where no collision occurred) and the position change the player experienced. To calculate the new position I use: Position = OldPosition + PositionChange; I also have a function which detects when I am colliding with any Wall in my world, It will return null if there is no collision and it will return an Wall if there is a collision. A Wall is a class I have added which has a model, OBB, and position. If (IntersectsAnyWall() == null) //no collision

That works well however I don't have sliding working. By sliding I mean when the player walks into a wall at an angle he slides along it instead of just stopping. Splitting the movement up into X and Z components and then testing both of them separately creates a jittering effect which is not what I want.

Can anyone give me a suggestion on how to approach sliding with OBB collision?


Solution

  • The wall can be modelled to stop only movements in the wall's normal's direction. In order to allow sliding, you have to find the wall's normal at the collision site. Furthermore, it would be a good idea to calculate, how deep the collision has taken place. Then all you have to do is subtract the "unpassable" part:

    Position = OldPosition + PositionChange
    if(IntersectsAnyWall() != null)
    {
        var normal = //wall's normal at collision site
        var collisionDepth = ...;
        Position += collisionDepth * normal;
    }
    

    If you can't calculate the collision depth, you may also subtract the entire part along the normal:

    Position = OldPosition + PositionChange
    if(IntersectsAnyWall() != null)
    {
        var normal = //wall's normal at collision site
        var partAlongNormal = Vector2.Dot(PositionChange, -normal);
        Position += partAlongNormal * normal;
    }