- Статус
- Оффлайн
- Регистрация
- 13 Фев 2026
- Сообщения
- 706
- Реакции
- 18
Здарова, местные. Столкнулся с классикой жанра при написании своего интернала под старый добрый сурс. Пытаюсь довести до ума ThirdPerson через override_view, но Source Engine, как обычно, выкидывает фокусы с синхронизацией состояний.
Суть проблемы:
Юзаю стандартный детаур на CViewSetup с интерполяцией камеры, чтобы картинка была плавной, а не дерганой при резких поворотах.
Подозреваю, что движок не успевает корректно обновить флаги в C_BasePlayer или нужно форсить UpdateClientSideAnimation, но просто втыкать его куда попало не хочется — полетят тайминги в других хуках. Кто ковырял анимации в CSS, как правильно фиксить эти транзишены между первым и третьим лицом, чтобы моделька не превращалась в манекен?
Интересует именно чистый метод без костылей с многократной перезаписью переменных в каждом тике.
Суть проблемы:
- Когда выключаю третье лицо, вьюмодель (руки/оружие) на пару фреймов ведет себя неадекватно — ломаются анимации или она просто пропадает.
- При включении TP ноги локального игрока иногда встают в Т-позу или проигрывают не ту секвенцию. Выглядит как типичная кривая паста.
Юзаю стандартный детаур на CViewSetup с интерполяцией камеры, чтобы картинка была плавной, а не дерганой при резких поворотах.
Код:
void override_view_detour(void* rcx, CViewSetup* pSetup) {
original(rcx, pSetup);
if (!pSetup || !local || !local->is_alive()) {
if (g_was_tp) {
i::input->m_fCameraInThirdPerson() = false;
g_was_tp = false;
}
return;
}
bool want_tp = is_thirdperson_active();
if (want_tp && !g_was_tp) {
i::input->m_fCameraInThirdPerson() = true;
tp_first_frame = true;
g_was_tp = true;
} else if (!want_tp && g_was_tp) {
i::input->m_fCameraInThirdPerson() = false;
g_was_tp = false;
}
if (g_was_tp) {
vec3 fwd, right, up;
math::angle_vectors(pSetup->Angles, &fwd, &right, &up);
float dist = fCFG[fCfg::misc_thirdperson_dist];
if (dist < 30.f) dist = 120.f;
vec3 eye = local->get_eye_pos();
vec3 end = eye + fwd * -dist;
Ray_t ray;
ray.Init(eye, end, {-9,-9,-9}, {9,9,9});
CTraceFilterWorldAndPropsOnly filter;
trace_t tr;
i::engine_trace->trace_ray(ray, MASK_SOLID, &filter, &tr);
static float last_rt = 0.f;
if (tp_first_frame) {
tp_origin = tr.endpos;
last_rt = i::global_vars->realtime;
tp_first_frame = false;
}
float dt = i::global_vars->realtime - last_rt;
last_rt = i::global_vars->realtime;
if (dt <= 0.f || dt > 1.f) dt = 0.016f;
static vec3 last_ang = {};
float ang_delta = std::abs(pSetup->Angles.x - last_ang.x)
+ std::abs(pSetup->Angles.y - last_ang.y);
last_ang = pSetup->Angles;
float t = 1.f - std::exp(-(ang_delta > 0.1f ? 100.f : 80.f) * dt);
tp_origin.x += (tr.endpos.x - tp_origin.x) * t;
tp_origin.y += (tr.endpos.y - tp_origin.y) * t;
tp_origin.z += (tr.endpos.z - tp_origin.z) * t;
pSetup->Origin = tp_origin;
}
}
Подозреваю, что движок не успевает корректно обновить флаги в C_BasePlayer или нужно форсить UpdateClientSideAnimation, но просто втыкать его куда попало не хочется — полетят тайминги в других хуках. Кто ковырял анимации в CSS, как правильно фиксить эти транзишены между первым и третьим лицом, чтобы моделька не превращалась в манекен?
Интересует именно чистый метод без костылей с многократной перезаписью переменных в каждом тике.