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

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