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.
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.
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)
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;
};
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!
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