Third person

Aus the_Cr0w's Wiki
Wechseln zu: Navigation, Suche
Arrowup.png Ebene höher:
Programmierung

Im Sourcecode ist bereits eine voll funktionierender Third Person Modus versteckt. Man muss den Code nur aktivieren.

ThirdPerson.jpg

Inhaltsverzeichnis

Anleitung

client\in_camera.cpp

Suche nach der Funktion CInput::Init_Camera und füge dort folgendes ein.

m_fCameraInThirdPerson = true;

Jetzt suche nach allen Vorkommen von sv_cheats und kommentiere sie aus oder entferne sie.

Dadurch ist die Verfolgerkamera immer aktiviert.

Suche nach

m_vecCameraOffset[ PITCH ] = camOffset[ PITCH ];

und ersetze es durch

m_vecCameraOffset[ PITCH ] = camOffset[ PITCH ] - 3.5f;

server\player.cpp

Suche nach der Funktion CBasePlayer::Spawn und füge an ihrem Ende folgendes ein.

SetModel( "models/Humans/Group03/Female_02.mdl" );

Damit setzten wir das Model des Spielers. Du kannst hier jedes Spielermodel aus Half-Life 2: Deathmatch verwenden.

Suche nach der Funktion CBasePlayer::Precache unde füge dort unterhalb von BaseClass::Precache(); folgendes ein.

PrecacheModel( "models/Humans/Group03/Female_02.mdl" );

Ohne dieses Stücke Code wird das Model beim Spielstart nicht geladen und das Spiel stürzt ab. Hier musst du natürlich das gleich Model wie oben eintragen.

Jetzt sollte das Spiel im Third Person Modus starten und ein Model anzeigen. Wenn die Animationen des Models nicht funktionieren, dann lies weiter unten weiter.


Animationen im Singeplayer reparieren

Wer versucht den Third Person Modus im Singleplayer zu aktivieren, wird feststellen, dass das Spielermodel sich nicht bewegt.

Jesuspose.jpg

Dieses Problem tritt auf, weil der Singleplayer nicht dazu gedacht war im Third Person Modus zu laufen, welcher erst nach erscheinen von Half-Life 2 im Spiel eingefügt wurde. Einfach ausgedrückt: Sowohl im Code als auch in den Models fehlen wichtige Komponenten.

Important.png
Hinweis: Ich denke, dass es am Einfachsten wäre, wenn man ein eigenes Model für den Spieler benutzt.

Models

Kopiere die folgenden Models aus der Datei half-life 2 deathmatch.gcf mittels GCFScape in den models-Ordner deiner Mod.

humans\female_gestures.mdl
humans\female_postures.mdl
humans\female_shared.mdl
humans\female_ss.mdlma
humans\male_gestures.mdl
humans\male_postures.mdl
humans\male_shared.mdl
humans\male_ss.mdl
player\female_anims.mdl
player\male_anims.mdl
combine_soldiers_anims.mdl
police_animations.mdl
police_ss.mdl

Code

Ursprünglich von Whisp im VERC Forum gepostet.

Überprüfe ob in der Datei server\hl2\hl2_player.cpp eine Funktion mit dem Namen SetAnimation vorhanden ist. Wenn nicht dann führe die folgenden Schritte aus.

Füge am Ende von hl2_player.cpp folgenden ein.

void CHL2_Player::SetAnimation( PLAYER_ANIM playerAnim )
{
	int animDesired;
   
	float speed;
 
	speed = GetAbsVelocity().Length2D();
 
	if ( GetFlags() & ( FL_FROZEN | FL_ATCONTROLS ) )
	{
	speed = 0;
	playerAnim = PLAYER_IDLE;
	}
 
	Activity idealActivity = ACT_RUN;
 
	// This could stand to be redone. Why is playerAnim abstracted from activity? (sjb)
	if ( playerAnim == PLAYER_JUMP )
	{
		idealActivity = ACT_JUMP;
	}
	else if ( playerAnim == PLAYER_DIE )
	{
		if ( m_lifeState == LIFE_ALIVE )
		{
			return;
		}
	}
	else if ( playerAnim == PLAYER_ATTACK1 )
	{
		if ( GetActivity( ) == ACT_HOVER ||
			GetActivity( ) == ACT_SWIM ||
			GetActivity( ) == ACT_HOP ||
			GetActivity( ) == ACT_LEAP ||
			GetActivity( ) == ACT_DIESIMPLE )
		{
			idealActivity = GetActivity( );
		}
		else
		{
			idealActivity = ACT_GESTURE_RANGE_ATTACK1;
		}
	}
	else if ( playerAnim == PLAYER_RELOAD )
	{
		idealActivity = ACT_GESTURE_RELOAD;
	}
	else if ( playerAnim == PLAYER_IDLE || playerAnim == PLAYER_WALK )
	{
		if ( !( GetFlags() & FL_ONGROUND ) && GetActivity( ) == ACT_JUMP ) // Still jumping
		{
			idealActivity = GetActivity( );
		}
		/*
		else if ( GetWaterLevel() > 1 )
		{
			if ( speed == 0 )
				idealActivity = ACT_HOVER;
			else
				idealActivity = ACT_SWIM;
		}
		*/
		else
		{
			if ( GetFlags() & FL_DUCKING )
			{
				if ( speed > 0 )
				{
					idealActivity = ACT_WALK_CROUCH;
				}
				else
				{
					idealActivity = ACT_COVER_LOW; //ACT_IDLE_CROUCH;
				}
			}
			else
			{
				if ( speed > 0 )
				{
					idealActivity = m_fIsSprinting ? ACT_WALK : ACT_RUN;
				}
				else
				{
					idealActivity = ACT_IDLE;
				}
			}
		}
   
		//idealActivity = TranslateTeamActivity( idealActivity );
	}
 
	if ( idealActivity == ACT_GESTURE_RANGE_ATTACK1 )
	{
		RestartGesture( Weapon_TranslateActivity( idealActivity ) );
 
		// FIXME: this seems a bit wacked
		Weapon_SetActivity( Weapon_TranslateActivity( ACT_RANGE_ATTACK1 ), 0 );
 
		return;
	}
	else if ( idealActivity == ACT_GESTURE_RELOAD )
	{
		RestartGesture( Weapon_TranslateActivity( idealActivity ) );
		return;
	}
	else
	{
		SetActivity( idealActivity );
  
		animDesired = SelectWeightedSequence( Weapon_TranslateActivity ( idealActivity ) );
 
		if (animDesired == -1)
		{
			animDesired = SelectWeightedSequence( idealActivity );
 
			if ( animDesired == -1 )
			{
				animDesired = 0;
			}
  		}
   
		// Already using the desired animation?
		if ( GetSequence() == animDesired )
			return;
  
		m_flPlaybackRate = 1.0;
		ResetSequence( animDesired );
		SetCycle( 0 );
		return;
	}
 
	// Already using the desired animation?
	if ( GetSequence() == animDesired )
		return;
  
	//Msg( "Set animation to %d\n", animDesired );
	// Reset to first frame of desired animation
	ResetSequence( animDesired );
	SetCycle( 0 );
}

In hl2_player.h füge folgendes ein.

void SetAnimation ( PLAYER_ANIM playerAnim );

Waffen

Leider besitzen Activities der neuen Models andere Namen, als die alten. Deswegen ist es notwendig die Namen im Code der Waffe anzupassen. Dies geschieht im Array m_acttable[] und kann einige Zeit in Anspruch nehmen. Man muss mittels der Entwicklungskonsole alle fehlenden Activities identifizieren und diese dann im Code eifügen. Um diesen Vorgang zu beschleunigen habe ich eine Liste der Activities, aus der Datei female_anims.mdl, erstellt.

ACT_HL2MP_IDLE_PISTOL
ACT_HL2MP_IDLE_SHOTGUN
ACT_HL2MP_IDLE_SMG1
ACT_HL2MP_IDLE_AR2
ACT_HL2MP_IDLE_PHYSGUN
ACT_HL2MP_IDLE_GRENADE
ACT_HL2MP_IDLE_RPG
ACT_HL2MP_IDLE_CROSSBOW
ACT_HL2MP_IDLE_MELEE
ACT_HL2MP_IDLE_SLAM

ACT_HL2MP_RUN_PISTOL
ACT_HL2MP_RUN_SHOTGUN
ACT_HL2MP_RUN_SMG1
ACT_HL2MP_RUN_AR2
ACT_HL2MP_RUN_PHYSGUN
ACT_HL2MP_RUN_GRENADE
ACT_HL2MP_RUN_RPG
ACT_HL2MP_RUN_CROSSBOW
ACT_HL2MP_RUN_MELEE
ACT_HL2MP_RUN_SLAM

ACT_HL2MP_IDLE_CROUCH_PISTOL
ACT_HL2MP_IDLE_CROUCH_SHOTGUN
ACT_HL2MP_IDLE_CROUCH_SMG1
ACT_HL2MP_IDLE_CROUCH_AR2
ACT_HL2MP_IDLE_CROUCH_PHYSGUN
ACT_HL2MP_IDLE_CROUCH_GRENADE
ACT_HL2MP_IDLE_CROUCH_RPG
ACT_HL2MP_IDLE_CROUCH_CROSSBOW
ACT_HL2MP_IDLE_CROUCH_MELEE
ACT_HL2MP_IDLE_CROUCH_SLAM

ACT_HL2MP_WALK_CROUCH_PISTOL
ACT_HL2MP_WALK_CROUCH_SHOTGUN
ACT_HL2MP_WALK_CROUCH_SMG1
ACT_HL2MP_WALK_CROUCH_AR2
ACT_HL2MP_WALK_CROUCH_PHYSGUN
ACT_HL2MP_WALK_CROUCH_GRENADE
ACT_HL2MP_WALK_CROUCH_RPG
ACT_HL2MP_WALK_CROUCH_CROSSBOW
ACT_HL2MP_WALK_CROUCH_MELEE
ACT_HL2MP_WALK_CROUCH_SLAM

ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL
ACT_HL2MP_GESTURE_RANGE_ATTACK_SHOTGUN
ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG1
ACT_HL2MP_GESTURE_RANGE_ATTACK_AR2
ACT_HL2MP_GESTURE_RANGE_ATTACK_PHYSGUN
ACT_HL2MP_GESTURE_RANGE_ATTACK_GRENADE
ACT_HL2MP_GESTURE_RANGE_ATTACK_RPG
ACT_HL2MP_GESTURE_RANGE_ATTACK_CROSSBOW
ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE
ACT_HL2MP_GESTURE_RANGE_ATTACK_SLAM

ACT_HL2MP_JUMP_PISTOL
ACT_HL2MP_JUMP_SHOTGUN
ACT_HL2MP_JUMP_SMG1
ACT_HL2MP_JUMP_AR2
ACT_HL2MP_JUMP_PHYSGUN
ACT_HL2MP_JUMP_GRENADE
ACT_HL2MP_JUMP_RPG
ACT_HL2MP_JUMP_CROSSBOW
ACT_HL2MP_JUMP_MELEE
ACT_HL2MP_JUMP_SLAM

ACT_HL2MP_GESTURE_RELOAD_PISTOL
ACT_HL2MP_GESTURE_RELOAD_SHOTGUN
ACT_HL2MP_GESTURE_RELOAD_SMG1
ACT_HL2MP_GESTURE_RELOAD_AR2

Das Array m_acttable[] in meiner weapon_pistol.cpp sah danach folgendermaßen aus.

acttable_t	CWeaponPistol::m_acttable[] = 
{
	{ ACT_IDLE,			ACT_HL2MP_IDLE_PISTOL,			true },
	{ ACT_IDLE_ANGRY,		ACT_IDLE_ANGRY_PISTOL,			true },
	{ ACT_RANGE_ATTACK1,		ACT_RANGE_ATTACK_PISTOL,		true },
	{ ACT_RELOAD,			ACT_RELOAD_PISTOL,			true },
	{ ACT_WALK_AIM,			ACT_WALK_AIM_PISTOL,			true },
	{ ACT_RUN_AIM,			ACT_RUN_AIM_PISTOL,			true },
	{ ACT_GESTURE_RANGE_ATTACK1,	ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL,	true },
	{ ACT_RELOAD_LOW,		ACT_RELOAD_PISTOL_LOW,			false },
	{ ACT_RANGE_ATTACK1_LOW,	ACT_RANGE_ATTACK_PISTOL_LOW,		false },
	{ ACT_COVER_LOW,		ACT_HL2MP_IDLE_CROUCH_PISTOL,		false },
	{ ACT_RANGE_AIM_LOW,		ACT_RANGE_AIM_PISTOL_LOW,		false },
	{ ACT_GESTURE_RELOAD,		ACT_HL2MP_GESTURE_RELOAD_PISTOL,	false },
	{ ACT_WALK,			ACT_WALK_PISTOL,			false },
	{ ACT_RUN,			ACT_HL2MP_RUN_PISTOL,			false },
	{ ACT_JUMP,			ACT_HL2MP_JUMP_PISTOL,			false },
	{ ACT_LEAP,			ACT_HL2MP_IDLE_CROUCH_PISTOL,		false },
	{ ACT_WALK_CROUCH,		ACT_HL2MP_WALK_CROUCH_PISTOL,		false },
	{ ACT_RELOAD_LOW,		ACT_HL2MP_GESTURE_RELOAD_PISTOL,	false },
};

Bugs

Meine Werkzeuge
Namensräume
Varianten
Aktionen
Navigation
Werkzeuge