Ru/Understanding VGUI2 Animation: Difference between revisions

From Valve Developer Community
< Ru
Jump to navigation Jump to search
(Created page with "{{otherlang2 |en=Understanding_VGUI2_Animation }} = Introduction = VGUI2 has a pretty powerful animation system for animating both HUD elements and VGUI panels. Here is a rela...")
 
No edit summary
Line 2: Line 2:
|en=Understanding_VGUI2_Animation
|en=Understanding_VGUI2_Animation
}}
}}
= Introduction =
= Вступление =
VGUI2 has a pretty powerful animation system for animating both HUD elements and VGUI panels. Here is a relatively complete overview of what you can do with it.
VGUI2 имеет довольно мощную систему анимации для анимации как элементов HUD, так и панелей VGUI. Вот относительно полный обзор того, что с ним можно делать.


= Architecture Overview =
= Обзор архитектуры =
The animation system is defined in '''AnimationController.cpp''', which can be found under '''vgui2/vgui_controls'''. It is very extensive, but the main concept is as follows:
Система анимации определена в '''AnimationController.cpp''', который можно найти в '''vgui2/vgui_controls'''. Он очень обширный, но основная концепция такова:
* Add animations through several methods
* Добавлять анимацию можно несколькими способами
* Run these animations each tick, using an interpolator function to calculate the intermediate value.
* Запускайте эти анимации каждый тик, используя функцию интерполятора для вычисления промежуточного значения.


There are two main ways to add animations, which are script-defined '''events''' and '''dynamic animations''', which are done during run-time.
Есть два основных способа добавления анимации, которые представляют собой определяемые сценарием события и динамические анимации, которые выполняются во время выполнения.


= Events =
= События =
Animation events can be loaded from two sources, both of which are located in the '''scripts''' folder:
События анимации могут быть загружены из двух источников, оба из которых находятся в папке '''scripts''':
* The animation script manifest: '''hudanimations_manifest.txt'''. If this isn't found, the latter is loaded:
* Манифест сценария анимации: '''hudanimations_manifest.txt'''. Если он не найден, загружается последний:
* A single script file: '''HudAnimations.txt'''.
* Один файл сценария: '''HudAnimations.txt'''.
{{Note|Even though it says "Hud" right there in the name, Events can also be defined for VGUI panels.}}
{{Note:ru|Несмотря на то, что прямо в названии написано «Hud», события также могут быть определены для панелей VGUI.}}




The manifest expects a KeyValue file, and will load each file in the manifest:
Манифест это обычный файл KeyValue. Он будет загружать каждый файл в манифесте:
  "HudAnimationManifest"
  "HudAnimationManifest"
  {
  {
Line 26: Line 26:
  }
  }


{{Tip|Neither the '''hudanimations_manifest.txt''' nor the '''HudAnimations.txt''' file will most likely be present. You can find the latter in the '''base source engine 2.gcf''' GCF file.}}
{{Tip:ru|Скорее всего, в директории '''scripts''' не будет ни '''hudanimations_manifest.txt''', ни '''HudAnimations.txt'''. Вы можете найти последний в директории '''hl2/scripts/'''.}}


== File Layout ==
== Макет файла ==
Opening up '''HudAnimations.txt''', you will see many events used in Half-Life 2. Here's the syntax of an event:
Открыв '''HudAnimations.txt''', вы увидите множество событий, используемых в Half-Life 2. Вот синтаксис события:
  event '''<EVENTNAME>'''
  event '''<EVENTNAME>'''
  {
  {
Line 35: Line 35:
  }
  }


== Event overview ==
== Обзор событий ==
At the top of the file, you'll see a lovely overview of possible commands and their arguments. Here is an updated overview (there's some new stuff in the code):
Вверху файла вы увидите прекрасный обзор возможных команд и их аргументов. Вот обновленный обзор (в коде есть кое-что новое):


* '''Animate'''
* '''Animate'''
** Arguments: <panel name> <variable> <target value(s)> <interpolator> <start time> <duration>
** Аргументы: <panel name> <variable> <target value(s)> <interpolator> <start time> <duration>
*** Valid panel names: Any VGUI or HUD panel.
*** Допустимые названия панелей: любая панель VGUI или HUD.
*** Valid variables: {{Note|Italic values only work for HUD panels and/or weapon selection}}
*** Допустимые значения: {{Note:ru|Значения курсивом (Italic) работают только для панелей HUD и/или выбора оружия.}}
**** Unary (1 argument): Xpos, Ypos, Wide, Tall, ''Blur, Alpha, SelectionAlpha''
**** Унарный (1 аргумент): Xpos, Ypos, Ширина, Высота, ''Блюр, Прозрачность(Альфа), Прозрачность при выборе элемента''
**** Binary (2 arguments): Position, Size
**** Двоичный (2 аргумента): Позиция, Размер
**** More than two: FgColor, BgColor, ''TextColor, Ammo2Color'' {{Tip|Color variables can also reference a scheme-defined color instead of an RGBA value, e.g. FgColor "BrightDamagedFg"}}
**** Более двух: FgColor, BgColor, ''TextColor, Ammo2Color'' {{Tip:ru|Цветовые переменные также могут ссылаться на определенный схемой цвет вместо значения RGBA, например FgColor "BrightDamagedFg"}}
**** Unknown: ''TextScan''
**** Неизвестный: ''TextScan''
**** Any values of the types KeyValues::TYPE_FLOAT and KeyValues::TYPE_COLOR that are accessible when calling '''RequestInfo''' on the panel are also modifiable.<sup id="fnote1">'''[[#Footnotes|1]]'''</sup>
****Любые значения типов KeyValues ​​::TYPE_FLOAT и KeyValues ​​::TYPE_COLOR, которые доступны при вызове '''RequestInfo''' на панели, также можно изменять. <Sup id = "fnote1"> '''[[#Footnotes|1]]'''</sup>
**** [[#Defining animation variables in code|Variables defined in code]]
**** [[#Defining animation variables in code|Variables defined in code]]
*** Valid target values: Any floating-point value. '''Up to four values are possible.''' Put multiple values between quotes (e.g. "255 0 0 255" or "512 512")
*** Valid target values: Any floating-point value. '''Up to four values are possible.''' Put multiple values between quotes (e.g. "255 0 0 255" or "512 512")

Revision as of 18:25, 19 June 2021

Template:Otherlang2

Вступление

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

Обзор архитектуры

Система анимации определена в AnimationController.cpp, который можно найти в vgui2/vgui_controls. Он очень обширный, но основная концепция такова:

  • Добавлять анимацию можно несколькими способами
  • Запускайте эти анимации каждый тик, используя функцию интерполятора для вычисления промежуточного значения.

Есть два основных способа добавления анимации, которые представляют собой определяемые сценарием события и динамические анимации, которые выполняются во время выполнения.

События

События анимации могут быть загружены из двух источников, оба из которых находятся в папке scripts:

  • Манифест сценария анимации: hudanimations_manifest.txt. Если он не найден, загружается последний:
  • Один файл сценария: HudAnimations.txt.

Template:Note:ru


Манифест это обычный файл KeyValue. Он будет загружать каждый файл в манифесте:

"HudAnimationManifest"
{
	"file" "scripts/HudAnimations.txt"
	// You can add more here
}

Template:Tip:ru

Макет файла

Открыв HudAnimations.txt, вы увидите множество событий, используемых в Half-Life 2. Вот синтаксис события:

event <EVENTNAME>
{
	<COMMAND>	<ARGUMENTS>
}

Обзор событий

Вверху файла вы увидите прекрасный обзор возможных команд и их аргументов. Вот обновленный обзор (в коде есть кое-что новое):

  • Animate
    • Аргументы: <panel name> <variable> <target value(s)> <interpolator> <start time> <duration>
      • Допустимые названия панелей: любая панель VGUI или HUD.
      • Допустимые значения: Template:Note:ru
        • Унарный (1 аргумент): Xpos, Ypos, Ширина, Высота, Блюр, Прозрачность(Альфа), Прозрачность при выборе элемента
        • Двоичный (2 аргумента): Позиция, Размер
        • Более двух: FgColor, BgColor, TextColor, Ammo2Color Template:Tip:ru
        • Неизвестный: TextScan
        • Любые значения типов KeyValues ​​::TYPE_FLOAT и KeyValues ​​::TYPE_COLOR, которые доступны при вызове RequestInfo на панели, также можно изменять. 1
        • Variables defined in code
      • Valid target values: Any floating-point value. Up to four values are possible. Put multiple values between quotes (e.g. "255 0 0 255" or "512 512")
      • Valid interpolators:
        • Linear
        • Accel - starts moving slow, ends fast
        • Deaccel - starts moving fast, ends slow
        • Spline - very smooth interpolation
        • Pulse - uses a sine pulse to interpolate. Expects a frequency value.
        • Flicker - uses the PRNG to determine whether to be at original value or at the final value, which causes a flicker effect. Expects a noise amount value.
          Tip.pngСовет: Both Pulse and Flicker take an extra value, so be sure to put one in the scripts.
      • Valid start times: Any floating-point value. Essentially a delay factor.
      • Valid durations: Any floating-point value.
  • RunEvent: starts another event running at the specified time.
    • Arguments: <event name> <start time>
      • Valid event names: Any event defined in the animation files.
  • StopEvent: stops another event that is currently running at the specified time.
    • Arguments: <event name> <start time>
  • StopAnimation: stops all animations referring to the specified variable in the specified panel.
    • Arguments: <panel name> <variable> <start time>
  • StopPanelAnimations: stops all active animations operating on the specified panel.
    • Arguments: <panel name> <start time>
  • SetFont:
    Нужно сделать: Look up what this does.
    • Arguments: <panel name> <font parameter> <font name from scheme> <set time>
  • SetTexture:
    Нужно сделать: Look up what this does.
    • Arguments: <panel name> <texture ID> <material name> <set time>
  • SetString:
    Нужно сделать: Look up what this does.
    • Arguments: <panel name> <string variable name> <value to set> <set time>

Executing Animations

Accessing the controller

First off, you'll need some includes. If you're working in a class that uses the vgui namespace, you can call the animation controller by including vgui_controls/AnimationController.h and calling it like so:

 vgui::GetAnimationController()

If you're not using the vgui namespace, you'll need to include both clientmode.h and vgui_controls/AnimationController.h, and call the animation controller like so:

 g_pClientMode->GetViewportAnimationController()

Executing Events

An event can be executed using the StartAnimationSequence method, which has two overloads. One simply takes the event name and looks up panels by itself, starting from the root panel, and the other takes the event name and a pointer to a panel that houses the controls that will be animated.

 vgui::GetAnimationController()->StartAnimationSequence( "ShowCommentary" ); // Just the event name
 vgui::GetAnimationController()->StartAnimationSequence( this, "MapZoomToLarge" ); // Event name + parent panel (example from CS:S)

Defining animation variables in code

Defining a variable that can be used in the event files is easy, and uses the following macro:

 #define CPanelAnimationVar( type, name, scriptname, defaultvalue )\
 	CPanelAnimationVarAliasType( type, name, scriptname, defaultvalue, #type )

Looking through code references, this appears to work fine for: 2

  • Colors: CPanelAnimationVar( Color, m_cChangableColor, "Changable_Color", "0 0 0 0" );
  • Fonts: CPanelAnimationVar( vgui::HFont, m_hChangableFont, "FontOverride", "DefaultSmall" );
  • Floats: CPanelAnimationVar( float, m_fChangableFloat, "FloatAnimation", "0" );
  • Integers: CPanelAnimationVar( int, m_iChangableInt, "IntOverride", "0" );
  • Booleans: CPanelAnimationVar( bool, m_bChangableBool, "BoolOverride", "0" );

Executing dynamic animations

Events are handy for static animations, but if you want to load any argument on the fly, you'll need dynamic animations. It's surprisingly simple!

Preparing for running animations

The method we are interested in is called RunAnimationCommand, and takes arguments similarly to the events defined above.

Note.pngПримечание:If you're accessing the controller via g_pClientMode, you'll want to call the UpdateAnimations method manually in the OnThink() method of your panel.


The RunAnimationCommand has two overloads: one for a single value, and another for multiple values. Unfortunately, the multiple-valued one uses the Color class to load any values, which means the values will be truncated to integers AND wrap around very quickly! To mitigate this, let's create a new overload:

Copy this under the other RunAnimationCommand overloads in AnimationController.cpp:

 //-----------------------------------------------------------------------------
 // Purpose: Runs a custom command from code, not from a script file
 //-----------------------------------------------------------------------------
 void AnimationController::RunAnimationCommand(vgui::Panel *panel, const char *variable, PublicValue_t targetValue, float startDelaySeconds, float duration, Interpolators_e interpolator, float animParameter /* = 0 */ )
 {
 	// clear any previous animations of this variable
 	UtlSymId_t var = g_ScriptSymbols.AddString(variable);
 	RemoveQueuedAnimationByType(panel, var, UTL_INVAL_SYMBOL);
 
 	// build a new animation
 	AnimCmdAnimate_t animateCmd;
 	memset(&animateCmd, 0, sizeof(animateCmd));
 	animateCmd.panel = 0;
 	animateCmd.variable = var;
 	animateCmd.target.a = targetValue.a;
 	animateCmd.target.b = targetValue.b;
 	animateCmd.target.c = targetValue.c;
 	animateCmd.target.d = targetValue.d;
 	animateCmd.interpolationFunction = interpolator;
 	animateCmd.interpolationParameter = animParameter;
 	animateCmd.startTime = startDelaySeconds;
 	animateCmd.duration = duration;
 
 	// start immediately
 	StartCmd_Animate(panel, 0, animateCmd);
 }

And copy this above the prototype of RunAnimationCommand in AnimationController.h:

 struct PublicValue_t
 {
 	float a, b, c, d;
 };
 void RunAnimationCommand(vgui::Panel *panel, const char *variable, PublicValue_t targetValue, float startDelaySeconds, float durationSeconds, Interpolators_e interpolator, float animParameter = 0 );
Note.pngПримечание:I know, there's a perfectly fine Value_t struct that we can also use, but when I made it public, the entire class went haywire. Feel free to find a correct implementation.

Running animations

Now we're in business! You can call animations though the controller very easily. Here's an example as to how you would programmatically change the size of an ImagePanel:

Let's say we have an ImagePanel called "overviewImage ", which is defined in our panel's .res file. First, we get the panel:

 m_pOverviewImage = dynamic_cast<ImagePanel*>( FindChildByName( "overviewImage ", false ) );
Note.pngПримечание:Put this in the class constructor right after you've loaded the Resource file. If you're confused, read this: Loading a Resource File.

You can then resize the ImagePanel as follows:

 AnimationController::PublicValue_t newSize;
 newSize.a = 256;
 newSize.b = 256;
 newSize.c = 0; // Unused
 newSize.d = 0; // Unused

 float totalAnimationTime = 3.0f;
 vgui::GetAnimationController()->RunAnimationCommand( m_pOverviewImage , "size", newSize, 0.0f, totalAnimationTime , vgui::AnimationController::INTERPOLATOR_LINEAR );


Footnotes

1. AnimationController::GetValue(ActiveAnimation_t& anim, Panel *panel, UtlSymId_t var) houses the according code.

2. You may also have noticed that CPanelAnimationVarAliasType is also a define, and takes an extra parameter: a type alias.

 // Only the first line
 #define CPanelAnimationVarAliasType( type, name, scriptname, defaultvalue, typealias ) \

This type alias is a string, and is used when converting the string-based default values into proper ones, and can also be used for custom processing. This processing is done in Panel::InitPropertyConverters(). This might be a good place to start if you want to extend this functionality to other variable types.