Ru/VGUI Screen Creation: Difference between revisions
SlasteliNVL (talk | contribs) No edit summary  | 
				mNo edit summary  | 
				||
| (12 intermediate revisions by 5 users not shown) | |||
| Line 1: | Line 1: | ||
{{  | {{LanguageBar}}  | ||
}}  | |||
== Добавление VGUI экрана на карту ==  | == Добавление VGUI экрана на карту ==  | ||
{{  | {{Note|В этом разделе предполагается мод, в котором были исправлены экраны VGUI. (Смотрите [[#VGUI code modifications| Модификацию кода]] ниже) но в остальном это то же самое. Экраны VGUI "не" работают в HL2 или HL2: DM; они вылетают из игры. (CS:S не тестировался.)}}  | ||
# Создайте [[VGUI_Screen|vgui_screen]] энтити. Это точечная энтити.  | # Создайте [[VGUI_Screen|vgui_screen]] энтити. Это точечная энтити.  | ||
# Установите его '''Panel Name''' равным имени экрана, который должен отображаться. (Это не имя файла экрана.) Доступные экраны перечислены в   | # Установите его '''Panel Name''' равным имени экрана, который должен отображаться. (Это не имя файла экрана.) Доступные экраны перечислены в {{code|vgui_screens.txt}} (который должен находиться в каталоге {{code|scripts}}).  | ||
# Установите '''Ширина панели в мире''' и '''Высота панели в мире''' в соответствии с размером кисти. 64 в ширину на 32 в высоту было бы разумным начальным размером.  | # Установите '''Ширина панели в мире''' и '''Высота панели в мире''' в соответствии с размером кисти. 64 в ширину на 32 в высоту было бы разумным начальным размером.  | ||
# Скомпилируйте карту и протестируйте.  | # Скомпилируйте карту и протестируйте.  | ||
| Line 14: | Line 12: | ||
== Создание VGUI экрана ==  | == Создание VGUI экрана ==  | ||
Файлы экрана VGUI имеют расширение .res и должны быть помещены в   | Файлы экрана VGUI имеют расширение .res и должны быть помещены в {{code|scripts\screen\}}..  | ||
#   | # {{path|vgui_test_screen|res}} - хорошая отправная точка для создания файла экрана VGUI; его можно найти по пути {{path|...\hl2\scripts\screen}}.  | ||
# Материалы, используемые в файле .res, можно найти в   | # Материалы, используемые в файле .res, можно найти в {{file|hl2_misc_dir|vpk}}. Извлеките файлы материалов, упомянутые в файле .res, в {{path|...\materials\vgui\screen}}.  | ||
# Добавьте экран в   | # Добавьте экран в {{path|scripts\vgui_screens|txt}}. Если его не существует, создайте его. Вот пример, описывающий экран {{code|vgui_test_screen}} в {{path|scripts/screen/vgui_test_screen|res}}. Отрегулируйте его под свой экран.  | ||
  "VGUI_Screens"  |   "VGUI_Screens"  | ||
| Line 33: | Line 31: | ||
  }  |   }  | ||
Пример файла   | Пример файла {{file|vgui_screen|txt}} находиться в {{path|hl2/scripts}}.  | ||
==Модификации кода VGUI==  | ==Модификации кода VGUI==  | ||
| Line 41: | Line 37: | ||
Возникла проблема с экранами VGUI, получающими ввод. Если это не исправить, игра может вылетать, когда курсор указывает на экран.  | Возникла проблема с экранами VGUI, получающими ввод. Если это не исправить, игра может вылетать, когда курсор указывает на экран.  | ||
{{code|CInput ::ExtraMouseSample}} вызывает {{code|g_pClientMode-> CreateMove()}} без инициализации флагов кнопок, поэтому экран VGui обновляется с неверным вводом кнопки. Поскольку {{code|IN_VALIDVGUIINPUT}} устанавливается только из {{code|CInput ::CreateMove}}, экраны VGui обновляются только тогда, когда флажки кнопки действительны.  | |||
Есть два известных исправления. Оба они включают изменения кода и поэтому применимы только к модам.  | Есть два известных исправления. Оба они включают изменения кода и поэтому применимы только к модам.  | ||
| Line 49: | Line 45: | ||
     #define IN_VALIDVGUIINPUT		    (1 << 23) //bitflag for vgui fix  |      #define IN_VALIDVGUIINPUT		    (1 << 23) //bitflag for vgui fix  | ||
дальше, в '''src\cl_dll\in_main.cpp''' внутри метода   | дальше, в '''src\cl_dll\in_main.cpp''' внутри метода {{code|CInput::CreateMove ( ''...'' )}}  | ||
добавить:  | добавить:  | ||
     cmd->buttons |= IN_VALIDVGUIINPUT;  |      cmd->buttons |= IN_VALIDVGUIINPUT;  | ||
| Line 55: | Line 51: | ||
     g_pClientMode->CreateMove( input_sample_frametime, cmd );  |      g_pClientMode->CreateMove( input_sample_frametime, cmd );  | ||
дальше, в '''src\cl_dll\c_baseplayer.cpp''' внутри метода   | дальше, в '''src\cl_dll\c_baseplayer.cpp''' внутри метода {{code|C_BasePlayer::CreateMove( ''...'' )}}  | ||
добавить:  | добавить:  | ||
     if(pCmd->buttons & IN_VALIDVGUIINPUT)  |      if(pCmd->buttons & IN_VALIDVGUIINPUT)  | ||
прямо над:  | прямо над:  | ||
     DetermineVguiInputMode( pCmd );  |      DetermineVguiInputMode( pCmd );  | ||
''(So it only calls   | ''(So it only calls {{code|DetermineVguiInputMode}} if the buttons include our flag)''  | ||
и наконец, внутри метода   | и наконец, внутри метода {{code|C_BasePlayer::DetermineVguiInputMode( ''...'' )}}  | ||
изменить '''оба''' экземпляра:  | изменить '''оба''' экземпляра:  | ||
     pCmd->buttons &= ~(IN_ATTACK | IN_ATTACK2);  |      pCmd->buttons &= ~(IN_ATTACK | IN_ATTACK2);  | ||
| Line 68: | Line 64: | ||
     pCmd->buttons &= ~(IN_ATTACK | IN_ATTACK2 | IN_VALIDVGUIINPUT);  |      pCmd->buttons &= ~(IN_ATTACK | IN_ATTACK2 | IN_VALIDVGUIINPUT);  | ||
После обновления движка   | После обновления движка {{L|HL2}} в октябре, экраны VGUI аварийно завершают работу, когда вы наводите на них указатель мыши. Это связано с тем, что функция {{code|g_InputInternal}}, используемая в {{code|\src\cl_dll\c_vguiscreen.cpp}}, больше не работает. Попытка получить к нему доступ приводит к сбою. В качестве обходного пути оказалась полезной следующая функция {{code|C_VGuiScreen ::ClientThink(void)}}.:  | ||
  	// Convert (u,v) into (px,py)  |   	// Convert (u,v) into (px,py)  | ||
| Line 100: | Line 96: | ||
=== Фикс 2 ===  | === Фикс 2 ===  | ||
Альтернативным исправлением может быть добавление новой логической переменной в   | Альтернативным исправлением может быть добавление новой логической переменной в {{code|CUserCmd}}, например {{code|bButtonFlagsValid}}, которая может быть установлена в зависимости от допустимости флагов кнопки. Это позволит структуре внутренне хранить эту информацию в течение всего срока ее службы, освобождая при этом лишний бит кнопки.  | ||
== Скриншоты ==  | == Скриншоты ==  | ||
[[  | [[File:Granted_vgui.jpg|thumb|left|Экран VGUI, используемый в моде]]  | ||
[[  | [[File:Ekg_vgui.jpg|thumb|left|Экран VGUI, используемый для отображения динамически отображаемых данных ЭКГ]]  | ||
[[  | [[File:Bms mortar vgui.jpg|thumb|left|Экран VGUI, используемый для управления минометом в {{bms|3.1}}]]  | ||
{{ACategory|Programming}}  | |||
{{ACategory|Tutorials}}  | |||
{{ACategory|VGUI|S}}  | |||
Latest revision as of 08:37, 9 October 2025
Добавление VGUI экрана на карту
- Создайте vgui_screen энтити. Это точечная энтити.
 - Установите его Panel Name равным имени экрана, который должен отображаться. (Это не имя файла экрана.) Доступные экраны перечислены в 
vgui_screens.txt(который должен находиться в каталогеscripts). - Установите Ширина панели в мире и Высота панели в мире в соответствии с размером кисти. 64 в ширину на 32 в высоту было бы разумным начальным размером.
 - Скомпилируйте карту и протестируйте.
 
Положение объекта на карте отмечает нижний левый угол панели. Направление панели (нормаль к ее грани) задается углом объекта (Yaw)..
Создание VGUI экрана
Файлы экрана VGUI имеют расширение .res и должны быть помещены в scripts\screen\..

vgui_test_screen.res- хорошая отправная точка для создания файла экрана VGUI; его можно найти по пути
...\hl2\scripts\screen.- Материалы, используемые в файле .res, можно найти в 

hl2_misc_dir.vpk. Извлеките файлы материалов, упомянутые в файле .res, в
...\materials\vgui\screen. - Добавьте экран в 

scripts\vgui_screens.txt. Если его не существует, создайте его. Вот пример, описывающий экранvgui_test_screenв
scripts/screen/vgui_test_screen.res. Отрегулируйте его под свой экран. 
"VGUI_Screens"
{
   "vgui_test_screen"
   {
       // This is our example screen
       "type"		"vgui_screen_panel"
       "pixelswide"	480
       "pixelshigh"	240
       // This must be the file you created in step 1
       "resfile"	"scripts/screens/vgui_test_screen.res"
   } 
}
Пример файла ![]()
vgui_screen.txt находиться в ![]()
hl2/scripts.
Модификации кода VGUI
Возникла проблема с экранами VGUI, получающими ввод. Если это не исправить, игра может вылетать, когда курсор указывает на экран.
CInput ::ExtraMouseSample вызывает g_pClientMode-> CreateMove() без инициализации флагов кнопок, поэтому экран VGui обновляется с неверным вводом кнопки. Поскольку IN_VALIDVGUIINPUT устанавливается только из CInput ::CreateMove, экраны VGui обновляются только тогда, когда флажки кнопки действительны.
Есть два известных исправления. Оба они включают изменения кода и поэтому применимы только к модам.
Фикс 1
В src\game_shared\in_buttons.h, где определены другие флаги, добавить:
#define IN_VALIDVGUIINPUT (1 << 23) //bitflag for vgui fix
дальше, в src\cl_dll\in_main.cpp внутри метода CInput::CreateMove ( ... )
добавить:
cmd->buttons |= IN_VALIDVGUIINPUT;
прямо над:
g_pClientMode->CreateMove( input_sample_frametime, cmd );
дальше, в src\cl_dll\c_baseplayer.cpp внутри метода C_BasePlayer::CreateMove( ... )
добавить:
if(pCmd->buttons & IN_VALIDVGUIINPUT)
прямо над:
DetermineVguiInputMode( pCmd );
(So it only calls DetermineVguiInputMode if the buttons include our flag)
и наконец, внутри метода C_BasePlayer::DetermineVguiInputMode( ... )
изменить оба экземпляра:
pCmd->buttons &= ~(IN_ATTACK | IN_ATTACK2);
для чтения:
pCmd->buttons &= ~(IN_ATTACK | IN_ATTACK2 | IN_VALIDVGUIINPUT);
После обновления движка HL2 в октябре, экраны VGUI аварийно завершают работу, когда вы наводите на них указатель мыши. Это связано с тем, что функция g_InputInternal, используемая в \src\cl_dll\c_vguiscreen.cpp, больше не работает. Попытка получить к нему доступ приводит к сбою. В качестве обходного пути оказалась полезной следующая функция C_VGuiScreen ::ClientThink(void).:
	// Convert (u,v) into (px,py)
	int px = (int)(u * m_nPixelWidth + 0.5f);
	int py = (int)(v * m_nPixelHeight + 0.5f);
// START TEDDYS FIX
	for (int i = 0; i < pPanel->GetChildCount(); i++)
	{
		vgui::Button *child = dynamic_cast<vgui::Button*>(pPanel->GetChild(i));
		if ( child )
		{
			int x1, x2, y1, y2;
			child->GetBounds( x1, y1, x2, y2 );
			// Generate mouse input commands
			if ( (m_nButtonState & IN_ATTACK) )
			{
				if ( px >= x1 && px <= x1 + x2 && py >= y1 && py <= y1 + y2 )
					child->FireActionSignal();
			}
		}
	}
// FIN TEDDYS FIX
	if ( m_bLooseThinkNextFrame == true )
	{
		m_bLooseThinkNextFrame = false;
		SetNextClientThink( CLIENT_THINK_NEVER );
	}
Фикс 2
Альтернативным исправлением может быть добавление новой логической переменной в CUserCmd, например bButtonFlagsValid, которая может быть установлена в зависимости от допустимости флагов кнопки. Это позволит структуре внутренне хранить эту информацию в течение всего срока ее службы, освобождая при этом лишний бит кнопки.