Raycast issue

Hey there,

I’m facing an issue with Raycasting. I have an enemy call Slime which is chasing a target, the Player. I would like to know if the Slime can see the Player, so I am using the raycastFirst to know if the first rigidBody from my Slime to the Player is the Player (i.e. has a direct view on it).
However, raycastFirst keep returns null. Here is a link to my project: PlayCanvas | HTML5 Game Engine. I made sure that both my Player and my Slime have collision/rigidBody. The code is in Scripts/Scene/MainScene/Character/Slime/slimeAi.js in the function updateCanSeeTarget.

Thank you for your help.

Hi @Ougogogadget! The script below causes this problem, so there is a problem with your setup of the layers. If you disable this script, it will work as expected.

image

Hi there Albertos!

Shouldn’t this be considered a bug?
Both the slime and the player’s rigidbodies collide with each other properly, so the layers setup makes sense for this use-case. Its the raycast feature that fails. I did not take a look at the implementation of raycastFirst method, but it feels like a buggy behaviour.

Did some more testing!
I tried a bunch of number values for maskCharacters by hand.

Sounds weird but every even number I tried failed to raycast (although collisions worked well).
On the other hand, every odd number worked well with both collisions and raycasting. So I think this definitely needs to be considered a bug.

For now @Ougogogadget, you can just add 1 to the mask value you are calculating (remember the first 8 bits are reserved for the engine, so from 256 and on, and no rigidbodies should have a value less than 256)

I’d like to ask @LeXXik to take a look at this.

Hi,

Yes, so currently PlayCanvas raycastFirst method does not support using masks filtering. If you use groups/masks, then I would recommend you to use your own raycast method, which would apply the filters to the raycast callback. Here is an example:

SlimeAi.v1 = new Ammo.btVector3();
SlimeAi.v2 = new Ammo.btVector3();
SlimeAi.prototype.raycastFirst = function(start, end) {
    let result = null;

    const ammoRayStart = SlimeAi.v1;
    const ammoRayEnd = SlimeAi.v2;
    
    ammoRayStart.setValue(start.x, start.y, start.z);
    ammoRayEnd.setValue(end.x, end.y, end.z);
    const rayCallback = new Ammo.ClosestRayResultCallback(ammoRayStart, ammoRayEnd);

    rayCallback.m_collisionFilterGroup = pc.BODYGROUP_DYNAMIC | pc.BODYGROUP_USER_1;
    rayCallback.m_collisionFilterMask = pc.BODYGROUP_DYNAMIC | pc.BODYGROUP_USER_1 | pc.BODYGROUP_USER_2 | pc.BODYGROUP_USER_3;

    this.app.systems.rigidbody.dynamicsWorld.rayTest(ammoRayStart, ammoRayEnd, rayCallback);
    if (rayCallback.hasHit()) {
        const collisionObj = rayCallback.get_m_collisionObject();
        const body = Ammo.castObject(collisionObj, Ammo.btRigidBody);
        if (body) {
            const point = rayCallback.get_m_hitPointWorld();
            const normal = rayCallback.get_m_hitNormalWorld();

            result = new pc.RaycastResult(
                body.entity,
                new pc.Vec3(point.x(), point.y(), point.z()),
                new pc.Vec3(normal.x(), normal.y(), normal.z())
            );
        }
    }

    Ammo.destroy(rayCallback);

    return result;
};
3 Likes

It seems like it is working, I just change line 13 and 14 for those following lines:

rayCallback.m_collisionFilterGroup = this.entity.rigidbody.group;
rayCallback.m_collisionFilterMask = this.entity.rigidbody.mask;

But it’s specific to my case. However, I am now afraid of my application performances especially if I have multiple slimes at the same time. But thank you for your help!

1 Like

I think I have a new problem since I added your raycasting method. This error is sometimes triggered :

[[ammo.wasm.js?id=91662056&branchId=79b9a290-605e-4cf9-abd7-4be8491c27ba&t=6b7ab3989e4f9f17c86e44380f9181c6:77]](https://playcanvas.com/editor/code/951628?tabs=91662056&line=77&col=12&error=true): TypeError: b.asm.ac is undefined