How does KinematicBody test_move work exactly? [Godot3]

sankisanki Posts: 4Member

Hey,

I'm doing a blockout (3d tetris) test/warmup project.
I've got a block that moves on increments (down on timer, x and z axis controlled by player)

It's defined as KinematicBody with 4 blocks as children (each with it's own box mesh and box CollisionShape)

I've tried using test_move to move the piece inside well and stop on collisions, but it doesn't really do that.
here is a code that I've tried to make it go down

the well is a StaticBody with plane CollisionShape for each wall and floor

if not activePiece.test_move(activePiece.transform,Vector3(0,-1,0)):
    activePiece.global_translate(Vector3(0,-1,0))

doesn't matter if I use transform or global_transform.

Docs say:

bool test_move ( Transform from, Vector3 rel_vec )

Checks for collisions without moving the body. Virtually sets the node’s position, scale and rotation to that of the given Transform, then tries to move the body along the vector rel_vec. Returns true if a collision would occur.

but it always returns false in my case

When I use move_and_collide function it moves and stops whenever it touches well boundaries and won't continue down, which is expected as it should stop on collisions.

Tagged:

Tags :

Answers

  • TwistedTwiglegTwistedTwigleg Posts: 858Admin

    Well, it may be the function does not work. After going down the Github rabbit hole, I found this comment in space_sw.cpp line 544

    //give me back regular physics engine logic
    //this is madness
    //and most people using this function will think
    //what it does is simpler than using physics
    //this took about a week to get right..
    //but is it right? who knows at this point..

    So, it may be the function does not work correctly. That said, I'm not sure. Based on what I could find, you are indeed using it correctly. I would use global_transform just to be safe (since collisions are likely in world space) but other than that, I'm not sure.

    Maybe you can use raycasts to get around it? Since the blocks are moving downwards and (presumabily) colliding with other blocks (below and to the sides), you could try sending a ray from each face with length 1 (or however far you are moving per tick) and see if it collides with something. That way you can tell if something has collided based on whatever the raycasts are colliding with something or not.

  • sankisanki Posts: 4Member

    Thanks for reply.
    I was thinking about using raycasts, but figured kinematicbody collisions should be easier.
    Will do some testing and try to figure it out, maybe it will be worth bug reporting ;).

  • sankisanki Posts: 4Member
    edited February 4

    I've checked with simple KinematicBody cube setup, didn't work, I've tried with other collision shapes, didn't work.
    Tried with smoother smaller increments, didn't work.

    But I've checked it on a KinematicBody2D and it works just fine, with virtually same code adjusted for 2D.
    Also doesn't matter if physics are bullet or godot.

    So I've reported bug on github will see how it goes :(

  • TwistedTwiglegTwistedTwigleg Posts: 858Admin
    Answer ✓

    Yeah, its likely that the function is bugged. I'd suggest opening a Github issue on the Godot repository. Providing a example project will probably help them nail down the problem (based on the comment in the code, I think they may have not had a good test case).

  • sankisanki Posts: 4Member
    edited February 4

    I've got reply on github, it looks like it's bullet's physics bug, it works in godot native physics.
    But one more weird thing, had to swap collision shape from plane to box, as the plane shape didn't work

  • TwistedTwiglegTwistedTwigleg Posts: 858Admin

    Huh, strange. Well, good to know its a bug!

    I've also found that plane collision shapes don't work (but honestly I found using boxes more convenient anyway, as it can prevent some clipping issues you can get with planes)

Sign In or Register to comment.