First Person Ragdolls

From Valve Developer Community
< Es
Jump to: navigation, search
English (en)Deutsch (de)Español (es)Русский (ru)Translate (Translate)
Muerte desde una perspectiva en primera persona en HL2DM

En la mayoría de los MODS multijugador de Source, cuando un jugador muere la cámara cambia automáticamente de la perspectiva de primera a tercera persona. El siguiente código permite al jugador tener la opción de ver las cosas desde la perspectiva del cadáver, con el fin de ver el mundo desde los ojos del mismo.

Pre-requisitos

Para que el código funcione es necesario que el modelo del cadáver tenga un acoplamiento llamado eyes que representa los ojos del mismo y desde donde el jugador podrá ver. En este caso usaremos los modelos humanos de HL2 que ya tienen por predeterminado este acoplamiento, sin embargo si tu modelo no lo tiene puedes agregarlo fácilmente desde el archivo QC(en) y HLMV(en).

El código

El siguiente código esta destinado para los MODS de HL2DM (Half-Life 2: Deathmatch). Si tu MOD esta basado en HL2 (Singleplayer) puedes ver el código para esta versión aquí(en).

c_hl2mp_player.cpp

Debido a que este código es para el lado del cliente (clientside) haremos los cambios en el archivo client/hl2mp/c_hl2mp_player.cpp

Primero debemos añadir unos comandos de consola para activar o desactivar las muertes en primera persona. Esto debe ser agregado al principio del archivo, junto a los otros comandos de consola:

static ConVar cl_fp_ragdoll( "cl_fp_ragdoll", "1", FCVAR_ARCHIVE, "Allow first person ragdolls" );
static ConVar cl_fp_ragdoll_auto( "cl_fp_ragdoll_auto", "1", FCVAR_ARCHIVE, "Autoswitch to ragdoll thirdperson-view when necessary" );

El siguiente paso es editar la función CalcView. Esta función verifica si el jugador ha muerto y entonces cambia a la camará en tercera persona. En este caso vamos a agregar el código para las muertes en primera persona:

void C_HL2MP_Player::CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov )
{
	// if we're dead, we want to deal with first or third person ragdolls.
	if ( m_lifeState != LIFE_ALIVE && !IsObserver() )
	{
		// First person ragdolls
		if ( cl_fp_ragdoll.GetBool() && m_hRagdoll.Get() )
		{
			// pointer to the ragdoll
			C_HL2MPRagdoll *pRagdoll = (C_HL2MPRagdoll*)m_hRagdoll.Get();

			// gets its origin and angles
			pRagdoll->GetAttachment( pRagdoll->LookupAttachment( "eyes" ), eyeOrigin, eyeAngles );
			Vector vForward; 
			AngleVectors( eyeAngles, &vForward );

			if ( cl_fp_ragdoll_auto.GetBool() )
			{
				// DM: Don't use first person view when we are very close to something
				trace_t tr;
				UTIL_TraceLine( eyeOrigin, eyeOrigin + ( vForward * 10000 ), MASK_ALL, pRagdoll, COLLISION_GROUP_NONE, &tr );

				if ( (!(tr.fraction < 1) || (tr.endpos.DistTo(eyeOrigin) > 25)) )
					return;
			}
			
			return;
		}

		eyeOrigin = vec3_origin;
		eyeAngles = vec3_angle;

		Vector origin = EyePosition();
		IRagdoll *pRagdoll = GetRepresentativeRagdoll();

		if ( pRagdoll )
		{
			origin = pRagdoll->GetRagdollOrigin();
			origin.z += VEC_DEAD_VIEWHEIGHT.z; // look over ragdoll, not through
		}

		BaseClass::CalcView( eyeOrigin, eyeAngles, zNear, zFar, fov );
		eyeOrigin = origin;
		Vector vForward; 
		AngleVectors( eyeAngles, &vForward );
		VectorNormalize( vForward );
		VectorMA( origin, -CHASE_CAM_DISTANCE, vForward, eyeOrigin );
		Vector WALL_MIN( -WALL_OFFSET, -WALL_OFFSET, -WALL_OFFSET );
		Vector WALL_MAX( WALL_OFFSET, WALL_OFFSET, WALL_OFFSET );
		trace_t trace; // clip against world
		// HACK don't recompute positions while doing RayTrace
		C_BaseEntity::EnableAbsRecomputations( false );
		UTIL_TraceHull( origin, eyeOrigin, WALL_MIN, WALL_MAX, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trace );
		C_BaseEntity::EnableAbsRecomputations( true );

		if (trace.fraction < 1.0)
		{
			eyeOrigin = trace.endpos;
		}

		return;
	}

	BaseClass::CalcView( eyeOrigin, eyeAngles, zNear, zFar, fov );
}

Entonces, cuando el comando "cl_fp_ragdoll_auto" esta activado el código automaticamente cambiará a la camará en tercera persona cuando no haya mucho que ver (¿una pared?)

Problemas menores

En ocaciones podrás encontrar que la cabeza del ragdoll se encuentre muy cerca a una superficie ocacionando que sea posible ver al otro lado. Esto se causa debido a que los ojos se encuentran extremadamente cerca o incluso dentro de la superficie en si.

Often this can be tracked down to the default HL2 physics model which is very loose and in the case of the head, quite small. You may find that you can reduce this happening by editing the physics model's weights and constraints so that the ragdoll falls in a more natural way. Also making the head part of the physics model a little larger near the nose and brow often helps in stopping the eye attachment from penetrating a surface.