Ru/Thinking: Difference between revisions

From Valve Developer Community
< Ru
Jump to navigation Jump to search
m (updated language bar. also some formatting.)
mNo edit summary
Line 1: Line 1:
{{lang|title=Thinking (Обновление)|en=Thinking}}[[Category:AI:ru]][[Category:Functions:ru]][[Category:Programming:ru]]
{{lang|title=Thinking (Обновление)|Thinking}}[[Category:AI:ru]][[Category:Functions:ru]][[Category:Programming:ru]]


<code>Think</code> (обновление) позволяет [[Entity:ru|Entity (энтити)]] объекту планировать запуск кода в определенное время. <code>Think</code> может работать постоянно, что позволяет создавать автономные энтити объекты.
<code>Think</code> (обновление) позволяет [[Entity:ru|Entity (энтити)]] объекту планировать запуск кода в определенное время. <code>Think</code> может работать постоянно, что позволяет создавать автономные энтити объекты.

Revision as of 16:22, 31 May 2022

English (en)Deutsch (de)Español (es)Português do Brasil (pt-br)Русский (ru)Translate (Translate)

Think (обновление) позволяет Entity (энтити) объекту планировать запуск кода в определенное время. Think может работать постоянно, что позволяет создавать автономные энтити объекты.

Планирование

Функция SetNextThink() настраивает следующий момент обновления энтити. Принимает значения float (число с плавающей запятой)

Warning icon.png
This article has been marked as a candidate for speedy deletion for the following reason:
Use {{Flag|en}} instead.
If you object to this decision, then please discuss why here (If you make a discussion section also create this redirect page). If this page doesn't meet the criteria for speedy deletion, then please remove this notice, but do not remove it from pages that you have created yourself
Administrators / Moderators - Remember to check if anything links here and the page history before deleting.

.

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, иначе может начаться бесконечный цикл. Template:Tip:ru

Создание собственных Think функций

Энтити может иметь любое количество дополнительных Think функций. Чтобы создать (зарегистрировать) еще одну функцию:

  1. Создайте свою функцию типа void.
  2. Добавьте ее в энтити DATADESC с помощью DEFINE_THINKFUNC().
  3. Вызовите SetThink() и укажите ссылку на вашу функцию Think (пример внизу).
  4. Проверьте наличие 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 функции можно легко переключаться между режимами работы вашей энтити. Template:Tip:ru

Использование контекстов

Можно запланировать (запустить) одновременно несколько Think функций с помощью «think contexts» (контексты). Чтобы создать новый контекст:

  1. Вызовите RegisterThinkContext(string ContextName) указав контекст (название) к Think функции.
  2. Вызовите SetContextThink(void* Function, float NextThinkTime, string ContextName) укажите функцию которая будет вызвана контекстом и название вашего контекста
  3. Для последующих вызовов 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 цикла, оба будут выводить определенные сообщения. Template:Tip:ru

Время

Вот некоторые функции определения времени обновления:

float	GetLastThink()     // время последнего обновления
float	GetNextThink()     // время следующего обновления
int	GetLastThinkTick() // время прошлого обновления в тиках (10,000,000 тик/ 1 секунд)
int	GetNextThinkTick() // время будущего обновления в тиках
Barnacle.jpg

Функции 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
Выполнять Think функцию после каждого кадра клиента. Используйте с осторожностью! Template:Tip:ru
CLIENT_THINK_NEVER
Остановка всех Think обновлений клиента.