Ru/Thinking: Difference between revisions

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


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


== Планирование ==
== Планирование ==
 
Функция <code>SetNextThink()</code> настраивает следующий момент обновления энтити. Принимает значения [[float|float (число с плавающей запятой)]] {{en}}.
Функция <code>SetNextThink()</code> настраивает следующий момент обновления [[Entity|энтити]]. Принимает значения [[float|float (число с плавающей запятой)]]


<source lang=cpp>
<source lang=cpp>
Line 27: Line 22:
</source>
</source>


Данный код, после создания [[Entity|энтити]], каждую секунду выводит сообщение.
Данный код, после создания энтити, каждую секунду выводит сообщение.
 
Не забывайте использовать <code>[[gpGlobals]]->curtime</code>, чтобы задать следующее время обновления относительно текущего времени, после которого была запущена функция <code>Think</code>, иначе может начаться бесконечный цикл.


Не забывайте использовать <tt>gpGlobals->curtime</tt>, чтобы задать следующее время обновления относительно текущего времени, после которого была запущена функция <tt>Think</tt>, иначе может начаться бесконечный цикл.
{{tip:ru|<code>SetNextThink(0)</code> или <code>SetNextThink(null)</code> остановит любые следующие обновления.}}
{{tip:ru|<code>SetNextThink(0)</code> или <code>SetNextThink(null)</code> остановит любые следующие обновления.}}


== Создание собственных Think функций ==
== Создание собственных Think функций ==
 
Энтити может иметь любое количество дополнительных <code>Think</code> функций. Чтобы создать (зарегистрировать) еще одну функцию:
[[Entity|Энтити]] может иметь любое количество дополнительных <code>Think</code> функций. Чтобы создать (зарегистрировать) еще одну функцию:


# Создайте свою функцию типа <code>void</code>.
# Создайте свою функцию типа <code>void</code>.
# Добавьте ее в [[Entity|энтити]] [[Data_Descriptions:ru|DATADESC]] с помощью <code>DEFINE_THINKFUNC()</code>.
# Добавьте ее в энтити [[Data_Descriptions:ru|DATADESC]] с помощью <tt>DEFINE_THINKFUNC()</tt>.
# Вызовите <code>SetThink()</code> и укажите ссылку на вашу функцию <code>Think</code> (пример внизу).
# Вызовите <code>SetThink()</code> и укажите ссылку на вашу функцию <code>Think</code> (пример внизу).
# Проверьте наличие <code>DECLARE_DATADESC();</code> в вашем классе.
# Проверьте наличие <code>DECLARE_DATADESC();</code> в вашем классе.
Line 61: Line 54:
</source>
</source>


Разделив ваш код на определенные <code>Think</code> функции можно легко переключаться между режимами работы вашей [[Entity|энтити]].
Разделив ваш код на определенные <code>Think</code> функции можно легко переключаться между режимами работы вашей энтити.
 
{{tip:ru|<code>SetThink()</code> может быть использована и через саму функцию <code>Think</code>. Следующий вызов обновления будет сделан через новую выбранную функцию.}}
{{tip:ru|<code>SetThink()</code> может быть использована и через саму функцию <code>Think</code>. Следующий вызов обновления будет сделан через новую выбранную функцию.}}


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


# Вызовите <code>RegisterThinkContext([[string]] ContextName)</code> указав контекст (название) к <code>Think</code> функции.
# Вызовите <code>RegisterThinkContext([[string]] ContextName)</code> указав контекст (название) к <code>Think</code> функции.
Line 102: Line 93:


Это создаст два <code>Think</code> цикла, оба будут выводить определенные сообщения.
Это создаст два <code>Think</code> цикла, оба будут выводить определенные сообщения.
 
{{tip:ru|Создать новый контекст это хороший способ для планирования запуска вашей функции, при котором другие <code>Think</code> функции затронуты не будут.}}
{{tip:ru|Создать новый контекст - это хороший способ для планирования запуска вашей функции, при котором другие <code>Think</code> функции затронуты не будут.}}


== Время ==
== Время ==
Line 119: Line 109:


Функции <code>GetLast</code> полезны для управления скорости, с которой что-то происходит.  
Функции <code>GetLast</code> полезны для управления скорости, с которой что-то происходит.  
Это <code>Think</code> код [[Entity|энтити]] [[npc_barnacle]] фиксирующий скорость движения языка, при смене частоты обновления:
Это <code>Think</code> код энтити {{ent:ru|npc_barnacle}} фиксирующий скорость движения языка, при смене частоты обновления:


<source lang=cpp>
<source lang=cpp>
Line 128: Line 118:
Данный код выполняется когда игрока хватает барнакл. Код делает анимацию языка плавной в отличии от скелетной анимации.
Данный код выполняется когда игрока хватает барнакл. Код делает анимацию языка плавной в отличии от скелетной анимации.


== ClientThink() - Обновление клиента ==
==<tt>ClientThink()</tt> - Обновление клиента==
 
Обновления могут быть объявлены и со стороны клиента («Client-Side»), однако есть ограничения. Для одной энтити доступна лишь одна <code>Think</code> функция.
Обновления могут быть объявлены и со стороны клиента (Client-Side), однако есть ограничения. Для одной [[Entity|энтити]] доступна лишь одна <code>Think</code> функция.


<source lang=cpp>
<source lang=cpp>
Line 141: Line 130:


Некоторый примеры client-side обновления:
Некоторый примеры client-side обновления:
* Визуальные эффекты / партиклы
* Визуальные эффекты / партиклы
* VGUI экран взаимодействия
* VGUI экран взаимодействия
Line 149: Line 137:
Функция <code>SetNextClientThink()</code> для запуска <code>ClientThink()</code>. Принимает два значения:
Функция <code>SetNextClientThink()</code> для запуска <code>ClientThink()</code>. Принимает два значения:


; CLIENT_THINK_ALWAYS
; <tt>CLIENT_THINK_ALWAYS</tt>: Выполнять <code>Think</code> функцию после каждого кадра клиента. Используйте с осторожностью! {{tip:ru|Используйте <code>gpGlobals->frametime</code> для регулирования скорости.}}
: Выполнять <code>Think</code> функцию после каждого кадра клиента. Используйте с осторожностью! {{tip:ru|Используйте <code>[[gpGlobals]]->frametime</code> для регулирования скорости.}}
; <tt>CLIENT_THINK_NEVER</tt>: Остановка всех <code>Think</code> обновлений клиента.
; CLIENT_THINK_NEVER
: Остановка всех <code>Think</code> обновлений клиента.
 
[[Category:Programming:ru]]
[[Category:AI:ru]]
[[Category:Functions:ru]]

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 (число с плавающей запятой) English.

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 обновлений клиента.