Ru/Thinking: Difference between revisions
m (изменены ссылки на категорию) |
No edit summary |
||
| Line 1: | Line 1: | ||
{{otherlang2 | {{otherlang2 | ||
|title=Обновление | |title=Thinking (Обновление) | ||
|en=Thinking | |en=Thinking | ||
|de=Thinking:de | |de=Thinking:de | ||
Revision as of 19:35, 25 July 2013
Think (обновление) позволяет Entity (энтити) объекту планировать запуск кода в определенное время. Think может работать постоянно, что позволяет создавать автономные энтити объекты.
Планирование
Функция SetNextThink() настраивает следующий момент обновления энтити. Принимает значения float (число с плавающей запятой)
void CMyEntity::Spawn()
{
BaseClass::Spawn();
SetNextThink( gpGlobals->curtime ); // Запустить Think прямо сейчас (обновить)
}
void CMyEntity::Think()
{
BaseClass::Think(); // Всегда пишите это здесь, если хотите предопределить функцию Think()
Msg( "Я думаю, следовательно, я существую.\n" );
SetNextThink( gpGlobals->curtime + 1 ); // Обновить еще раз, через 1 секунду
}
Данный код, после создания энтити, каждую секунду выводит сообщение.
Не забывайте использовать gpGlobals->curtime, чтобы задать следующее время обновления относительно текущего времени, после которого была запущена функция Think, иначе может начаться бесконечный цикл.
Создание собственных Think функций
Энтити может иметь любое количество дополнительных Think функций. Чтобы создать (зарегистрировать) еще одну функцию:
- Создайте свою функцию типа
void. - Добавьте ее в энтити DATADESC с помощью
DEFINE_THINKFUNC(). - Вызовите
SetThink()и укажите ссылку на вашу функциюThink(пример внизу). - Проверьте наличие
DECLARE_DATADESC();в вашем классе.
BEGIN_DATADESC( CMyEntity )
DEFINE_THINKFUNC( MyThink ), // Регистрация новой Think функции
END_DATADESC()
void CMyEntity::Spawn()
{
BaseClass::Spawn();
SetThink( &CMyEntity::MyThink ); // Задать Think указатель на функцию MyThink()
SetNextThink(gpGlobals->curtime);
}
void CMyEntity::MyThink()
{
Msg( "Я думаю, следовательно, я существую.\n" );
SetNextThink( gpGlobals->curtime + 1 );
}
Разделив ваш код на определенные Think функции можно легко переключаться между режимами работы вашей энтити.
Использование контекстов
Можно запланировать (запустить) одновременно несколько Think функций с помощью "think contexts" (контексты). Чтобы создать новый контекст:
- Вызовите
RegisterThinkContext(string ContextName)указав контекст (название) кThinkфункции. - Вызовите
SetContextThink(void* Function, float NextThinkTime, string ContextName) укажите функцию которая будет вызвана контекстом и название вашего контекста - Для последующих вызовов
Think, используйтеSetNextThink(float NextThinkTime, string ContextName)
BEGIN_DATADESC( CMyEntity )
DEFINE_THINKFUNC( ContextThink ),
END_DATADESC()
void CMyEntity::Spawn()
{
SetNextThink( gpGlobals->curtime ); // Запуск обычного Think - контекста нет
RegisterThinkContext( "TestContext" );
SetContextThink( &CMyEntity::ContextThink, gpGlobals->curtime, "TestContext" );
}
void CMyEntity::Think()
{
BaseClass::Think();
Msg( "Обновление\n" );
SetNextThink( gpGlobals->curtime + .1 );
}
void CMyEntity::ContextThink()
{
Msg( "Контекстное обновление\n" );
SetNextThink(gpGlobals->curtime + .2, "TestContext" );
}
Это создаст два Think цикла, оба будут выводить определенные сообщения.
Время
Вот некоторые функции определения времени обновления:
float GetLastThink() // время последнего обновления
float GetNextThink() // следующего обновления
int GetLastThinkTick() // тик (10,000,000 тик/ 1 секунд) прошлого обновления
int GetNextThinkTick() // будущего обновления
Функции GetLast полезны для управления скорости, с которой что-то происходит.
Это код Think энтити npc_barnacle фиксирующий скорость движения языка, при смене частоты обновления:
float dt = gpGlobals->curtime - GetLastThink(); // dt - это "delta time (изменение времени относительно прошлого обновления)"
SetAltitude( m_flAltitude + m_flBarnaclePullSpeed * dt ); // смена высоты языка барнакла
Данный код выполняется когда игрока хватает барнакл. Код делает анимацию языка плавной в отличии от скелетной анимации.
ClientThink() - Обновление клиента
Обновления могут быть обнаружены и со стороны клиента (Client-Side), однако есть ограничения. Для одной энтити доступна лишь одна Think функция.
void C_MyEntity::ClientThink()
{
Msg( "Не кладите ничего дорогого в эту функцию!\n" );
SetNextClientThink( CLIENT_THINK_ALWAYS ); // Обновлять каждый кадр
}
Некоторый примеры client-side обновления:
- Визуальные эффекты / партиклы
- VGUI экран взаимодействия
- Изменение скорости игрока (выполняется на стороне клиента, а также серверов, для избежания прогнозируемых ошибкок)
- Ноги страйдеров, привязки веревки (изначально отключено)
Функция SetNextClientThink() для запуска ClientThink(). Принимает два значения:
- CLIENT_THINK_ALWAYS
- Обновлять каждый кадр клиента. Используйте с осторожностью! Template:Tip:ru
- CLIENT_THINK_NEVER
- Остановка всех
Thinkобновлений клиента.