Ищу способ определить направление движения

Тема в разделе "Программирование / Скриптинг", создана пользователем iamdss, 1 авг 2015.

  1. iamdss

    iamdss

    Сообщения:
    117
    Симпатии:
    0
    Необходимо определить, в какую сторону движется игрок, относительно его направления обзора. Все известные мне способы дают только позицию и вектор, но информация о том, как эти данные относятся к линии, куда направлена камера игрока, отсутствует. Помогите примерным алгоритмом.

    Вкратце, зачем всё это. Многие ставят плагины, препятствующие распрыгу, у меня задача обратная, облегчить распрыг, но только если игрок прыгает спиной вперёд.
     
  2. gibs

    gibs Фитиль народного волненья

    Сообщения:
    542
    Симпатии:
    139
    Ну так вектор направления движения возьми и посчитай.
     
  3. iamdss

    iamdss

    Сообщения:
    117
    Симпатии:
    0
    В этом и заключается проблема. Видимо, я не совсем понимаю смысл вектора.

    Код:
    // Вот я получаю направление взгляда
    GetClientAbsAngles(client, Angle);
    // Вот получаю вектор
    GetAngleVectors(Angle, Velocity, NULL_VECTOR, NULL_VECTOR);
    Что я должен сделать далее?
     
  4. SourceGod

    SourceGod

    Сообщения:
    47
    Симпатии:
    0
    Может через AimTarget?
     
  5. iamdss

    iamdss

    Сообщения:
    117
    Симпатии:
    0
    GetClientAimTarget? Не думаю, что она как-то поможет. Или в чём заключается идея?
     
  6. SourceGod

    SourceGod

    Сообщения:
    47
    Симпатии:
    0
    iamdss, этим мы узнаем позицию прицела!
     
  7. Reiko1231

    Reiko1231 AlexTheRegent

    Сообщения:
    238
    Симпатии:
    569
    Нет конечно. Никогда при помощи этой функции мы не получим точную позицию прицела. Возвращаемое значение ф-и:
    Код:
    Entity index being aimed at. -1 if no entity is being aimed at
    Уже -1 в описании должен насторожить. Дальше мы можем получить индекс сущности, но опять же, чем описывается сущность? координаты (origin), угол поворота (angles) и скорость (velocity). А куда смотрит прицел, мы никак отсюда не узнаем, если только случайным образом позиция прицела не совпадет с координатами объекта. А чаще всего предмет смотрит на мир, а координаты мира вообще далеки от нужных нам. Поэтому для поиска позиции прицела только используют TraceRay функции (TR_*).

    Для решения этой задачи нужно вспомнить линал. Как определить, что векторы направлены противоположно друг другу? В случае нашей задачи начало координат в позиции игрока, так что эти векторы лежат на одной прямой (вектор движения игрока и вектор направления модели игрока). Если это нарисовать, то станет ясно, что нам нужно, чтобы угол между этими векторами был 180 градусов. Значит нам необходимо найти угол между вектором движения игрока и вектором направления модели игрока. Задача на самом деле проще - угол игрока нам искать не надо, есть ф-я GetClientAbsAngles(). AbsAngles, а не EyeAngles, т.к. нам нужна именно модель, а не взгляд игрока (модель не всегда вертится при повороте прицела). Найти угол движения игрока не так сложно: достаточно получить скорость игрока (GetEntPropVector("m_vecAbsVelocity")) и затем получить его угол (GetVectorAngles()). Затем найти разность нужной нам плоскости (т.к. мы в трехмерном мире), и по ней уже определить, движется игрок вперед или назад.

    Пример кода ниже, за движение назад принят угол в диапазоне от 160 до 200 градусов. При этом такой код учитывает, что игрок не сразу движется назад, а может тормозить, и в это время (несмотря на то, что он жмет назад) алгоритм не напишет, что клиент движется назад.
    Код:
    public OnPluginStart() 
    {
    	RegConsoleCmd("sm_test", Command_Test);
    }
    
    public Action Command_Test(int iClient, int iArgc)
    {
    	float vAngles[3], vVelocity[3], vDirection[3];
    	GetClientAbsAngles(iClient, vAngles);
    	GetEntPropVector(iClient, Prop_Data, "m_vecAbsVelocity", vVelocity);
    	GetVectorAngles(vVelocity, vDirection);
    	
    	float fabs = FloatAbs(vAngles[1] - vDirection[1]);
    	if ( fabs > 160 && fabs < 200 ) {
    		PrintToChat(iClient, "you are moving back");
    	}
    	
    	return Plugin_Handled;
    }
     
  8. iamdss

    iamdss

    Сообщения:
    117
    Симпатии:
    0
    Благодарю за помощь. Куда делась кнопка благодарности? Не вижу её... Ещё пару дней назад она была на месте.