Приветствую.
На днях разбирался в работе хитбоксов игрока и возможных багах связанных с ними.
На первом этапе постарался определить основные проблемы:
1. Отсутствие синхронизации углов вращения модели игрока на сервере и клиенте.
2. Возможные проблемы с блендингом (этот вопрос ещё не разбирал). Блендинг в модели игрока отвечает за перекос верхней части туловища по двум осям. Благодаря ему модель игрока может смотреть "вверх/вниз", ну или помотать головой например. За информацию по блендингу отвечают два pev:
pev_blending_0,
pev_blending_1,
Как я понял, они являются чисто информационными и изменить их значение со стороны Амх нельзя, хотя блендинг ещё есть в фуллпаке "ES_Blending", но так далеко я пока не залезал.
3. Отставание модели игрока от реальных хитбоксов во время перемещения (чем выше скорость, тем больше отставание). Решается значением ex_interp 0.01 на клиенте.
На сколько я понял, решить эти проблемы (особенно последнюю), без изменения движка/протокола не получится, т.к. все эти "Баги" (на сколько я понимаю) призваны компенсировать возможные задержки между сервером и клиентом.
Немного поковыряв сурсы, нашел код, который отвечает за возникновение первой проблемы:
И очень занятный оффсет m_flGaitYaw. Как раз он выдает правильный угол модели и на его основе рассчитывается угол на стороне сервера. Очевидно, что на стороне клиента этот код другой.
После, я собрал код в виде отдельной энтити, которая в пресинке перенимает от игрока: Оригины, Велосити, Кадр анимации и Animtime, а угол был скопирован с m_flGaitYaw, что в итоге дало "видимую" модель игрока с правильными хитбоксами. Фактически, такая реализация решает 1 и 3 проблемы (хотя в идеале нужен фуллпак).
В моем случае я использовал полностью кастомные анимации модели игрока с измененным скелетом, по этому у меня не возникло проблем с анимациями ног "gaitsequence" и на сколько я понимаю, задействовать их на отдельной энтити не получится, т.к. gaitsequence работает только на реальном игроке.
Вот пример различия работы хитбоксов:
Взята большая модель. Есть пример не првильного рассчета углов и отставания реальных хитбоксов от клиентской модели при быстром передвижении.
У кого какие мысли ? Кто уже пробовал ковырять в этом направлении ?
На днях разбирался в работе хитбоксов игрока и возможных багах связанных с ними.
На первом этапе постарался определить основные проблемы:
1. Отсутствие синхронизации углов вращения модели игрока на сервере и клиенте.
2. Возможные проблемы с блендингом (этот вопрос ещё не разбирал). Блендинг в модели игрока отвечает за перекос верхней части туловища по двум осям. Благодаря ему модель игрока может смотреть "вверх/вниз", ну или помотать головой например. За информацию по блендингу отвечают два pev:
pev_blending_0,
pev_blending_1,
Как я понял, они являются чисто информационными и изменить их значение со стороны Амх нельзя, хотя блендинг ещё есть в фуллпаке "ES_Blending", но так далеко я пока не залезал.
3. Отставание модели игрока от реальных хитбоксов во время перемещения (чем выше скорость, тем больше отставание). Решается значением ex_interp 0.01 на клиенте.
На сколько я понял, решить эти проблемы (особенно последнюю), без изменения движка/протокола не получится, т.к. все эти "Баги" (на сколько я понимаю) призваны компенсировать возможные задержки между сервером и клиентом.
Немного поковыряв сурсы, нашел код, который отвечает за возникновение первой проблемы:
Код:
void CBasePlayer::StudioEstimateGait(void)
{
float dt;
vec3_t est_velocity;
dt = gpGlobals->frametime;
if (dt < 0)
dt = 0;
else if (dt > 1)
dt = 1;
if (dt == 0)
{
m_flGaitMovement = 0;
return;
}
est_velocity[0] = pev->origin[0] - m_prevgaitorigin[0];
est_velocity[1] = pev->origin[1] - m_prevgaitorigin[1];
est_velocity[2] = pev->origin[2] - m_prevgaitorigin[2];
m_prevgaitorigin[0] = pev->origin[0];
m_prevgaitorigin[1] = pev->origin[1];
m_prevgaitorigin[2] = pev->origin[2];
m_flGaitMovement = sqrt(est_velocity[0] * est_velocity[0] + est_velocity[1] * est_velocity[1] + est_velocity[2] * est_velocity[2]);
if (dt <= 0 || m_flGaitMovement / dt < 5)
{
m_flGaitMovement = 0;
est_velocity[0] = est_velocity[1] = 0;
}
if (est_velocity[0] == 0 && est_velocity[1] == 0)
{
float flYawDiff = pev->angles[1] - m_flGaityaw;
float flYaw = flYawDiff;
flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360;
if (flYawDiff > 180)
flYawDiff -= 360;
if (flYawDiff < -180)
flYawDiff += 360;
if (flYaw < -180)
flYaw += 360;
else if (flYaw > 180)
flYaw -= 360;
if (flYaw > -5 && flYaw < 5)
m_flYawModifier = 0.05;
if (flYaw < -90 || flYaw > 90)
m_flYawModifier = 3.5;
if (dt < 0.25)
flYawDiff *= dt * m_flYawModifier;
else
flYawDiff *= dt;
if (abs(flYawDiff) < 0.1)
flYawDiff = 0;
m_flGaityaw += flYawDiff;
m_flGaityaw -= (int)(m_flGaityaw / 360) * 360;
m_flGaitMovement = 0;
}
else
{
m_flGaityaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI);
if (m_flGaityaw > 180)
m_flGaityaw = 180;
if (m_flGaityaw < -180)
m_flGaityaw = -180;
}
}
void CBasePlayer::CalculateYawBlend(void)
{
float dt;
float flYaw;
float maxyaw;
float blend_yaw;
dt = gpGlobals->frametime;
if (dt < 0)
dt = 0;
else if (dt > 1)
dt = 1;
StudioEstimateGait();
maxyaw = 255.0;
flYaw = pev->angles[1] - m_flGaityaw;
if (flYaw < -180)
flYaw += 360;
else if (flYaw > 180)
flYaw -= 360;
if (m_flGaitMovement != 0)
{
if (flYaw > 120)
{
m_flGaityaw -= 180;
m_flGaitMovement = -m_flGaitMovement;
flYaw -= 180;
}
else if (flYaw < -120)
{
m_flGaityaw += 180;
m_flGaitMovement = -m_flGaitMovement;
flYaw += 180;
}
}
flYaw = (flYaw / 90) * 128.0 + 127.0;
if (flYaw > 255)
flYaw = 255;
else if (flYaw < 0)
flYaw = 0;
blend_yaw = maxyaw - flYaw;
pev->blending[0] = (int)(blend_yaw);
m_flYaw = blend_yaw;
}
И очень занятный оффсет m_flGaitYaw. Как раз он выдает правильный угол модели и на его основе рассчитывается угол на стороне сервера. Очевидно, что на стороне клиента этот код другой.
После, я собрал код в виде отдельной энтити, которая в пресинке перенимает от игрока: Оригины, Велосити, Кадр анимации и Animtime, а угол был скопирован с m_flGaitYaw, что в итоге дало "видимую" модель игрока с правильными хитбоксами. Фактически, такая реализация решает 1 и 3 проблемы (хотя в идеале нужен фуллпак).
В моем случае я использовал полностью кастомные анимации модели игрока с измененным скелетом, по этому у меня не возникло проблем с анимациями ног "gaitsequence" и на сколько я понимаю, задействовать их на отдельной энтити не получится, т.к. gaitsequence работает только на реальном игроке.
Вот пример различия работы хитбоксов:
Взята большая модель. Есть пример не првильного рассчета углов и отставания реальных хитбоксов от клиентской модели при быстром передвижении.
У кого какие мысли ? Кто уже пробовал ковырять в этом направлении ?
Последнее редактирование: