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

iamdss

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

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

gibs

Фитиль народного волненья
Сообщения
722
Реакции
407
Мошенник
Ну так вектор направления движения возьми и посчитай.
 

iamdss

Участник
Сообщения
126
Реакции
12
В этом и заключается проблема. Видимо, я не совсем понимаю смысл вектора.

C-подобный:
// Вот я получаю направление взгляда
GetClientAbsAngles(client, Angle);
// Вот получаю вектор
GetAngleVectors(Angle, Velocity, NULL_VECTOR, NULL_VECTOR);

Что я должен сделать далее?
 

Reiko1231

AlexTheRegent
Сообщения
508
Реакции
1,336
iamdss, этим мы узнаем позицию прицела!
Нет конечно. Никогда при помощи этой функции мы не получим точную позицию прицела. Возвращаемое значение ф-и:
C-подобный:
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 градусов. При этом такой код учитывает, что игрок не сразу движется назад, а может тормозить, и в это время (несмотря на то, что он жмет назад) алгоритм не напишет, что клиент движется назад.
C-подобный:
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;
}
 

iamdss

Участник
Сообщения
126
Реакции
12
Благодарю за помощь. Куда делась кнопка благодарности? Не вижу её... Ещё пару дней назад она была на месте.
 
Сверху Снизу