Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Вопрос CS:Source ThirdPerson — Баг вьюмодели и анимации ног

Sloppy
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
13 Фев 2026
Сообщения
706
Реакции
18
Здарова, местные. Столкнулся с классикой жанра при написании своего интернала под старый добрый сурс. Пытаюсь довести до ума ThirdPerson через override_view, но Source Engine, как обычно, выкидывает фокусы с синхронизацией состояний.

Суть проблемы:
  1. Когда выключаю третье лицо, вьюмодель (руки/оружие) на пару фреймов ведет себя неадекватно — ломаются анимации или она просто пропадает.
  2. При включении TP ноги локального игрока иногда встают в Т-позу или проигрывают не ту секвенцию. Выглядит как типичная кривая паста.

Юзаю стандартный детаур на CViewSetup с интерполяцией камеры, чтобы картинка была плавной, а не дерганой при резких поворотах.

Код:
Expand Collapse Copy
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, как правильно фиксить эти транзишены между первым и третьим лицом, чтобы моделька не превращалась в манекен?

Интересует именно чистый метод без костылей с многократной перезаписью переменных в каждом тике.
 
Назад
Сверху Снизу