HLFX.Ru Forum
профиль •  правила •  регистрация •  календарь •  народ •  FAQ •  поиск •  новое •  сутки •  главная •  выход  
HLFX.Ru Forum HLFX.Ru Forum > Теория и практика > Half-Life SDK > (Help!) Сдвиг камеры при приземлении как в CS:GO
Для ксаш-мода, кодинг
  Предыдущая тема   Следующая тема
Автор
Тема Новая тема    Ответить
Aynekko
Маппер

Дата регистрации: Jun 2016
Проживает: г. Подольск, Россия
Сообщений: 128
Возраст: 27

Рейтинг



Question (Help!) Сдвиг камеры при приземлении как в CS:GO

Привет всем! Хотел запостить в нубских вопросах, но, думаю, лучше создать отдельную тему.
Наверняка все видели анимацию приземления в csgo, когда вид от первого лица плавно и слегка пружинит вниз и возвращается обратно. Честно сказать, парюсь уже недели две, если не больше. До последнего не хотел создавать тему и пытался разобраться сам, но ничего не выходит. Надеюсь на какую-нибудь помощь. В общем, вот сам код из исходников csgo, который я нарыл:

C++ Source Code:
1
void CBasePlayer::CalcViewBob( Vector& eyeOrigin )
2
{
3
#if defined( CSTRIKE15 )
4
#if defined( CLIENT_DLL )
5
  if ( cl_use_new_headbob.GetBool() == false )
6
    return;
7
 
8
  Vector vecBaseEyePosition = eyeOrigin;
9
 
10
  // if we just landed, dip the player's view
11
    float flOldFallVel = m_Local.m_flOldFallVelocity;
12
  float flFallVel = m_Local.m_flFallVelocity;
13
  //Msg("Fall Velocity: %f\n", flFallVel );
14
 
15
  if ( flFallVel <= 0.1f && flOldFallVel > 10.0f && flOldFallVel <= PLAYER_FATAL_FALL_SPEED && m_Local.m_bInLanding == false )
16
  {
17
    m_Local.m_bInLanding = true;
18
    m_Local.m_flLandingTime = gpGlobals->curtime;
19
  }
20
 
21
  // don't bob the view right now
22
  /*
23
  		const float flMaxSpeed = sv_maxspeed.GetFloat();
24
  		float flSpeedFactor;
25
  		*/
26
 
27
  if ( m_Local.m_bInLanding == true )
28
  {
29
    float landseconds = MAX(gpGlobals->curtime - m_Local.m_flLandingTime, 0.0f);
30
    float landFraction = SimpleSpline( landseconds / 0.25f );
31
    clamp( landFraction, 0.0f, 1.0f );
32
 
33
    float flDipAmount = (1 / flOldFallVel) * 0.1f;
34
 
35
    int dipHighOffset = 64;
36
    int dipLowOffset = dipHighOffset - cl_headbob_land_dip_amt.GetInt();
37
    Vector temp = GetViewOffset();
38
    temp.z = ( ( dipLowOffset - flDipAmount ) * landFraction ) +
39
    ( dipHighOffset * ( 1 - landFraction ) );
40
 
41
    if ( temp.z > dipHighOffset )
42
    {
43
      temp.z = dipHighOffset;
44
      m_Local.m_bInLanding = false;
45
    }
46
    eyeOrigin.z -= ( dipHighOffset - temp.z );
47
    //SetViewOffset( temp );
48
  }
49
  else
50
  {
51
    // don't bob the view right now
52
    /*
53
    			flSpeedFactor = GetAbsVelocity().Length() / flMaxSpeed;
54
    			clamp( flSpeedFactor, 0.0f, 1.0f );
55
    			eyeOrigin.z += flSpeedFactor * (sin(gpGlobals->curtime * cl_headbob_freq.GetFloat() ) * cl_headbob_amp.GetFloat());
56
    			*/
57
  }
58
 
59
  // stop when our eyes get back to default
60
  if ( m_Local.m_bInLanding == true && ( (eyeOrigin.z - 0.001f) >= vecBaseEyePosition.z )  )
61
  {
62
    m_Local.m_bInLanding = false;
63
  }
64
 
65
  if ( m_Local.m_bInLanding == false  )
66
  {
67
    // Set the old velocity to the new velocity, we check next frame to see if we hit the ground
68
    m_Local.m_flOldFallVelocity = m_Local.m_flFallVelocity;
69
  }
70
#endif
71
#endif
72
}


Куда вставить этот код (конечно же не в этом виде!) я нашел - это в функцию PM_CheckFalling в playermove.cpp на сервере.
Изначально я сделал все проще и одной строчкой:
C++ Source Code:
pmove->punchangle.x = pmove->flFallVelocity * 0.005;

Ну такое, ага… Слишком резкое, и наклон идет не вертикальный, а вперед. В целом, вполне сошло бы, но что-то как-то не. Я даже пытался менять функцию punch, делая ее плавнее, но тогда "сломал" другие места, где она используется. Принял решение копать в другую сторону. Мне бы подошла функция из PM_Duck. Потому что если в ксаш-моде быстро нажать и отпустить приседание, камера плавно спускается вниз и тут же плавно возвращается. Но там все завязано, как я понял, на проверке "нажато ли приседание в текущем кадре, если нет - возврат".

Дальше идет полное ламерство. Все изменения, как уже сказал, делал в конце PM_CheckFalling - там, где стоял мой простой punchangle. Не знаю, корректно ли это, но я хотя бы уверен, что именно в этом месте выполняется код после приземления.
Итак: есть, значит, такая штука в коде, как pmove->view_ofs[2], которая отвечает за высоту взгляда игрока. Я логично рассудил, что мне "всего лишь" надо сделать, чтобы это значение после приземления плавно спускалось от дефолтного VEC_VIEW и, достигнув определенного значения, так же плавно вернулось обратно. В итоге я попробовал написать вот такую фигную:
C++ Source Code:
pmove->view_ofs[2] -= 3 * pmove->frametime;

Полный бред, теперь я уже знаю (значение 3 для эксперимента было, может и не 3 там было, уже не суть; по итогу просто после каждого призмеления взгляд просто спускался ниже и ниже. Но, думаю, что начал копать в правильном направлении, т.к. все плавные изменения чего-либо в коде всегда были завязаны на frametime или time, как я заметил.
Пытался еще сделать проверку, что при достижении какого-то уровня взгляда он бы возвращался к VEC_VIEW. После этого вообще ничего не менялось, т.к. все условия, видимо, выполнялись разом. Я рассчитывал увидеть отскок, хотя бы резкий. Увы.

Дальше я пытался завести временную переменную, и как-то отсчитывать от нее, но опять ничего не получилось. Либо изменений не было, либо камера просто резко смещалась вниз, ни о какой плавности речи не было.

Дальше я снова вернулся к коду приседания и попытался как-то впаять эту плавность к себе в PM_CheckFalling:
C++ Source Code:
1
float duckFraction;
2
float time;
3
float fMore = (VEC_DUCK_HULL_MIN - VEC_HULL_MIN);
4
time = max( 0.0, ( 1.0 - (float)pmove->flDuckTime / 1000.0 ) );
5
duckFraction = PM_SplineFraction( time, (1.0/TIME_TO_DUCK) );
6
pmove->view_ofs[2] = ((VEC_DUCK_VIEW - fMore ) * duckFraction) + (VEC_VIEW * (1-duckFraction));

Теперь при приземлении взгляд резко уходит вертикально вверх. Дальше уже ничего не вышло, либо ломалось все, либо так же взгляд уходил вверх.

Ну а дальше будет полный анекдот, можете просто посмеяться. Решил "адаптировать" функцию из csgo, прям копипастнул и отредактировал. С комментами.
Разумеется, ничего не получилось, кто бы мог подумать.

C++ Source Code:
1
#define clamp(a,b,c) (a = min(max(a, b), c))  // скопипастил сюда, иначе кламп не работал
2
float m_flFallVelocity = pmove->flFallVelocity;
3
float m_flOldFallVelocity = 0.0f; // взял из playerlocaldata.h (csgo)
4
bool m_bInLanding = false;        // взял из playerlocaldata.h (csgo)
5
float m_flLandingTime = -1.0f;    // взял из playerlocaldata.h (csgo)
6
 
7
Vector vecBaseEyePosition = pmove->view_ofs[2];  // вместо eyeOrigin, она же позиция глаз, видимо… поставил view_ofs. Ставил " = VEC_VIEW ", но тоже не сработало
8
 
9
// if we just landed, dip the player's view
10
  float flOldFallVel = m_flOldFallVelocity;   // m_Local.m_flOldFallVelocity; что такое м_локал, точно выяснить не удалось… поэтому решил переименовать так
11
float flFallVel = m_flFallVelocity;
12
//Msg("Fall Velocity: %f\n", flFallVel );
13
 
14
if ( flFallVel <= 0.1f && flOldFallVel > 10.0f && flOldFallVel <= PLAYER_FATAL_FALL_SPEED && m_bInLanding == false )
15
  // m_Local.m_bInLanding == false - это вообще шо? в playerlocaldata.h оно было false по-умолчанию, так что задал перед функцией
16
{
17
  m_bInLanding = true;
18
  m_flLandingTime = pmove->time;  // было m_Local.m_flLandingTime = gpGlobals->curtime;
19
}
20
 
21
// don't bob the view right now
22
/*
23
		const float flMaxSpeed = sv_maxspeed.GetFloat();
24
		float flSpeedFactor;
25
		*/
26
 
27
if ( m_bInLanding == true )
28
{
29
  float landseconds = max(pmove->time - m_flLandingTime, 0.0f);  // было  MAX(gpGlobals->curtime - m_Local.m_flLandingTime, 0.0f);
30
  float landFraction = SimpleSpline( landseconds / 0.25f );
31
  clamp( landFraction, 0.0f, 1.0f );
32
 
33
  float flDipAmount = (1 / flOldFallVel) * 0.1f;
34
 
35
  int dipHighOffset = 64;
36
  int dipLowOffset = dipHighOffset - 4;
37
  // было dipHighOffset - cl_headbob_land_dip_amt.GetInt(); - удалось выяснить, что значение cl_headbob--- равно 4 по-умолчанию
38
  Vector temp = pmove->view_ofs[2];   // было Vector temp = GetViewOffset();
39
  temp.z = ( ( dipLowOffset - flDipAmount ) * landFraction ) +
40
  ( dipHighOffset * ( 1 - landFraction ) );
41
 
42
  if ( temp.z > dipHighOffset )
43
  {
44
    temp.z = dipHighOffset;
45
    m_bInLanding = false;
46
  }
47
  pmove->view_ofs[2] -= ( dipHighOffset - temp.z );   // было eyeOrigin.z -= ( dipHighOffset - temp.z );
48
  //SetViewOffset( temp );
49
}
50
else
51
{
52
  // don't bob the view right now
53
  /*
54
  			flSpeedFactor = GetAbsVelocity().Length() / flMaxSpeed;
55
  			clamp( flSpeedFactor, 0.0f, 1.0f );
56
  			eyeOrigin.z += flSpeedFactor * (sin(gpGlobals->curtime * cl_headbob_freq.GetFloat() ) * cl_headbob_amp.GetFloat());
57
  			*/
58
}
59
 
60
// stop when our eyes get back to default
61
if ( m_bInLanding == true && ( (pmove->view_ofs[2] - 0.001f) >= VEC_VIEW )  )
62
  // было if ( m_Local.m_bInLanding == true && ( (eyeOrigin.z - 0.001f) >= vecBaseEyePosition.z )  )
63
{
64
  m_bInLanding = false;
65
}
66
 
67
if ( m_bInLanding == false  )
68
{
69
  // Set the old velocity to the new velocity, we check next frame to see if we hit the ground
70
  m_flOldFallVelocity = m_flFallVelocity;
71
}


Компилит, но результата ноль, то есть вообще ничего не происходит. Надо полагать и не должно, т.к. я вообще не уверен, что я тут наделал (но надеялся, эх ).

В общем, ниасилил. Спасибо, что прочитали, может было интересно. Если кто может помочь адаптировать функцию или подсказать, как это сделать проще, буду очень благодарен. Сам в матане/линале не шарю, а уж в кодинге…слишком сложно оказалось. Вот регенерацию хп из Portal стащить получилось, а тут никак. Ну там и строчек-то совсем мало было…

Сообщить модератору | | IP: Записан
Сообщение: 196057

Старое сообщение вчера 16:32
- За что?
 Дядя Миша
who said meow?

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 26404
Нанёс повреждений: 385 ед.

Рейтинг



Можно по аналогии с кодом сглаживания ступенек в view.cpp. Немного переделать.

__________________
My Projects: download page

Ты сегодня мне принёс гидравлический насос и сказал, что это ландышы
Но меня не проведёшь, насос на ландыш не похож, он большой, а ландыш маленький

Сообщить модератору | | IP: Записан
Сообщение: 196058

Старое сообщение вчера 18:46
-
Aynekko
Маппер

Дата регистрации: Jun 2016
Проживает: г. Подольск, Россия
Сообщений: 128
Возраст: 27

Рейтинг



Это я нашел, кажется

C++ Source Code:
1
if( !pparams->smoothing && pparams->onground && pparams->simorg[2] - oldz > 0.0f )
2
{
3
  float steptime;
4
 
5
  steptime = pparams->time - lasttime;
6
  if( steptime < 0 ) steptime = 0;
7
 
8
  oldz += steptime * 150.0f;
9
 
10
  if( oldz > pparams->simorg[2] )
11
    oldz = pparams->simorg[2];
12
  if( pparams->simorg[2] - oldz > pparams->movevars->stepsize )
13
    oldz = pparams->simorg[2] - pparams->movevars->stepsize;
14
 
15
  pparams->vieworg[2] += oldz - pparams->simorg[2];
16
}
17
else
18
{
19
  oldz = pparams->simorg[2];
20
}

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

Сообщить модератору | | IP: Записан
Сообщение: 196059

Старое сообщение вчера 19:31
- За что?
 Дядя Миша
who said meow?

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 26404
Нанёс повреждений: 385 ед.

Рейтинг



такие эффекты лучше всего и делать на клиенте.

__________________
My Projects: download page

Ты сегодня мне принёс гидравлический насос и сказал, что это ландышы
Но меня не проведёшь, насос на ландыш не похож, он большой, а ландыш маленький

Сообщить модератору | | IP: Записан
Сообщение: 196060

Старое сообщение вчера 19:44
-
Тема: (Опционально)
Ваш ответ:



Переводчик транслита


[проверить длину сообщения]
Опции: Автоматическое формирование ссылок: автоматически добавлять [url] и [/url] вокруг интернет адресов.
Уведомление по E-Mail: отправить вам уведомление, если кто-то ответил в тему (только для зарегистрированных пользователей).
Отключить смайлики в сообщении: не преобразовывать текстовые смайлики в картинки.
Показать подпись: добавить вашу подпись в конец сообщения (только зарегистрированные пользователи могут иметь подписи).

Временная зона GMT. Текущее время 10:46. Новая тема    Ответить
  Предыдущая тема   Следующая тема
HLFX.Ru Forum HLFX.Ru Forum > Теория и практика > Half-Life SDK > (Help!) Сдвиг камеры при приземлении как в CS:GO
Для ксаш-мода, кодинг
Версия для печати | Отправить тему по E-Mail | Подписаться на эту тему

Быстрый переход:
Оцените эту тему:

Правила Форума:
Вы not можете создавать новые темы
Вы not можете отвечать в темы
Вы not можете прикреплять вложения
Вы not можете редактировать ваши сообщения
HTML Код ВЫКЛ
vB Код ВКЛ
Смайлики ВКЛ
[IMG] Код ВКЛ
 

< Обратная связь - HLFX.ru >

На основе vBulletin
Авторское право © 2000 - 2002, Jelsoft Enterprises Limited.
Дизайн и программирование: Crystice Softworks © 2005 - 2020