GML 3D Wall Clipping

So I'm working on a 3D platformer of sorts and I've run into a clipping issue with walls. Using the code from the old Gamemaker fps tutorial, I can get the character to slide along walls however If the player is moving too fast and collides with the corner of 2 wall objects, the player will clip into the wall they are facing. Depending on the players speed, they can even just pass through the wall as if it's not even there. What can I do to fix this?
From player object, if it collides with the objWall_Par
Code:
//Platform collision. Ensures the player doesn't phase through the platform if they are on top of it
if (z<other.zheight+8 && z >= other.zheight- 8 && (z_speed<=0))
{

    if (action == action_jumping||action == action_fan)
    {
        if completed=false
        {
            action = action_normal;
        }
    }
   //Force the player to be at the max height of the ground
    z = other.zheight;
    ground = true;
    z_speed = 0;
 
}

//If above the zheight of the floor, ground = false as there is nothing is keeping the player from dropping from gravity
if (z>other.zheight  )
{
    ground = false;
}


//If player z position not on top of the wall object
if (z > other.zUnder && z<other.zheight)
    {
        //Prevent movement unless..
        x = xprevious;
        y = yprevious;

       
        if (!place_meeting(x+hspeed,y,other))
        {
            x += hspeed;
        }
        else
        {
            x = xprevious;
        }
   
        if (!place_meeting(x,y+vspeed,other))
        {
            y += vspeed;
        }
        else
        {
            y = yprevious;
        }
   
    }
Before I made a small modification to the code, this issue never happened.
At this point, I don't understand what is causing it and any help would be appreciated.
 
Note: Realised there should be a 48 hour gap between bumps. Thought I posted this earlier...Won't happen again.

So Bumping as haven't gotten any closer to fixing it at the moment.

For sake of comparison, the original code had only one difference where instead of checking for the object it collided with but instead the parent object instead. Also should add that the wall collisions are based off the old fps tutorial for gm6 if that helps.
Code:
//If player z position not on top of the wall object
if (z > other.zUnder && z<other.zheight)
   {
       //Prevent movement unless..
       x = xprevious;
       y = yprevious;

  
       if (!place_meeting(x+hspeed,y,objWall_Parent))
       {
           x += hspeed;
       }
       else
       {
           x = xprevious;
       }
 
       if (!place_meeting(x,y+vspeed,objWall_Parent))
       {
           y += vspeed;
       }
       else
       {
           y = yprevious;
       }
 
   }
Also, bug in action and context on what I'm making.

Hope anyone can provide some assistance.
 
Last edited:
F

Fishman1175

Guest
Place meeting is bad because it depends on the size of the sprites collision mask, and if the player is moving fast enough they will not collide with a wall.

There are lots of alternatives. I think the quickest way would be to stop using place_meeting and use collision_line instead. The line consists of two points. The first point is where you were before moving. The second point would be where you ended up after moving (or where you will end up, depending on where you put the code). If that line collides with a wall then you know you're hitting a wall.
 
Place meeting is bad because it depends on the size of the sprites collision mask, and if the player is moving fast enough they will not collide with a wall.

There are lots of alternatives. I think the quickest way would be to stop using place_meeting and use collision_line instead. The line consists of two points. The first point is where you were before moving. The second point would be where you ended up after moving (or where you will end up, depending on where you put the code). If that line collides with a wall then you know you're hitting a wall.
Hi, Thank you for the response. I tried replacing place_meeting with Collision Line however now the player character now ignores collisions altogether. Just to clarify, the collision coding is been called through the collision event. Would it be better if the collision line was been called through the step event for example for line_collision?

Here my code for reference:
Code:
        //if (!place_meeting(x+hspeed,y,other)) // Original check for comparison
         
        if (!collision_line(xprevious,yprevious,x+ hspeed,y,other,false,true))
        {
            x += hspeed;
        }
        else
        {
            x = xprevious;
        }
//Vice versa for y variation.
I tried making modifications to the above line of code hoping to get it to work. Removing the ! Or changing the xy coordinates. Removing the ! does allow collisions though I don't think it's because of the coding+ the character gets stuck on the wall instead of sliding along it.

Edit: Additionally, I have added some coding which limits the players speed if they are colliding with a wall. While it does stop them from phasing through wall, you can still get partially stuck.
 
Last edited:
Bump.
Still got the collision issue. Due to the speed cap that occurs when the player triggers wall collisions, the clipping is reduced slightly though it is still a problem. I attempted the Collision Line Method that Fishman1175 mentioned but I couldn't get it to work.
 
Bump.

Attempted to group wall objects using the collision Rectangle to assign multiple ids to a single id to collide with. Didn't seem to work.

Code:
Wall_Collision = collision_rectangle(x-hspeed,y-vspeed,x+hspeed,y+vspeed,objWall_Par,false,true)
I called that from the step event. In the collision event, i then changed other to the Wall_Collision in hopes it would work.

Again to clarify, colliding with a single wall object is fine. It's only if the player collides with 2 wall objects that the clipping occurs.

Another detail, I originally checked for the wall parent instead of using the Other tag. While the clipping issue never occurred while it was using the old coding, it prevented the player from sliding along walls if the player was standing on a block & colliding with another wall.
Instead of sliding, the player would get caught on the walls until the player is facing the right angle.(which was when there is no collision)

That bug was because it was checking for a collision and the floor of the block was also been considered in the collision. With Other, it changed it so that it only focused on the one object which is where I'm at now.
 
Top