Hi, so, Im currently trying to make a shooter game on my own, just to simply expand my knowledge, anyway, Im trying to somewhat understand the concept of Raycaster. Lets say I have a bullet, once the bullet hits an object (gets to an intersection), it will let me know, currently, this is how my code looks:
(Before animate) const ray = new THREE.Raycaster();
(Animate)
There are other properties like near and far you can try.
Also if you have objs that are grouped, you can try to use ray.intersectObjects(scene.children, true) The second param will search recursively through the group of objs
Use world position instead of position (if your bullet is within any kind of container, position becomes a local transform):
If your scene contains grouped objects / objects with submeshes, enable recursive intersections when raycasting.
In real-life situation, you probably don’t want to intersect the entire scene - limit testing to only the objects that care about bullets hitting them.
You don’t have to modify origin directly - using Raycaster.set lets you override both origin and direction.
const position = new Three.Vector3();
const direction = new Three.Vector3();
const raycaster = new Three.Raycaster(new Three.Vector3(), new Three.Vector3(), 0.0, 100.0);
const speedFactor = 10.0;
bullets.forEach(bullet => {
bullet.getWorldPosition(position);
bullet.getWorldDirection(direction);
raycaster.set(position, direction);
const hits = raycaster.intersectObjects(scene.children, true);
if (hits[0]) {
// Hit
}
bullet.position.add(direction.multiplyScalar(speedFactor).negate());
direction.normalize();
});
Hi! The code works perfectly! But for some reason, even when I shoot just into the air (where no object children is) it says hit. I switched from scene.children to map.children but this still ocurs, Ill is there any workaround?
Isn’t by any chance bullet also a part of scene / map.children? In this case raycaster is probably colliding with the bullet itself. You can try offsetting the ray a little to the front (if it’s still colliding, offset it a bit more - it depends on the size of the model):
const position = new Three.Vector3();
const direction = new Three.Vector3();
const raycaster = new Three.Raycaster(new Three.Vector3(), new Three.Vector3(), 0.0, 100.0);
const speedFactor = 10.0;
bullets.forEach(bullet => {
bullet.getWorldPosition(position);
bullet.getWorldDirection(direction);
raycaster.set(
position.add(direction.clone().multiplyScalar(2.0), // <- offset ray to start a little in-front of the bullet
direction
);
const hits = raycaster.intersectObjects(scene.children, true);
if (hits[0]) {
// Hit
}
bullet.position.add(direction.multiplyScalar(speedFactor).negate());
direction.normalize();
});
That’s why it’s a good idea to store a list of “shootable” objects in a separate array - an test only against them (since you don’t really want bullets to collide with themselves or each other - that’s just poor player experience.)