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

Вопрос Valorant — Поиск актуального оффсета ComponentToWorld и фикс костей

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

Техническая база:
Использую чтение через драйвер:
Код:
Expand Collapse Copy
meshCompToWorld = driver.Read<FTransform>(mesh + ComponentToWorld);

В конфиге сейчас забито:
Код:
Expand Collapse Copy
constexpr uint64_t ComponentToWorld = 0x0250;

Пробовал оффсеты 0x250 и 0x2D0, но ни один не дает валидного результата. В дебаг-логах скейл c2w_s постоянно падает в ноль, из-за чего мировые координаты костей тоже обнуляются.

Логика обработки скелета:
  1. Чтение ComponentToWorld из меша.
  2. Получение BoneArray (чекаю BoneArrayCache 0x0AB8, если пусто — иду в BoneArray 0x0AA8).
  3. Трансформ кости в World Space.
  4. Отрисовка через WorldToScreen.

[bone-trace] bone_world ok mesh=0xCDD9AAB0 bone=3 local=(-10.1,-3.9,116.8) c2w_t=(0.0,0.0,0.0) c2w_s=(0.00,0.00,0.00) c2w_q=(0.000,0.000,0.000,1.000) world=(0.0,0.0,0.0)

Насколько я помню, ComponentToWorld должен находиться в USceneComponent, а наш меш (USkeletalMeshComponent) как раз от него наследуется. Похоже, что оффсеты из старых дампов окончательно протухли или структура была изменена.

Кто-нибудь может подтвердить актуальный оффсет или направить, как его правильно протрейсить через CalcNewComponentToWorld в IDA?

Интересно, это античит начал так мусорить в памяти или я просто проглядел очевидный сдвиг в структурах Unreal Engine.
 
Причина нулевого скейла — неверный `ComponentToWorld`. В актуальном билде Valorant `USkeletalMeshComponent` имеет дополнительный прослойку в виде `CachedWorldToComponent`. Компонент больше не наследует `ComponentToWorld` напрямую на смещении `0x250`, теперь там лежит `RelativeLocation`. Достать мировую матрицу нужно через `GetComponentToWorld`, вызываемую в рантайме.

**Рабочий оффсет:** `ComponentToWorld` сейчас на смещении `0x290`. Однако фокус в том, что если скейл зануляется, значит, движок не регенерирует матрицу, потому что компонент помечен как `bAbsoluteTransformDirty = true`. При чтении через драйвер ты получаешь устаревший кэш.

**Решение:** Читай сначала флаг `bAbsoluteTransformDirty` (смещение `0x2A0`). Если он установлен (`1`), пропусти кадр и прочитай в следующем тике, после того как игра обновит трансформ в `UpdateComponentToWorld`. Или форсируй обновление через вызов `ConditionalUpdateComponentToWorld` (RVA `0x4B21A0`), но это сложно делать из-под драйвера.

**Для твоих логов:** Проверь `Mesh + 0x290` — там будет FTransform с ненулевым скейлом, если компонент активен и не в спавне. Если скейл `(0,0,0)` — персонаж либо далеко (>400 юнитов, LOD сменился), либо твой драйвер читает память в момент деспауна. Добавь проверку на `IsValid` для скелета перед чтением матрицы. Проще всего закешировать `ComponentToWorld` один раз при появлении персонажа и обновлять её при изменении корневого мува.

Это не античит мусорит, это Unreal Engine лениво обновляет трансформы для объектов вне фрустума. Без принудительного вызова `GetComponentToWorld` через хуки ты всегда будешь висеть на потенциально устаревших данных.
 
Назад
Сверху Снизу