Вид от третьего лица
Для получения помощи, обратитесь к руководству по редактированию на VDC и процессу очистки на Wikipedia. Также не забудьте проверить наличие заметок, оставленных отмечающим на странице обсуждения этой статьи.
Отсутствие некоторых строк (обновленный перевод/случайно пропущены), машинный перевод
Эта статья не подходит для движка Orange Box
Для Orange Box версии движка смотрите статью Thirdperson-OrangeBox
Обзор
В этом уроке описано, как сделать вид от третьего лица со следующими функциями:
- Обнаружение столкновения
- Масштабирование колесиком мыши
- Прозрачность модели, если камера слишком близко
- Скрытие рук Гордона в режиме от третьего лица
- Скрытие оружия в режиме от третьего лица (или первого лица)
- Скрытие crosshair в режиме от третьего лица (или первого лица)
- Скрытие модели игрока в режиме от первого лица
- Добавление кнопки переключения
Спасибо за Third Person Camera статьям сThe Wavelength. Этот туториал модификация нескольких статьей, удобна для понимания.
Спасибо за перевод Google Переводчик
Шаг первый: in_camera.cpp
Это руководство предполагает, что вы используете Single Player Mod и Microsoft Visual Studio 2003/2005/2008/2010.
Откройте Game_Episodic-2005.sln в Visual Studio.
Первым делом будет изменен код внутри камеры: in_camera.cpp (Находится в client).
Закомментируйте строку:
#define CAM_MIN_DIST 36.0
Чтобы получилось так:
// #define CAM_MIN_DIST 36.0
Под строкой #define YAW_MIN -135.0
Добавьте:
in_camera.cpp
#define CAM_MIN_DIST 16.0 // Don't let the camera get any closer than ...
#define CAM_MAX_DIST 96.0 // ... or any farther away than ...
#define CAM_SWITCH_DIST 96.0 // the default camera distance when switching 1st to 3rd person
#define CAM_HULL_OFFSET 6.0 // the size of the bounding hull used for collision checking
#define START_TRANS_DIST 40.0 // how close to player when it starts making model translucent
#define TRANS_DELTA 1.9921875 // Set to 255 / START_TRANS_DIST
static Vector CAM_HULL_MIN(-CAM_HULL_OFFSET,-CAM_HULL_OFFSET,-CAM_HULL_OFFSET);
static Vector CAM_HULL_MAX( CAM_HULL_OFFSET, CAM_HULL_OFFSET, CAM_HULL_OFFSET);
Под строкой: static kbutton_t cam_in, cam_out, cam_move;
Добавьте:
float mf_NextSwitch;
Замените:
static ConVar cam_idealyaw( "cam_idealyaw", "90", FCVAR_ARCHIVE ); // thirdperson yaw
На:
static ConVar cam_idealyaw( "cam_idealyaw", "0", FCVAR_ARCHIVE ); /* thirdperson yaw
| fix side view bug */
Замените эту секцию (под функцией CAM_Think):
if( !m_fCameraInThirdPerson )
return;
На:
// Toggle first/3rd person, check every 0.5 seconds
if(gpGlobals->curtime >= mf_NextSwitch) {
if(input->KeyState(&in_camchange))
{
mf_NextSwitch = gpGlobals->curtime + 0.5; /* Check if the key has been pressed every
0.5 seconds */
if(!m_fCameraInThirdPerson)
{
CAM_ToThirdPerson();
} else {
CAM_ToFirstPerson();
}
}
}
if( !m_fCameraInThirdPerson )
{
// If in FP mode, transparent
// This is sort of a hack since when the map first loads you ARE transparent...
// This is for when you switch from 3rd to 1st.
if(C_BasePlayer::GetLocalPlayer() ) {
C_BasePlayer::GetLocalPlayer()->SetRenderMode( kRenderTransColor );
C_BasePlayer::GetLocalPlayer()->SetRenderColorA(0);
}
return;
}
mf_NextSwitch = gpGlobals->curtime + 0.5
на более маленькое значение.В пределах этого куска кода:
else if( input->KeyState( &cam_out ) ) {
dist += CAM_DIST_DELTA;
}
Добавьте после dist += CAM_DIST_DELTA;
:
// Prevent the cam_out from going any further
// NOTE: Without this, it _appears_ it's not moving, but
// the transparency changes so it is... this fixes it.
if( dist > CAM_MAX_DIST )
dist = CAM_MAX_DIST;
Замените это:
if( cam_snapto.GetInt() )
{
camAngles[ YAW ] = cam_idealyaw.GetFloat() + viewangles[ YAW ];
camAngles[ PITCH ] = cam_idealpitch.GetFloat() + viewangles[ PITCH ];
camAngles[ 2 ] = cam_idealdist.GetFloat();
}
else
{
// code already here
}
На это:
if( cam_snapto.GetInt() )
{
camAngles[ YAW ] = cam_idealyaw.GetFloat() + viewangles[ YAW ];
camAngles[ PITCH ] = cam_idealpitch.GetFloat() + viewangles[ PITCH ];
camAngles[ 2 ] = cam_idealdist.GetFloat();
}
else
{
if( camAngles[ YAW ] - viewangles[ YAW ] != cam_idealyaw.GetFloat() )
camAngles[ YAW ] = MoveToward( camAngles[ YAW ],
cam_idealyaw.GetFloat() + viewangles[ YAW ],
CAM_ANGLE_SPEED );
if( camAngles[ PITCH ] - viewangles[ PITCH ] != cam_idealpitch.GetFloat() )
camAngles[ PITCH ] = MoveToward( camAngles[ PITCH ],
cam_idealpitch.GetFloat() + viewangles[ PITCH ],
CAM_ANGLE_SPEED );
if( !C_BasePlayer::GetLocalPlayer() ) {
// this code can be hit from the main menu, where it will crash
camAngles[ 2 ] = dist; // if there's no localplayer to calc from
}
else {
trace_t tr;
float adjDist = dist;
C_BasePlayer* localPlayer = C_BasePlayer::GetLocalPlayer();
Vector origin = localPlayer->GetLocalOrigin(); // find our player's origin
origin += localPlayer->GetViewOffset(); // and from there, his eye position
AngleVectors( QAngle(camAngles.x, camAngles.y, camAngles.z),
&camForward, NULL, NULL ); // get the forward vector
UTIL_TraceHull( origin, origin - (camForward * dist),
CAM_HULL_MIN, CAM_HULL_MAX,
MASK_SOLID, NULL, &tr ); /* use our previously #defined hull to
collision trace */
if( tr.fraction < 1.0 ) {
adjDist = dist * tr.fraction; // move the camera closer if it hit something
}
else {
adjDist = dist; // no trace hit, use cam_idealdist without adjusting it
}
if ( adjDist < START_TRANS_DIST ) {
localPlayer->SetRenderMode( kRenderTransColor ); // make him translucent
localPlayer->SetRenderColorA( (byte)(adjDist * TRANS_DELTA) ); // closer=less opacity
}
if( adjDist < CAM_MIN_DIST )
adjDist = CAM_MIN_DIST; // clamp up to minimum
if( adjDist > CAM_MAX_DIST )
adjDist = CAM_MAX_DIST; // clamp down to maximum
camAngles[ 2 ] = adjDist;
}
}
Найдите:
m_vecCameraOffset[ 0 ] = camAngles[ 0 ];
m_vecCameraOffset[ 1 ] = camAngles[ 1 ];
m_vecCameraOffset[ 2 ] = dist;
Замените:
m_vecCameraOffset[ 2 ] = dist;
На:
m_vecCameraOffset[ 2 ] = camAngles[ 2 ];
В функции void CInput::CAM_ToThirdPerson(void)
Измените:
m_vecCameraOffset[ 2 ] = CAM_MIN_DIST;
на:
m_vecCameraOffset[ 2 ] = CAM_SWITCH_DIST; /* When switching, move camera to our specified switch
distance */
Добавьте под этим:
// Set model to 'player' because when a map first loads
// it doesn't set the model... sort of a hack.
//C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
//pPlayer->SetModel("player");
Шаг второй: c_basecombatweapon.cpp
Откройте файл c_basecombatweapon.cpp в client.
Под этим, в C_BaseCombatWeapon::DrawModel( int flags ):
// check if local player chases owner of this weapon in first person
C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer();
Добавьте:
// Get rid of view model, crosshair and weapon in 3rd person
// Once we actually get weapons working, we'll let it draw only the weapon
if (localplayer)
{
if (input->CAM_IsThirdPerson())
{
// make sure the caller is the player to prevent hiding EVERYONE's weapon model.
if(localplayer == GetOwner())
{
SetModel( GetWorldModel() );
// Hide crosshair, remove this line if you still want to see it.
localplayer->m_Local.m_iHideHUD |= HIDEHUD_CROSSHAIR;
return false;
/* Comment above and uncomment the line underneath if you want
to be able to do weapon things (it will display the weapon). */
//return BaseClass:: DrawModel( flags );
}
}
}
Шаг третий: in_main.cpp
Откройте in_main.cpp в client.
Под строкой kbutton_t in_graph;
, добавьте:
kbutton_t in_camchange;
Снизу:
void IN_ZoomDown(void) {KeyDown(&in_zoom);}
void IN_ZoomUp(void) {KeyUp(&in_zoom);}
Добавьте:
void IN_CamChangeDown(void) {KeyDown(&in_camchange);}
void IN_CamChangeUp(void) {KeyUp(&in_camchange);}
Снизу CalcButtonBits( bits, IN_ZOOM, s_ClearInputState, &in_zoom, bResetState );
, добавьте:
CalcButtonBits( bits, IN_CAMCHANGE, s_ClearInputState, &in_camchange, bResetState );
Снизу:
static ConCommand startzoom("+zoom", IN_ZoomDown);
static ConCommand endzoom("-zoom", IN_ZoomUp);
Добавьте:
static ConCommand startcamchange("+camchange", IN_CamChangeDown);
static ConCommand endcamchange("-camchange", IN_CamChangeUp);
Шаг четвертый: input.h & in_buttons.h
Откройте in_buttons.h в server.
Снизу #define IN_BULLRUSH (1 << 22)
, добавьте:
#define IN_CAMCHANGE (1 << 23)
#define {command} (1 << {int})
Откройте input.h в client.
Снизу:
extern kbutton_t in_back;
Добавьте:
extern kbutton_t in_camchange;
Шаг пятый: kb_act.lst
Откройте kb_act.lst в папке SourceMods/{Ваш_Мод}/scripts/.
И добавьте под:
"blank" "=========================="
"blank" "#Valve_Movement_Title"
"blank" "=========================="
"+forward" "#Valve_Move_Forward"
"+back" "#Valve_Move_Back"
"+moveleft" "#Valve_Move_Left"
"+moveright" "#Valve_Move_Right"
"+speed" "#Valve_Sprint"
"+jump" "#Valve_Jump"
"+duck" "#Valve_Duck"
Вот это:
"+camchange" "Toggle 3rd/1st Person View"
Шаг шестой: Animations
Оригинал на VERC форумах:
Добавлено: Whisp
- Это последующей деятельности в должность, что я сделал некоторое время назад. Я пытался ли какие-либо знал, как добавить анимацию в thirdperson чтобы один игрок мод. Никто не знал, но я рад буду объявить что я нашел способ. Глядя на многочисленные код игрок, которого я нашел, что класс CHL2MP_Player происходит от CHL2_Player из одиночной игры. Если вы посмотрите на класс CHL2MP_Player вы увидите, что функция SetAnimation переопределяется. Я скопировал эту функцию из источника депутат и добавил его к классу CHL2_Player моего одного игрока мод. Затем я изменить модель игрока на один из человека (Алике также работает) и изменение функции депутата использовать СП деятельности. Ниже приводится функция, как он сидит сейчас. Я надеюсь, что это помогает, кто пытается добавить такую анимацию. Я не нашел способ сообщить, если игрок бежит не так анимации в настоящее время всегда выполняется (то есть так, как это в депутаты, а). Я попытался проверки ключевых IN_RUN но это не сработало. Я также попытался скорости код в начало функции МП и которые также не работает. Если кто знает способ говорить об этом, пожалуйста, дайте мне знать.
// Set the activity based on an event or current state
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 );
}
==
выше код должен идти внутрь hl2_player.cpp. это, то должна быть определена в hl2_player.h
поэтому в строке 174 поставить:
void SetAnimation ( PLAYER_ANIM playerAnim );
==
Заключение
Теперь вы имеете рабочий вид от третьего/первого лица. Если вы хотите назначить кнопку по умолчания для "+camchange", смотрите Customizing Options: Keyboard вики статьи.
Если вы не скрывают модели игрока и оружия, вы увидите, уродливые модели, которая должна представлять Гордона Фримена. Valve не пытаться использовать вид от третьего лица в HL2 поэтому вам придется найти игрока модель с оружием анимации и установить его!
Reference
Reference code
in_camera.cpp
Ваш готовый in_camera.cpp Должен выглядить так:
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Handles 3rd and 1st Person Views
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "hud.h"
#include "kbutton.h"
#include "input.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-------------------------------------------------- Constants
#define CAM_DIST_DELTA 1.0
#define CAM_ANGLE_DELTA 2.5
#define CAM_ANGLE_SPEED 2.5
#define CAM_ANGLE_MOVE .5
#define MAX_ANGLE_DIFF 10.0
#define PITCH_MAX 90.0
#define PITCH_MIN 0
#define YAW_MAX 135.0
#define YAW_MIN -135.0
#define CAM_MIN_DIST 16.0 // Don't let the camera get any closer than ...
#define CAM_SWITCH_DIST 96.0 // the default distance when switching from 1st to 3rd
#define CAM_MAX_DIST 96.0 // ... or any farther away than ...
#define CAM_HULL_OFFSET 6.0 // the size of the bounding hull used for collision checking
#define START_TRANS_DIST 40.0 // how close to player when it starts making model translucent
#define TRANS_DELTA 1.9921875 // Set to 255 / START_TRANS_DIST
static Vector CAM_HULL_MIN(-CAM_HULL_OFFSET,-CAM_HULL_OFFSET,-CAM_HULL_OFFSET);
static Vector CAM_HULL_MAX( CAM_HULL_OFFSET, CAM_HULL_OFFSET, CAM_HULL_OFFSET);
//-------------------------------------------------- Global Variables
static ConVar cam_command( "cam_command", "0", FCVAR_CHEAT | FCVAR_ARCHIVE ); /* tells camera to go
to thirdperson */
static ConVar cam_snapto( "cam_snapto", "0", FCVAR_ARCHIVE ); // snap to thirdperson view
static ConVar cam_idealyaw( "cam_idealyaw", "0", FCVAR_ARCHIVE ); // thirdperson yaw
static ConVar cam_idealpitch( "cam_idealpitch", "0", FCVAR_ARCHIVE ); // thirperson pitch
static ConVar cam_idealdist( "cam_idealdist", "64", FCVAR_ARCHIVE ); // thirdperson distance
static ConVar c_maxpitch( "c_maxpitch", "90", FCVAR_ARCHIVE );
static ConVar c_minpitch( "c_minpitch", "0", FCVAR_ARCHIVE );
static ConVar c_maxyaw( "c_maxyaw", "135", FCVAR_ARCHIVE );
static ConVar c_minyaw( "c_minyaw", "-135", FCVAR_ARCHIVE );
static ConVar c_maxdistance( "c_maxdistance", "200", FCVAR_ARCHIVE );
static ConVar c_mindistance( "c_mindistance", "30", FCVAR_ARCHIVE );
static ConVar c_orthowidth( "c_orthowidth", "100", FCVAR_ARCHIVE );
static ConVar c_orthoheight( "c_orthoheight", "100", FCVAR_ARCHIVE );
static kbutton_t cam_pitchup, cam_pitchdown, cam_yawleft, cam_yawright;
static kbutton_t cam_in, cam_out, cam_move;
float mf_NextSwitch;
// API Wrappers
/*
==============================
CAM_ToThirdPerson
==============================
*/
void CAM_ToThirdPerson(void)
{
input->CAM_ToThirdPerson();
}
/*
==============================
CAM_ToFirstPerson
==============================
*/
void CAM_ToFirstPerson(void)
{
input->CAM_ToFirstPerson();
}
/*
==============================
CAM_ToOrthographic
==============================
*/
void CAM_ToOrthographic(void)
{
input->CAM_ToOrthographic();
}
/*
==============================
CAM_StartMouseMove
==============================
*/
void CAM_StartMouseMove( void )
{
input->CAM_StartMouseMove();
}
/*
==============================
CAM_EndMouseMove
==============================
*/
void CAM_EndMouseMove( void )
{
input->CAM_EndMouseMove();
}
/*
==============================
CAM_StartDistance
==============================
*/
void CAM_StartDistance( void )
{
input->CAM_StartDistance();
}
/*
==============================
CAM_EndDistance
==============================
*/
void CAM_EndDistance( void )
{
input->CAM_EndDistance();
}
/*
==============================
CAM_ToggleSnapto
==============================
*/
void CAM_ToggleSnapto( void )
{
cam_snapto.SetValue( !cam_snapto.GetInt() );
}
/*
==============================
MoveToward
==============================
*/
float MoveToward( float cur, float goal, float maxspeed )
{
if( cur != goal )
{
if( abs( cur - goal ) > 180.0 )
{
if( cur < goal )
cur += 360.0;
else
cur -= 360.0;
}
if( cur < goal )
{
if( cur < goal - 1.0 )
cur += ( goal - cur ) / 4.0;
else
cur = goal;
}
else
{
if( cur > goal + 1.0 )
cur -= ( cur - goal ) / 4.0;
else
cur = goal;
}
}
// bring cur back into range
if( cur < 0 )
cur += 360.0;
else if( cur >= 360 )
cur -= 360;
return cur;
}
/*
==============================
CAM_Think
==============================
*/
void CInput::CAM_Think( void )
{
Vector origin;
Vector ext, pnt, camForward, camRight, camUp;
float dist;
Vector camAngles;
float flSensitivity;
QAngle viewangles;
switch( cam_command.GetInt() )
{
case CAM_COMMAND_TOTHIRDPERSON:
CAM_ToThirdPerson();
break;
case CAM_COMMAND_TOFIRSTPERSON:
CAM_ToFirstPerson();
break;
case CAM_COMMAND_NONE:
default:
break;
}
// Toggle first/3rd person
if(gpGlobals->curtime >= mf_NextSwitch) {
if(input->KeyState(&in_camchange))
{
mf_NextSwitch = gpGlobals->curtime + 0.5;
if(!m_fCameraInThirdPerson)
{
CAM_ToThirdPerson();
} else {
CAM_ToFirstPerson();
}
}
}
if( !m_fCameraInThirdPerson )
{
// If in FP mode, transparent
// This is sort of a hack since when the map first loads you ARE transparent...
// This is for when you switch from 3rd to 1st.
if(C_BasePlayer::GetLocalPlayer() ) {
C_BasePlayer::GetLocalPlayer()->SetRenderMode( kRenderTransColor );
C_BasePlayer::GetLocalPlayer()->SetRenderColorA(0);
}
return;
}
camAngles[ PITCH ] = cam_idealpitch.GetFloat();
camAngles[ YAW ] = cam_idealyaw.GetFloat();
dist = cam_idealdist.GetFloat();
//
//movement of the camera with the mouse
//
if (m_fCameraMovingWithMouse)
{
int cpx, cpy;
//get windows cursor position
GetMousePos (cpx, cpy);
m_nCameraX = cpx;
m_nCameraY = cpy;
//check for X delta values and adjust accordingly
//eventually adjust YAW based on amount of movement
//don't do any movement of cam using YAW/PITCH if we are zooming in/out the camera
if (!m_fCameraDistanceMove)
{
int x, y;
GetWindowCenter( x, y );
/* keep the camera within certain limits around the player (ie avoid certain
bad viewing angles) */
if (m_nCameraX>x)
{
//if ((camAngles[YAW]>=225.0)||(camAngles[YAW]<135.0))
if (camAngles[YAW]<c_maxyaw.GetFloat())
{
camAngles[ YAW ] += (CAM_ANGLE_MOVE)*((m_nCameraX-x)/2);
}
if (camAngles[YAW]>c_maxyaw.GetFloat())
{
camAngles[YAW]=c_maxyaw.GetFloat();
}
}
else if (m_nCameraX<x)
{
//if ((camAngles[YAW]<=135.0)||(camAngles[YAW]>225.0))
if (camAngles[YAW]>c_minyaw.GetFloat())
{
camAngles[ YAW ] -= (CAM_ANGLE_MOVE)* ((x-m_nCameraX)/2);
}
if (camAngles[YAW]<c_minyaw.GetFloat())
{
camAngles[YAW]=c_minyaw.GetFloat();
}
}
//check for y delta values and adjust accordingly
//eventually adjust PITCH based on amount of movement
//also make sure camera is within bounds
if (m_nCameraY > y)
{
if(camAngles[PITCH]<c_maxpitch.GetFloat())
{
camAngles[PITCH] +=(CAM_ANGLE_MOVE)* ((m_nCameraY-y)/2);
}
if (camAngles[PITCH]>c_maxpitch.GetFloat())
{
camAngles[PITCH]=c_maxpitch.GetFloat();
}
}
else if (m_nCameraY<y)
{
if (camAngles[PITCH]>c_minpitch.GetFloat())
{
camAngles[PITCH] -= (CAM_ANGLE_MOVE)*((y-m_nCameraY)/2);
}
if (camAngles[PITCH]<c_minpitch.GetFloat())
{
camAngles[PITCH]=c_minpitch.GetFloat();
}
}
//set old mouse coordinates to current mouse coordinates
//since we are done with the mouse
if ( ( flSensitivity = gHUD.GetSensitivity() ) != 0 )
{
m_nCameraOldX=m_nCameraX*flSensitivity;
m_nCameraOldY=m_nCameraY*flSensitivity;
}
else
{
m_nCameraOldX=m_nCameraX;
m_nCameraOldY=m_nCameraY;
}
ResetMouse();
}
}
//Nathan code here
if( input->KeyState( &cam_pitchup ) )
camAngles[ PITCH ] += CAM_ANGLE_DELTA;
else if( input->KeyState( &cam_pitchdown ) )
camAngles[ PITCH ] -= CAM_ANGLE_DELTA;
if( input->KeyState( &cam_yawleft ) )
camAngles[ YAW ] -= CAM_ANGLE_DELTA;
else if( input->KeyState( &cam_yawright ) )
camAngles[ YAW ] += CAM_ANGLE_DELTA;
if( input->KeyState( &cam_in ) )
{
dist -= CAM_DIST_DELTA;
if( dist < CAM_MIN_DIST )
{
// If we go back into first person, reset the angle
camAngles[ PITCH ] = 0;
camAngles[ YAW ] = 0;
dist = CAM_MIN_DIST;
}
}
else if( input->KeyState( &cam_out ) ) {
dist += CAM_DIST_DELTA;
// Prevent the cam_out from going any further
// NOTE: Without this, it _appears_ it's not moving, but
// the transparency changes so it is... this fixes it.
if( dist > CAM_MAX_DIST )
dist = CAM_MAX_DIST;
}
if (m_fCameraDistanceMove)
{
int x, y;
GetWindowCenter( x, y );
if (m_nCameraY>y)
{
if(dist<c_maxdistance.GetFloat())
{
dist +=CAM_DIST_DELTA * ((m_nCameraY-y)/2);
}
if (dist>c_maxdistance.GetFloat())
{
dist=c_maxdistance.GetFloat();
}
}
else if (m_nCameraY<y)
{
if (dist>c_mindistance.GetFloat())
{
dist -= (CAM_DIST_DELTA)*((y-m_nCameraY)/2);
}
if (dist<c_mindistance.GetFloat())
{
dist=c_mindistance.GetFloat();
}
}
//set old mouse coordinates to current mouse coordinates
//since we are done with the mouse
m_nCameraOldX=m_nCameraX*gHUD.GetSensitivity();
m_nCameraOldY=m_nCameraY*gHUD.GetSensitivity();
ResetMouse();
}
// update ideal
cam_idealpitch.SetValue( camAngles[ PITCH ] );
cam_idealyaw.SetValue( camAngles[ YAW ] );
cam_idealdist.SetValue( dist );
// Move towards ideal
VectorCopy( m_vecCameraOffset, camAngles );
engine->GetViewAngles( viewangles );
if( cam_snapto.GetInt() )
{
camAngles[ YAW ] = cam_idealyaw.GetFloat() + viewangles[ YAW ];
camAngles[ PITCH ] = cam_idealpitch.GetFloat() + viewangles[ PITCH ];
camAngles[ 2 ] = cam_idealdist.GetFloat();
}
else
{
if( camAngles[ YAW ] - viewangles[ YAW ] != cam_idealyaw.GetFloat() )
camAngles[ YAW ] = MoveToward( camAngles[ YAW ],
cam_idealyaw.GetFloat() + viewangles[ YAW ],
CAM_ANGLE_SPEED );
if( camAngles[ PITCH ] - viewangles[ PITCH ] != cam_idealpitch.GetFloat() )
camAngles[ PITCH ] = MoveToward( camAngles[ PITCH ],
cam_idealpitch.GetFloat() + viewangles[ PITCH ],
CAM_ANGLE_SPEED );
if( !C_BasePlayer::GetLocalPlayer() ) {
// this code can be hit from the main menu, where it will crash
camAngles[ 2 ] = dist; // if there's no localplayer to calc from
}
else {
trace_t tr;
float adjDist = dist;
C_BasePlayer* localPlayer = C_BasePlayer::GetLocalPlayer();
Vector origin = localPlayer->GetLocalOrigin(); // find our player's origin
origin += localPlayer->GetViewOffset(); // and from there, his eye position
AngleVectors( QAngle(camAngles.x, camAngles.y, camAngles.z),
&camForward, NULL, NULL ); // get the forward vector
UTIL_TraceHull( origin, origin - (camForward * dist),
CAM_HULL_MIN, CAM_HULL_MAX,
MASK_SOLID, NULL, &tr ); /* use our previously #defined hull to
collision trace */
if( tr.fraction < 1.0 ) {
adjDist = dist * tr.fraction; // move the camera closer if it hit something
}
else {
adjDist = dist; // no trace hit, use cam_idealdist without adjusting it
}
if ( adjDist < START_TRANS_DIST ) {
// make him translucent
localPlayer->SetRenderMode( kRenderTransColor );
// closer = less opacity
localPlayer->SetRenderColorA( (byte)(adjDist * TRANS_DELTA) );
}
if( adjDist < CAM_MIN_DIST )
adjDist = CAM_MIN_DIST; // clamp up to minimum
if( adjDist > CAM_MAX_DIST )
adjDist = CAM_MAX_DIST; // clamp down to maximum
camAngles[ 2 ] = adjDist;
}
}
m_vecCameraOffset[ 0 ] = camAngles[ 0 ];
m_vecCameraOffset[ 1 ] = camAngles[ 1 ];
m_vecCameraOffset[ 2 ] = camAngles[ 2 ];
}
void CAM_PitchUpDown(void) { KeyDown( &cam_pitchup ); }
void CAM_PitchUpUp(void) { KeyUp( &cam_pitchup ); }
void CAM_PitchDownDown(void) { KeyDown( &cam_pitchdown ); }
void CAM_PitchDownUp(void) { KeyUp( &cam_pitchdown ); }
void CAM_YawLeftDown(void) { KeyDown( &cam_yawleft ); }
void CAM_YawLeftUp(void) { KeyUp( &cam_yawleft ); }
void CAM_YawRightDown(void) { KeyDown( &cam_yawright ); }
void CAM_YawRightUp(void) { KeyUp( &cam_yawright ); }
void CAM_InDown(void) { KeyDown( &cam_in ); }
void CAM_InUp(void) { KeyUp( &cam_in ); }
void CAM_OutDown(void) { KeyDown( &cam_out ); }
void CAM_OutUp(void) { KeyUp( &cam_out ); }
/*
==============================
CAM_ToThirdPerson
==============================
*/
void CInput::CAM_ToThirdPerson(void)
{
QAngle viewangles;
// Do allow third person in TF2 for now
#if !defined( TF2_CLIENT_DLL ) && !defined( CSTRIKE_DLL )
#if !defined( _DEBUG )
if ( gpGlobals->maxClients > 1 )
{
// no thirdperson in multiplayer.
return;
}
#endif
#endif
engine->GetViewAngles( viewangles );
if( !m_fCameraInThirdPerson )
{
m_fCameraInThirdPerson = true;
m_vecCameraOffset[ YAW ] = viewangles[ YAW ];
m_vecCameraOffset[ PITCH ] = viewangles[ PITCH ];
m_vecCameraOffset[ 2 ] = CAM_SWITCH_DIST;
// Set model to player because when a map first loads
// it doesn't set the model... sort of a hack.
//C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
//pPlayer->SetModel("player");
}
cam_command.SetValue( 0 );
}
/*
==============================
CAM_ToFirstPerson
==============================
*/
void CInput::CAM_ToFirstPerson(void)
{
m_fCameraInThirdPerson = false;
cam_command.SetValue( 0 );
}
/*
==============================
CAM_ToFirstPerson
==============================
*/
bool CInput::CAM_IsOrthographic(void) const
{
return m_CameraIsOrthographic;
}
/*
==============================
CAM_ToFirstPerson
==============================
*/
void CInput::CAM_OrthographicSize(float& w, float& h) const
{
w = c_orthowidth.GetFloat(); h = c_orthoheight.GetFloat();
}
/*
==============================
CAM_ToFirstPerson
==============================
*/
void CInput::CAM_ToOrthographic(void)
{
m_fCameraInThirdPerson = false;
m_CameraIsOrthographic = true;
cam_command.SetValue( 0 );
}
/*
==============================
CAM_StartMouseMove
==============================
*/
void CInput::CAM_StartMouseMove(void)
{
float flSensitivity;
//only move the cam with mouse if we are in third person.
if ( m_fCameraInThirdPerson )
{
//set appropriate flags and initialize the old mouse position
//variables for mouse camera movement
if (!m_fCameraMovingWithMouse)
{
int cpx, cpy;
m_fCameraMovingWithMouse=true;
m_fCameraInterceptingMouse=true;
GetMousePos(cpx, cpy);
m_nCameraX = cpx;
m_nCameraY = cpy;
if ( ( flSensitivity = gHUD.GetSensitivity() ) != 0 )
{
m_nCameraOldX=m_nCameraX*flSensitivity;
m_nCameraOldY=m_nCameraY*flSensitivity;
}
else
{
m_nCameraOldX=m_nCameraX;
m_nCameraOldY=m_nCameraY;
}
}
}
//we are not in 3rd person view..therefore do not allow camera movement
else
{
m_fCameraMovingWithMouse=false;
m_fCameraInterceptingMouse=false;
}
}
/*
==============================
CAM_EndMouseMove
the key has been released for camera movement
tell the engine that mouse camera movement is off
==============================
*/
void CInput::CAM_EndMouseMove(void)
{
m_fCameraMovingWithMouse=false;
m_fCameraInterceptingMouse=false;
}
/*
==============================
CAM_StartDistance
routines to start the process of moving the cam in or out
using the mouse
==============================
*/
void CInput::CAM_StartDistance(void)
{
//only move the cam with mouse if we are in third person.
if ( m_fCameraInThirdPerson )
{
//set appropriate flags and initialize the old mouse position
//variables for mouse camera movement
if (!m_fCameraDistanceMove)
{
int cpx, cpy;
m_fCameraDistanceMove=true;
m_fCameraMovingWithMouse=true;
m_fCameraInterceptingMouse=true;
GetMousePos(cpx, cpy);
m_nCameraX = cpx;
m_nCameraY = cpy;
m_nCameraOldX=m_nCameraX*gHUD.GetSensitivity();
m_nCameraOldY=m_nCameraY*gHUD.GetSensitivity();
}
}
//we are not in 3rd person view..therefore do not allow camera movement
else
{
m_fCameraDistanceMove=false;
m_fCameraMovingWithMouse=false;
m_fCameraInterceptingMouse=false;
}
}
/*
==============================
CAM_EndDistance
the key has been released for camera movement
tell the engine that mouse camera movement is off
==============================
*/
void CInput::CAM_EndDistance(void)
{
m_fCameraDistanceMove=false;
m_fCameraMovingWithMouse=false;
m_fCameraInterceptingMouse=false;
}
/*
==============================
CAM_IsThirdPerson
==============================
*/
int CInput::CAM_IsThirdPerson( void )
{
return m_fCameraInThirdPerson;
}
/*
==============================
CAM_GetCameraOffset
==============================
*/
void CInput::CAM_GetCameraOffset( Vector& ofs )
{
VectorCopy( m_vecCameraOffset, ofs );
}
/*
==============================
CAM_InterceptingMouse
==============================
*/
int CInput::CAM_InterceptingMouse( void )
{
return m_fCameraInterceptingMouse;
}
static ConCommand startpitchup( "+campitchup", CAM_PitchUpDown );
static ConCommand endpitcup( "-campitchup", CAM_PitchUpUp );
static ConCommand startpitchdown( "+campitchdown", CAM_PitchDownDown );
static ConCommand endpitchdown( "-campitchdown", CAM_PitchDownUp );
static ConCommand startcamyawleft( "+camyawleft", CAM_YawLeftDown );
static ConCommand endcamyawleft( "-camyawleft", CAM_YawLeftUp );
static ConCommand startcamyawright( "+camyawright", CAM_YawRightDown );
static ConCommand endcamyawright( "-camyawright", CAM_YawRightUp );
static ConCommand startcamin( "+camin", CAM_InDown );
static ConCommand endcamin( "-camin", CAM_InUp );
static ConCommand startcamout( "+camout", CAM_OutDown );
static ConCommand camout( "-camout", CAM_OutUp );
static ConCommand thirdperson( "thirdperson", ::CAM_ToThirdPerson,
"Switch to thirdperson camera.", FCVAR_CHEAT );
static ConCommand firstperson( "firstperson", ::CAM_ToFirstPerson, "Switch to firstperson camera." );
static ConCommand camortho( "camortho", ::CAM_ToOrthographic,
"Switch to orthographic camera.", FCVAR_CHEAT );
static ConCommand startcammousemove( "+cammousemove",::CAM_StartMouseMove);
static ConCommand endcammousemove( "-cammousemove",::CAM_EndMouseMove);
static ConCommand startcamdistance( "+camdistance", ::CAM_StartDistance );
static ConCommand endcamdistance( "-camdistance", ::CAM_EndDistance );
static ConCommand snapto( "snapto", CAM_ToggleSnapto );
/*
==============================
Init_Camera
==============================
*/
void CInput::Init_Camera( void )
{
m_CameraIsOrthographic = false;
}
c_basecombatweapon.cpp
Функция DrawModel должен выглядеть так:
//-----------------------------------------------------------------------------
// Purpose: Render the weapon. Draw the Viewmodel if the weapon's being carried
// by this player, otherwise draw the worldmodel.
//-----------------------------------------------------------------------------
int C_BaseCombatWeapon::DrawModel( int flags )
{
VPROF_BUDGET( "C_BaseCombatWeapon::DrawModel", VPROF_BUDGETGROUP_MODEL_RENDERING );
if ( !m_bReadyToDraw )
return 0;
if ( !IsVisible() )
return 0;
// check if local player chases owner of this weapon in first person
C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer();
// Get rid of view model, crosshair and weapon in 3rd person
// Once we actually get weapons working, we'll let it draw only the weapon
if (localplayer)
{
if (input->CAM_IsThirdPerson())
{
if(localplayer == GetOwner())
{
SetModel( GetWorldModel() );
localplayer->m_Local.m_iHideHUD |= HIDEHUD_CROSSHAIR;
return false;
//return BaseClass:: DrawModel( flags );
/* Uncomment this if you want to be
able to do weapon things
(it will display the weapon). */
}
}
}
if ( localplayer && localplayer->IsObserver() && GetOwner() )
{
// don't draw weapon if chasing this guy as spectator
// we don't check that in ShouldDraw() since this may change
// without notification
if ( localplayer->GetObserverMode() == OBS_MODE_IN_EYE &&
localplayer->GetObserverTarget() == GetOwner() )
return false;
}
return BaseClass::DrawModel( flags );
}