Ru/Over the Shoulder View: Difference between revisions

From Valve Developer Community
< Ru
Jump to navigation Jump to search
Line 19: Line 19:
These actions have established a third-person view of the standard, without requiring any gestures from the player.
These actions have established a third-person view of the standard, without requiring any gestures from the player.


==Шаг 2 - Создаём вид из-за плеча.==
== Step 2 - Create a view from behind the shoulder. ==
В этом шаге мы внесём необходимые изменения, для того чтобы сделать камеру с видом из-за плеча. Найдите и откройте clientmode_shared.cpp. Он также находиться в client.dll файлах.
In this step, we will make the necessary changes in order to make a camera with a view from the back. Find and open clientmode_shared.cpp. It is also located in the client.dll files.
Теперь найдите функцию void ClientModeShared::OverrideView( CViewSetup *pSetup ).
Now find the function void ClientModeShared :: OverrideView (CViewSetup * pSetup).
Замените всё внутри функции на:
Replace everything inside the function with:
<source lang=cpp>
<source lang = cpp>
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
C_BasePlayer * pPlayer = C_BasePlayer :: GetLocalPlayer ();
if(!pPlayer)
if (! pPlayer)
      return;
       return;


pPlayer->OverrideView( pSetup );
pPlayer->OverrideView( pSetup );
Line 51: Line 51:
   UTIL_TraceLine( vecStart, vecStop, MASK_ALL, pPlayer, COLLISION_GROUP_NONE, &tr );
   UTIL_TraceLine( vecStart, vecStop, MASK_ALL, pPlayer, COLLISION_GROUP_NONE, &tr );
        
        
   if (tr.fraction == 1) //достаточно ли мы далеки чтобы не задеть стену камерой
   if (tr.fraction == 1) //are we far enough not to hit the wall with the camera
   {
   {
     if(camCurrentX < 16.0f)
     if(camCurrentX < 16.0f)
Line 57: Line 57:
     if(camCurrentX >16.0f)
     if(camCurrentX >16.0f)
     camCurrentX=16.0f;
     camCurrentX=16.0f;
     VectorMA( pSetup->origin, camCurrentX, camRight, pSetup->origin); //установка правильного смещения
     VectorMA( pSetup->origin, camCurrentX, camRight, pSetup->origin); //setting the correct offset
     VectorMA( pSetup->origin, 16.0f, camUp, pSetup->origin);
     VectorMA( pSetup->origin, 16.0f, camUp, pSetup->origin);
     vecStart=tr.endpos;
     vecStart=tr.endpos;
Line 94: Line 94:
     }
     }
     else   
     else   
       //Добавьте код, чтобы сделать игрока прозрачным, таким образом игрок может видеть лучше (?)
       //Add code to make the player transparent so the player can see better. (?)
     {
     {
       VectorMA( pSetup->origin, 0.0f, camUp, pSetup->origin);
       VectorMA( pSetup->origin, 0.0f, camUp, pSetup->origin);
Line 122: Line 122:
}
}
</source>
</source>
Это создаст вид из-за плеча, который стандартно будет стоять из-за правого плеча. Это конечно не идеальный код, но для начала создания какого-нибудь интересного мода может и подойти.
This will create a shoulder view that will stand by the right shoulder as standard. This is certainly not an ideal code, but to start creating some interesting mod, it may be suitable.
Если не будет пространства справа, то произойдёт проверка и если пространство есть, то установиться x и z -16/+16 а затем проверяется расстояние позади. Если нет пространства слева, или справа, z устанавливается +32 и x 0. Это поместит камеру выше головы модели игрока, таким образом игрок всё ещё сможет видеть. Если будет недостаточно пространства выше, то камера будет помещена на уровне глаз. Все эти проверки нужны для корректного вида камеры, например если вы ползёте в вентиляционных трубах или того хуже, в канализации
If there is no space on the right, then a test will occur and if there is space, then x and z -16 / + 16 will be installed and then the distance behind will be checked. If there is no space to the left or to the right, z is set to +32 and x 0. This will place the camera above the player’s model head, so the player can still see. If there is not enough space above, the camera will be placed at eye level. All these checks are needed for the correct type of camera, for example, if you crawl in the ventilation pipes or worse, in the sewer


==Шаг 3 - Исправляем маленький баг==
==Шаг 3 - Исправляем маленький баг==

Revision as of 15:06, 19 May 2019

Template:Otherlang2

заплечная камера в игре

Step 1 - Put a third-person view by default.

Find and open 'in_camera.cpp' , it should be in the 'client.dll' files. Now find each use case of sv_cheats, and delete or comment out all these lines. Find the last function, and at the very end you should see something like this 'void CInput :: Init_Camera (void)' In this function add m_fCameraInThirdPerson = true ; It should turn out like this:

void CInput::Init_Camera( void )
{
   m_CameraIsOrthographic = false;
   m_fCameraInThirdPerson = true;
}

These actions have established a third-person view of the standard, without requiring any gestures from the player.

Step 2 - Create a view from behind the shoulder.

In this step, we will make the necessary changes in order to make a camera with a view from the back. Find and open clientmode_shared.cpp. It is also located in the client.dll files. Now find the function void ClientModeShared :: OverrideView (CViewSetup * pSetup). Replace everything inside the function with:

C_BasePlayer * pPlayer = C_BasePlayer :: GetLocalPlayer ();
if (! pPlayer)
       return;

pPlayer->OverrideView( pSetup );

if( ::input->CAM_IsThirdPerson() )
{
   Vector camForward, camRight, camUp;
     
          AngleVectors( pPlayer->EyeAngles(), &camForward, &camRight, &camUp );
     
   trace_t tr, tr2;
   Vector vecStart, vecStop, vecDirection, vecSetDirection;   
   static float camCurrentY;   
   static float camCurrentX=16.0f;   
   float camDelta=0.5f;
   vecStart=pSetup->origin;

   AngleVectors(pPlayer->EyeAngles(), &vecDirection);   
      
   vecSetDirection.Init(0,0,1.0f);
   vecDirection=vecDirection.Cross(vecSetDirection);
   vecStop = vecStart + vecDirection*52.0f;

   UTIL_TraceLine( vecStart, vecStop, MASK_ALL, pPlayer, COLLISION_GROUP_NONE, &tr );
      
   if (tr.fraction == 1) //are we far enough not to hit the wall with the camera
   {
    if(camCurrentX < 16.0f)
     camCurrentX +=camDelta;
    if(camCurrentX >16.0f)
     camCurrentX=16.0f;
    VectorMA( pSetup->origin, camCurrentX, camRight, pSetup->origin); //setting the correct offset
    VectorMA( pSetup->origin, 16.0f, camUp, pSetup->origin);
     vecStart=tr.endpos;
   }
   else   
   {   
       
    vecStop = vecStart + vecDirection * -52.0f;
       
    UTIL_TraceLine( vecStart, vecStop, MASK_ALL, pPlayer, COLLISION_GROUP_NONE, &tr );
         
    if (tr.fraction == 1)   
    {   
     if(camCurrentX > -16.0f)
      camCurrentX -=camDelta;
     if(camCurrentX < -16.0f)
      camCurrentX=-16.0f;
     VectorMA( pSetup->origin, camCurrentX, camRight, pSetup->origin);
     VectorMA( pSetup->origin, 16.0f, camUp, pSetup->origin);
     vecStart=tr.endpos;
    }
    else   
    {   
     VectorMA( pSetup->origin, 0.0f, camRight, pSetup->origin);   
     AngleVectors(pPlayer->EyeAngles(), &vecDirection);   
     vecSetDirection.Init(1.0f,0,0);
     vecDirection=vecDirection.Cross(vecSetDirection);
     vecStop = vecStart +vecDirection*32.0f;
       
     UTIL_TraceLine( vecStart, vecStop, MASK_ALL, pPlayer, COLLISION_GROUP_NONE, &tr);

     if(tr.fraction == 1)
     {
      VectorMA( pSetup->origin, 32.0f, camUp, pSetup->origin);
      vecStart=tr.endpos;
     }
     else   
       //Add code to make the player transparent so the player can see better. (?)
     {
      VectorMA( pSetup->origin, 0.0f, camUp, pSetup->origin);
     }
    }

   }
       
   AngleVectors(pPlayer->EyeAngles(), &vecDirection);   
   vecStop = vecStart + vecDirection * -96;
   UTIL_TraceLine( vecStart, vecStop, MASK_ALL, pPlayer, COLLISION_GROUP_NONE, &tr );
     
   vecStart=pSetup->origin;
     
   vecStop = vecStart+vecDirection*-96;
   UTIL_TraceLine( vecStart, vecStop, MASK_ALL, pPlayer, COLLISION_GROUP_NONE, &tr );
        
   if(tr.fraction != 1)
   {
    camCurrentY = -96 * tr.fraction + 10.0f;
   }
   else
          {
    camCurrentY=-96.0f;
    VectorMA( pSetup->origin, camCurrentY, camForward, pSetup->origin);
   }
}

This will create a shoulder view that will stand by the right shoulder as standard. This is certainly not an ideal code, but to start creating some interesting mod, it may be suitable. If there is no space on the right, then a test will occur and if there is space, then x and z -16 / + 16 will be installed and then the distance behind will be checked. If there is no space to the left or to the right, z is set to +32 and x 0. This will place the camera above the player’s model head, so the player can still see. If there is not enough space above, the camera will be placed at eye level. All these checks are needed for the correct type of camera, for example, if you crawl in the ventilation pipes or worse, in the sewer

Шаг 3 - Исправляем маленький баг

Существует маленький баг, который нужно исправить, если его не исправить, то анимация вашего персонажа при повороте камеры по сторонам, будет глючить. Найдите и откройте c_sdk_player.cpp. Найдите функцию void C_SDKPlayer::UpdateClientSideAnimation() и замените содержимое на:

if ( this == C_SDKPlayer::GetLocalSDKPlayer() )
   m_PlayerAnimState->Update( EyeAngles()[YAW], EyeAngles()[PITCH] );
else
   m_PlayerAnimState->Update( m_angEyeAngles[YAW], EyeAngles()[PITCH] );

BaseClass::UpdateClientSideAnimation();

Теперь анимация должна быть корректной. Для игр на движке HL2MP нужно сделать немного другое. Найдите и откройте файл hl2mp_player.cpp. Найдите функцию void CHL2MP_Player::PostThink( void ) и замените содержимое на:

BaseClass::PostThink();
     
if ( GetFlags() & FL_DUCKING )
{
   SetCollisionBounds( VEC_CROUCH_TRACE_MIN, VEC_CROUCH_TRACE_MAX );
}

m_PlayerAnimState.Update();

QAngle angles = GetLocalAngles();

CBasePlayer *pPlayer = dynamic_cast<CBasePlayer*>(this);
if ( pPlayer )
{
   angles[PITCH] = EyeAngles()[PITCH];
   angles[YAW] = EyeAngles()[YAW];
}
else
{
   angles[PITCH] = EyeAngles()[PITCH];
   angles[YAW] = m_angEyeAngles[YAW];
}

SetLocalAngles( angles );

Теперь глюков быть не должно.

Шаг 4 - Саморегулирующийся прицел.

Найдите и откройте hud_crosshair.cpp. Он находиться в client.dll файлах. Теперь найдите функцию void CHudCrosshair::Paint( void ). Замените содержимое функции на:

if ( !m_pCrosshair )
   return;

if ( !IsCurrentViewAccessAllowed() )
   return;   

C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
Vector vecStart, vecStop, vecDirection, vecCrossPos;
trace_t tr;
     
AngleVectors(pPlayer->EyeAngles(), &vecDirection);

vecStart= pPlayer->EyePosition();
vecStop = vecStart + vecDirection * MAX_TRACE_LENGTH;
     
UTIL_TraceLine( vecStart, vecStop, MASK_ALL, pPlayer , COLLISION_GROUP_NONE, &tr );
     
     
ScreenTransform(tr.endpos, vecCrossPos);

m_pCrosshair->DrawSelf( 0.5f*ScreenWidth()+0.5f*ScreenWidth()*vecCrossPos[0]-0.5f*m_pCrosshair->Width(),   
     0.5f*ScreenHeight()+(0.5f*ScreenHeight()*-vecCrossPos[1])-0.5f*m_pCrosshair->Height(),
     m_clrCrosshair );

Так как вид уже из-за плеча, координаты прицела должны поменяться вот это собственно мы и изменяем.