Game Development Community

Problem shooting people in 3rd person view

by Terence Tan · in Torque Game Engine · 06/23/2006 (6:23 am) · 2 replies

Hi,

I am trying to shoot these korks in 3rd person view:

www.posdreams.com/TORQ.jpg

My first try was to use Dave Myers Object selection resource to some success. I was able to select 'objects' and alternate my projectiles vector to hit them.

So I thought about raycasting from the players eye position straight out. I set pitch to zero (yaw is controlled by my mouse cursor).

%player = %client.player;

   //Determine how far should the picking ray extend into the world?
   %selectRange = 400;

   %forwardVec = %player.getEyeVector();
	 
  %forwardScaled = VectorScale(%forwardVec, %selectRange);

   // Search for anything that is selectable – below are some examples
   %searchMasks = $TypeMasks::PlayerObjectType | $TypeMasks::CorpseObjectType |
                  $TypeMasks::ItemObjectType | $TypeMasks::TriggerObjectType;

 //     %scanTarg = ContainerRayCast (%cameraPoint, %rangeEnd, %searchMasks);
		echo("Trying to target somebody");
	//	%pos = getBoxCenter(%player.getWorldBox());
		
    %scanTarg = ContainerRayCast (%player.getPosition(), %forwardScaled, %searchMasks,%player);

It doesn't work (or works intermittently)..

So now I'm stumped, have a bad cold and a headache. I do have access to the screen coordinates (and unprojected world coordinates)..so my best next guess is to figure out how to ray cast from the player position(and or box center) to a tranformed world coordinate??? By the camera perhaps?

Apologize if i mispell anything or typed something about dancing pink elephants...cough cough

#1
06/24/2006 (12:29 am)
Still haven't figure out how to properly select objects. What I tried is:

1) Ray cast from the camerpos to the clickpos using the mousevec until it hits a terrain
2) Offset the terrain position by 5 units to cater for height
3) ray cast again from player eye position to the new terrain position to see what I hit.

Doing 2 ray casts seems a bit excessive but I am unsure how else to approach this. It still doesn't work either.

See code:
//Determine how far should the picking ray extend into the world?
   %selectRange = 400;

   // scale mouseVec to the range the player is able to select with mouse
   %mouseScaled = VectorScale(%mouseVec, %selectRange);

   // cameraPoint = the world position of the camera
   // rangeEnd = camera point + length of selectable range
   %rangeEnd = VectorAdd(%cameraPoint, %mouseScaled);

   // Search for anything that is selectable – below are some examples
//   %searchMasks = $TypeMasks::PlayerObjectType | $TypeMasks::CorpseObjectType |
//                  $TypeMasks::ItemObjectType | $TypeMasks::TriggerObjectType;

	  %searchMasks = $TypeMasks::TerrainObjectType;
	  
   // Search for objects within the range that fit the masks above. If we are
   // in first person mode, we make sure player is not selectable by setting
   // fourth parameter (exempt  from collisions) when calling ContainerRayCast
   %player = %client.player;

   %target = ContainerRayCast (%cameraPoint, %rangeEnd, %searchMasks);
   
   if (%target)
   {
   		%xx = getWord(%target, 1);
   		%yy = getWord(%target, 2);
   		%zz = getWord(%target, 3);
   		%nx = getWord(%target, 4);
   		%ny = getWord(%target, 5);
   		%nz = getWord(%target, 6);
   		%height = 6;  // Height of average character
   		%normal = %nx SPC %ny SPC %nz;
   		%finalPos = %xx SPC %yy SPC %zz;
   		%finalPos = VectorAdd(%finalPos,VectorScale(%normal,%height));
   		echo ("Terrain found ",%finalPos);
   		
   		%playerEye = %player.getEyePoint();
   		%viewVec = VectorSub(%finalPos,%playerEye);
   		%viewVec = VectorNormalize(%viewVec);

   		%endPoint = VectorAdd(%playerEye, VectorScale(%viewVec, 50));
 
   		%searchMasks = $TypeMasks::PlayerObjectType;
   		%scanTarget = ContainerRayCast (%playerEye,%endPoint, %searchMasks,%player);
   		
   		echo ("Scan for target from ",%playerEye, " to " , %endPoint);
   		
   		if (%scanTarget)
   		{
   			  echo("Player found at location");
   			  %targetObject = firstWord(%scanTarget);
      		%client.setSelectedObject(%targetObject);
   		}
   }

I'm missing something stupid aren't I?
#2
06/28/2006 (8:22 pm)
After a little of testing I finally settled on:

- In the initial ray trace, if the object hit is a terrain then use the X,Y,Z location as the target
- If the object is a character then set it as the target

It seems to work well enough for now, until I get more significant gameplay working. For some reason using the elevated normal from the terrain didn't seem to work well. The problem I had was also that the height units are in meters so a 6m character stupid

//Determine how far should the picking ray extend into the world?
   %selectRange = 400;

   // scale mouseVec to the range the player is able to select with mouse
   %mouseScaled = VectorScale(%mouseVec, %selectRange);

   // cameraPoint = the world position of the camera
   // rangeEnd = camera point + length of selectable range
   %rangeEnd = VectorAdd(%cameraPoint, %mouseScaled);

   // Search for anything that is selectable – below are some examples
//   %searchMasks = $TypeMasks::PlayerObjectType | $TypeMasks::CorpseObjectType |
//                  $TypeMasks::ItemObjectType | $TypeMasks::TriggerObjectType;

	  %searchMasks = $TypeMasks::TerrainObjectType | $TypeMasks::PlayerObjectType;
	  
   // Search for objects within the range that fit the masks above. If we are
   // in first person mode, we make sure player is not selectable by setting
   // fourth parameter (exempt  from collisions) when calling ContainerRayCast
   %player = %client.player;

   %target = ContainerRayCast (%cameraPoint, %rangeEnd, %searchMasks,%player);
   
   if (%target)
   {
		  %obj = getWord(%target,0);
		  echo ("Object get type returns ",%obj.getType());
		  
		  if (%obj.getType() & $TypeMasks::TerrainObjectType)
		  {
   			%xx = getWord(%target, 1);
   			%yy = getWord(%target, 2);
   			%zz = getWord(%target, 3);
   			%nx = getWord(%target, 4);
   			%ny = getWord(%target, 5);
   			%nz = getWord(%target, 6);
   			%height = 0.5;  // Height of average character
	   		%finalPos = %xx SPC %yy SPC %zz;
	   		%player.setTargetPosition(%finalPos);
		  }
		  else
		  {
		  	%player.setTarget(%obj);
		  }
		  
  		$mvTriggerCount0++;

   }