TraceLine: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
(Re-wrote most of the page to be more Wiki-like and clearer about how to use traces. Will add more detailed TraceLine stuff tomorrow.)
(Redirected to the new UTIL_TraceLine page which follows the rest of the UTIL_ functions formatting)
Line 1: Line 1:
{{otherlang2
#REDIRECT [[UTIL_TraceLine]]
|ru=TraceLine:ru
}}
Tracing is the process of going from a point A towards another point B, and finding out the first thing that we "hit" on our way from A to B ('''TraceLine'''). The most common example for the use of TraceLines would be weapons. Weapons use TraceLines to determine where they hit (and if they hit someone).
 
The line starts from the barrel (Point A) and ends at an arbitrary spot 8000 or more units in front of it. If it hits the world (a wall, a box, something solid) the code tells it to display an effect (for example, a smoke puff coming from the wall, or sparks from metal...). If it hits a player, it'll do damage.
 
== TraceLines ==
To create a simple trace, call '''UTIL_TraceLine( const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask, const IHandleEntity *ignore, int collisionGroup, trace_t *ptr )'''.
Where:
:*'''&vecAbsStart''' is a Vector such as GetAbsOrigin(); The "const" part of the function tells you that the function will not modify the variable.
:*'''&vecAbsEnd''' is a Vector such as GetAbsOrigin() + (vecForward * 192); Tracing 192 units in front of the Absolute Origin of the caller.
:*'''mask''' is a bitmask of valid MASK_ types to hit. See: [[MASK_Types]]. Since it is a bitmask, you can use multiple types and as such MASK_VISIBLE | MASK_SHOT will count as an acceptable mask.
:*'''<nowiki>*</nowiki>ignore''' is a IHandleEntity, or a pointer to a CBaseEntity. It is common to use "this" as to keep the TraceLine from hitting the object you're tracing from.
:*'''collisionGroup''' is a COLLISION_ type that the TraceLine is. See: [[COLLISION_Types]]Certain COLLISION_ types will not 'collide' with each other. Use COLLISION_GROUP_NONE to have your TraceLine hit everything.
:*'''<nowiki>*</nowiki>tr''' is a trace_t class. The results of the UTIL_TraceLine are written to this.
 
== Common vecAbsStart and vecAbsEnd Methods ==
'''vecAbsStart'''
:*'''GetAbsOrigin()''': This returns a Vector of the entity's Origin in World Space coordinates. For Player's this is their feet, and for most entities :*it is either the center or bottom of the model.
{{Note|This is visible in [[HLMV]] under the '''Bones''' tab, by checking '''Highlight Bone''' of the first bone.}}
{{todo|Is this accurate?}}
:*'''Weapon_ShootPosition()''': Point in World Space where the player's weapon's shot originates.
{{Note|Only available in the Player class}}
:*'''GetAttachment( int attachment, Vector &origin, QAngle &angles );''': Returns the position of an attachment point. Used in conjunction with...
:*'''LookupAttachment( char *pAttachmentName )''': The name (as a char*) of the attachment point you wish to use.
 
 
'''vecAbsEnd'''
:*'''EyeAngles()''': Returns a QAngle of the angle the player is currently looking at.
{{Note|Only avaible in the Player class}}
:*'''GetAbsAngles()''': Returns a QAngle of the angle the player is facing at. Often does not match the z rotation of EyeAngles, as the player only turns in 15-30 degree increments to avoid jitter and increase realism.
 
 
'''QAngles'''
QAngles is a Vector of Angles -- That is to say it stores rotation in X, Y and Z.
Often, we will want to turn a QAngle into a vector. To do this, we can use AngleVectors(), which takes a QAngle and can return 1 or 3 pointers to Vectors. For example:
 
<source lang=cpp>
Vector vecForward, vecRight, vecUp;
AngleVectors( EyeAngles(), &vecForward, &vecRight, &vecUp); </source>
Will return a vector facing to the "front", a vector to the "right", and a vector to the "up" of your QAngle. You can then use vecForwards to get where EyeAngles() is looking at.
 
To get a point infront of your 'end' position, you can do:
<source lang=cpp>Vector vecForward;
AngleVectors( pPlayer->EyeAngles(), &vecForward ) //Assign vecForward a vector facing the EyeAngles
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + ( vecForward * MAX_TRACE_LENGTH, ...)
</source>
 
'''MAX_TRACE_LENGTH''' is the longest trace you can have, or ~56,754 units.
{{Note|This is a trace from one corner to the opposite corner of the world, assuming a cubic world.}}
 
== trace_t &tr ==
'''trace_t''' is a special class that stores the results of our TraceLine. It has the following values.
:*'''startpos''': The start of the TraceLine as a Vector.
:*'''endpos''': The end of the TraceLine as a Vector.
:*'''plane''': Struct. Contains the information about the plane you hit.
{{Warning|plane can be invalid! If the trace never leaves a solid, there will be no valid plane.}}
:*'''fraction''': How far the trace went before hitting something. 0-1, 1.0 means it didn't hit anything.
:*'''allsolid''': Boolean. If true, the plane is not valid. (You never left the solid you started in)
:*'''startsolid''': Boolean. If true, the initial point was in a solid area.
:*'''hitbox''': Returns the int of the hitbox hit.
:*'''m_pEnt''': The entity hit. Can be invalid.
{{Tip| Use "if ( tr.m_pEnt )" to validate it!}}
:*'''DidHit()''': Boolean. Returns true if it hit something.
:*'''IsPlayer()''': Boolean. Returns true if the entity hit was a player.
:*'''IsNPC()''': Boolean. Returns true if the entity hit was an NPC.
:*'''GetClassname()''': Returns the name of the entity hit.
{{Note|Returns strange results on the client if the entity is not predicted.}}
:*'''GetTeamNumber()''': Returns the team number that the entity is on. Returns UNASSIGNED for entities not on a team.
:*'''contents''': Contents on the other side of the surface it hit
{{Todo|What exactly is this? Has properties such as tr.surface.name, tr.surface.flags, tr.surface.surfaceProps, etc.}}
 
== Examples ==
Trace from the player's eyes to the max trace distance.
 
<source lang=cpp>
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
if ( !pPlayer )
  return; //Always validate a pointer
 
//Create our trace_t class to hold the end result
trace_t tr;
 
//Create Vectors for the start, stop, and direction
Vector vecAbsStart, vecAbsEnd, vecDir;
 
//Take the Player's EyeAngles and turn it into a direction
AngleVectors( pPlayer->EyeAngles(), &vecDir );
 
//Get the Start/End
vecAbsStart = pPlayer->EyePosition();
vecAbsEnd = vecAbsStart + (vecDir * MAX_TRACE_LENGTH);
 
//Do the TraceLine, and write our results to our trace_t class, tr.
UTIL_TraceLine( vecAbsStart, vecAbsEnd, MASK_ALL, pPlayer, COLLISION_GROUP_NONE, &tr );
 
//Do something with the end results
if ( tr.m_pEnt )
{
    if ( tr.m_pEnt->IsNPC() )
    {
        Msg("TraceLine hit an NPC!\n");
    }
    if ( tr.m_pEnt->IsPlayer() )
    {
        Msg("TraceLine hit a Player!\n");
    }
}
</source>
 
{{todo|More Examples!}}
 
[[Category:Programming]]
[[Category:UTIL]]

Revision as of 18:08, 9 April 2011

Redirect to: