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)
const speedFactor = -10;
bullets.forEach(b => {
ray.ray.origin.copy(b.position);
const inters = ray.intersectObjects(scene.children);
if(inters.length > 0) {
$(".debug").html("hit");
b.getWorldDirection(direction);
b.position.add(direction.multiplyScalar(speedFactor));
I had some previous attempts, but I never got to actually seeing yes on my screen, so, what could be possibly wrong?
Draw a arrow along your raycaster direction to see if its right
And console.log your intersects
Or make a live demo, for me, your code is not enough to help
Take a look at my example:
Use green arrow and aim whatever object you wish.
when raycaster detects object the object will change color
cadcamge.ch
I dont know if this is correct way to do intersection but for my case it helped me .
function castRay(){
requestAnimationFrame( castRay );
dir = camera.getWorldDirection( directionVector );
pos = camera.getWorldPosition( positionVector);
var raycaster = new THREE.Raycaster( pos, dir.normalize() );
var intersects = raycaster.intersectObjects( scene.children );
if( intersects.length>0 ){
itr++;
opacity += (1-0.6)/100;
center.style.opacity = 0.6 + opacity;
if( itr > 30 ){
intersects[0].object.material.color.set( 0xff0000 );
intersects[0].object.material.color.getHSL( colorHSL )
alpha += 0.01;
l = Math.abs( Math.cos( alpha ));
intersects[0].object.material.color.setHSL( colorHSL.h, colorHSL.s, l );
waiting = false;
else if( !waiting ){
itr = 0;
opacity = 0;
center.style.opacity = 0.6;
for( var i=0; i<arr.length; i++){
arr[i].material.color.set( 0xaaafff);
waiting = true;
castRay();
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();
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.)