添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

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.)