|
|
Line 1: |
Line 1: |
− | {{lang|UTIL TraceLine|title=UTIL TraceLine}} | + | {{Delete|Page was not at all translated}} |
− | {{translate:zh-cn}}
| |
− | | |
− | 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 [[hitscan]] weapons. Hitscan 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
| |
− | :*'''surface''': Returns the surface hit by the TraceLine.
| |
− | ::*'''name''': Returns the name of the surface. {{Todo| What is normally returned (i.e. "rock" etc.)}}
| |
− | ::*'''flags''': Returns a bitflag normally used to avoid the TraceLine hitting unwanted surfacetypes (i.e. "if( tr.surface.flags & SURF_SKY )")
| |
− | ::*'''surfaceProps''': Returns a ''short'' integer used in finding the material of the surface hit:
| |
− | :{{Tip| Use physprops->GetSurfaceData(tr.surface.surfaceProps) to return a ''surfacedata_t'' which can be used to determine the material of the surface you hit. }}
| |
− | | |
− | == 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 Vector for direction
| |
− | Vector vecDir;
| |
− | | |
− | // Take the Player's EyeAngles and turn it into a direction
| |
− | AngleVectors( pPlayer->EyeAngles(), &vecDir );
| |
− | | |
− | // Get the Start/End
| |
− | Vector vecAbsStart = pPlayer->EyePosition();
| |
− | Vector vecAbsEnd = vecAbsStart + (vecDir * MAX_TRACE_LENGTH);
| |
− | | |
− | trace_t tr; // Create our trace_t class to hold the end result
| |
− | // 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:zh-cn]]
| |
− | [[Category:UTIL:zh-cn]]
| |