22
33#include " editor/meta_project_setup_dialog.h"
44
5+ #include " raw_headers/start_xr.gd.gen.h"
6+ #include " raw_headers/xr_startup.tscn.gen.h"
7+
58#include < godot_cpp/classes/button.hpp>
69#include < godot_cpp/classes/center_container.hpp>
710#include < godot_cpp/classes/config_file.hpp>
811#include < godot_cpp/classes/control.hpp>
912#include < godot_cpp/classes/dir_access.hpp>
13+ #include < godot_cpp/classes/editor_file_system.hpp>
1014#include < godot_cpp/classes/editor_interface.hpp>
1115#include < godot_cpp/classes/editor_settings.hpp>
1216#include < godot_cpp/classes/file_access.hpp>
2832#include < godot_cpp/classes/window.hpp>
2933#include < godot_cpp/core/error_macros.hpp>
3034#include < godot_cpp/core/memory.hpp>
31-
3235#include < godot_cpp/variant/utility_functions.hpp>
3336
37+ static const char *XR_STARTUP_SCENE_PATH = " res://xr_startup.tscn" ;
38+ static const char *START_XR_SCRIPT_PATH = " res://start_xr.gd" ;
39+
3440void MetaProjectSetupDialog::_bind_methods () {
3541}
3642
@@ -40,14 +46,14 @@ void MetaProjectSetupDialog::_notification(uint32_t p_what) {
4046 recommendations.clear ();
4147
4248 // Required XR settings
43- recommendations.push_back ({ " OpenXR" , " xr/openxr/enabled" , true , " OpenXR must be enabled" , true , {} });
44- recommendations.push_back ({ " XR Shaders" , " xr/shaders/enabled" , true , " XR shaders must be compiled" , true , {} });
49+ recommendations.push_back ({ " OpenXR" , " xr/openxr/enabled" , true , " OpenXR must be enabled" , ALERT_TYPE_ERROR , {} });
50+ recommendations.push_back ({ " XR Shaders" , " xr/shaders/enabled" , true , " XR shaders must be compiled" , ALERT_TYPE_ERROR , {} });
4551
4652 // Other XR setting recommendations
47- recommendations.push_back ({ " MSAA" , " rendering/anti_aliasing/quality/msaa_3d" , 1 , " Recommended to set MSAA to 2x" , false , {} });
48- recommendations.push_back ({ " VRS Mode" , " rendering/vrs/mode" , 2 , " Recommended to set VRS mode to VR" , false , {} });
49- recommendations.push_back ({ " Foveation Level" , " xr/openxr/foveation_level" , 3 , " Recommended to set foveation level to high" , false , {} });
50- recommendations.push_back ({ " Dynamic Foveation" , " xr/openxr/foveation_dynamic" , true , " Recommended to enable dynamic foveation" , false , {} });
53+ recommendations.push_back ({ " MSAA" , " rendering/anti_aliasing/quality/msaa_3d" , 1 , " Recommended to set MSAA to 2x" , ALERT_TYPE_WARNING , {} });
54+ recommendations.push_back ({ " VRS Mode" , " rendering/vrs/mode" , 2 , " Recommended to set VRS mode to VR" , ALERT_TYPE_WARNING , {} });
55+ recommendations.push_back ({ " Foveation Level" , " xr/openxr/foveation_level" , 3 , " Recommended to set foveation level to high" , ALERT_TYPE_WARNING , {} });
56+ recommendations.push_back ({ " Dynamic Foveation" , " xr/openxr/foveation_dynamic" , true , " Recommended to enable dynamic foveation" , ALERT_TYPE_WARNING , {} });
5157
5258 ScrollContainer *scroll_container = memnew (ScrollContainer);
5359 scroll_container->set_anchors_and_offsets_preset (Control::PRESET_FULL_RECT);
@@ -70,28 +76,33 @@ void MetaProjectSetupDialog::_notification(uint32_t p_what) {
7076 }
7177 }
7278
73- vendors_plugin_entry = add_window_entry (" Vendors Plugin" , true );
79+ vendors_plugin_entry = add_window_entry (" Vendors Plugin" , ALERT_TYPE_ERROR );
7480 vendors_plugin_entry.description_label ->set_text (" Please install the Godot OpenXR Vendors Plugin" );
7581 vendors_plugin_entry.button ->set_text (" Open" );
7682 vendors_plugin_entry.button ->connect (" pressed" , callable_mp (this , &MetaProjectSetupDialog::open_asset_lib));
7783
78- export_preset_entry = add_window_entry (" Export" , true );
84+ export_preset_entry = add_window_entry (" Export" , ALERT_TYPE_ERROR );
7985 export_preset_entry.button ->set_text (" Open" );
8086 export_preset_entry.button ->connect (" pressed" , callable_mp (this , &MetaProjectSetupDialog::open_export_dialog));
8187
82- java_sdk_entry = add_window_entry (" Java SDK" , true );
88+ java_sdk_entry = add_window_entry (" Java SDK" , ALERT_TYPE_ERROR );
8389 java_sdk_entry.description_label ->set_text (" Please set a valid Java SDK path in Editor Settings" );
8490 java_sdk_entry.button ->set_text (" Info" );
8591 java_sdk_entry.button ->connect (" pressed" , callable_mp (this , &MetaProjectSetupDialog::open_android_export_doc));
8692
87- android_sdk_entry = add_window_entry (" Android SDK" , true );
93+ android_sdk_entry = add_window_entry (" Android SDK" , ALERT_TYPE_ERROR );
8894 android_sdk_entry.description_label ->set_text (" Please set a valid Android SDK path in Editor Settings" );
8995 android_sdk_entry.button ->set_text (" Info" );
9096 android_sdk_entry.button ->connect (" pressed" , callable_mp (this , &MetaProjectSetupDialog::open_android_export_doc));
9197
98+ main_scene_entry = add_window_entry (" Main Scene" , ALERT_TYPE_NONE);
99+ main_scene_entry.description_label ->set_text (" No main scene is set, add XR startup scene?" );
100+ main_scene_entry.button ->set_text (" Add" );
101+ main_scene_entry.button ->connect (" pressed" , callable_mp (this , &MetaProjectSetupDialog::add_xr_startup_scene));
102+
92103 int rec_index = 0 ;
93104 for (ProjectSettingRecommendation &recommendation : recommendations) {
94- recommendation.entry = add_window_entry (recommendation.setting_name , recommendation.is_high_priority );
105+ recommendation.entry = add_window_entry (recommendation.setting_name , recommendation.alert_type );
95106 recommendation.entry .button ->set_text (" Apply" );
96107 recommendation.entry .button ->connect (" pressed" , callable_mp (this , &MetaProjectSetupDialog::apply_recommendation).bind (rec_index));
97108 rec_index++;
@@ -108,7 +119,7 @@ void MetaProjectSetupDialog::_notification(uint32_t p_what) {
108119 }
109120}
110121
111- MetaProjectSetupDialog::WindowEntry MetaProjectSetupDialog::add_window_entry (const String &p_entry_name, bool p_is_high_priority ) {
122+ MetaProjectSetupDialog::WindowEntry MetaProjectSetupDialog::add_window_entry (const String &p_entry_name, AlertType p_alert_type ) {
112123 WindowEntry entry;
113124
114125 VBoxContainer *inner_vbox = memnew (VBoxContainer);
@@ -135,26 +146,33 @@ MetaProjectSetupDialog::WindowEntry MetaProjectSetupDialog::add_window_entry(con
135146 message_hbox->set_h_size_flags (Control::SIZE_EXPAND | Control::SIZE_SHRINK_BEGIN);
136147 hbox->add_child (message_hbox);
137148
138- Ref<Texture2D> icon_texture = p_is_high_priority ? error_texture : warning_texture;
139- if (icon_texture.is_valid ()) {
140- CenterContainer *icon_container = memnew (CenterContainer);
141- message_hbox->add_child (icon_container);
142- entry.icon_container = icon_container;
149+ CenterContainer *icon_container = memnew (CenterContainer);
150+ message_hbox->add_child (icon_container);
151+ entry.icon_container = icon_container;
143152
144- TextureRect *icon = memnew (TextureRect);
145- icon->set_texture (icon_texture);
146- icon->set_expand_mode (TextureRect::EXPAND_IGNORE_SIZE);
147- icon->set_custom_minimum_size (Vector2 (15.0 , 15.0 ));
148- icon_container->add_child (icon);
149- }
150-
151- Color font_color = p_is_high_priority ? error_color : warning_color;
153+ TextureRect *icon = memnew (TextureRect);
154+ icon->set_expand_mode (TextureRect::EXPAND_IGNORE_SIZE);
155+ icon_container->add_child (icon);
152156
153157 Label *description_label = memnew (Label);
154- description_label->add_theme_color_override (" font_color" , font_color);
155158 message_hbox->add_child (description_label);
156159 entry.description_label = description_label;
157160
161+ switch (p_alert_type) {
162+ case ALERT_TYPE_ERROR: {
163+ icon->set_texture (error_texture);
164+ icon->set_custom_minimum_size (Vector2 (15.0 , 15.0 ));
165+ description_label->add_theme_color_override (" font_color" , error_color);
166+ } break ;
167+ case ALERT_TYPE_WARNING: {
168+ icon->set_texture (warning_texture);
169+ icon->set_custom_minimum_size (Vector2 (15.0 , 15.0 ));
170+ description_label->add_theme_color_override (" font_color" , warning_color);
171+ } break ;
172+ case ALERT_TYPE_NONE: {
173+ } break ;
174+ }
175+
158176 Button *button = memnew (Button);
159177 hbox->add_child (button);
160178 entry.button = button;
@@ -251,18 +269,34 @@ void MetaProjectSetupDialog::open() {
251269 }
252270 }
253271
272+ // Check for main scene.
273+ if (project_settings->get (" application/run/main_scene" ) == String (" " )) {
274+ main_scene_entry.vbox ->show ();
275+ is_rec_list_empty = false ;
276+ } else {
277+ main_scene_entry.vbox ->hide ();
278+ }
279+
254280 // Check project setting recommendations.
255281 for (const ProjectSettingRecommendation &recommendation : recommendations) {
256282 if (project_settings->get (recommendation.setting_path ) == recommendation.recommended_value ) {
257283 recommendation.entry .vbox ->hide ();
258284 } else {
259285 recommendation.entry .vbox ->show ();
260286 recommendation.entry .button ->set_disabled (false );
261-
262- Color font_color = recommendation.is_high_priority ? error_color : warning_color;
263- recommendation.entry .description_label ->add_theme_color_override (" font_color" , font_color);
264287 recommendation.entry .description_label ->set_text (recommendation.description );
265288
289+ switch (recommendation.alert_type ) {
290+ case ALERT_TYPE_ERROR: {
291+ recommendation.entry .description_label ->add_theme_color_override (" font_color" , error_color);
292+ } break ;
293+ case ALERT_TYPE_WARNING: {
294+ recommendation.entry .description_label ->add_theme_color_override (" font_color" , warning_color);
295+ } break ;
296+ case ALERT_TYPE_NONE: {
297+ } break ;
298+ }
299+
266300 if (recommendation.entry .icon_container != nullptr ) {
267301 recommendation.entry .icon_container ->show ();
268302 }
@@ -400,6 +434,36 @@ void MetaProjectSetupDialog::open_android_export_doc() {
400434 os->shell_open (" https://docs.godotengine.org/en/stable/tutorials/export/exporting_for_android.html" );
401435}
402436
437+ void MetaProjectSetupDialog::add_xr_startup_scene () {
438+ ProjectSettings *project_settings = ProjectSettings::get_singleton ();
439+ ERR_FAIL_NULL (project_settings);
440+
441+ EditorInterface *editor_interface = EditorInterface::get_singleton ();
442+ ERR_FAIL_NULL (editor_interface);
443+
444+ if (FileAccess::file_exists (START_XR_SCRIPT_PATH)) {
445+ ERR_FAIL_EDMSG (" XR startup script start_xr.gd already exists" );
446+ }
447+
448+ if (FileAccess::file_exists (XR_STARTUP_SCENE_PATH)) {
449+ ERR_FAIL_EDMSG (" XR startup scene xr_startup.tscn already exists" );
450+ }
451+
452+ Ref<FileAccess> start_xr = FileAccess::open (START_XR_SCRIPT_PATH, FileAccess::WRITE);
453+ start_xr->store_string (String (start_xr_gd));
454+ start_xr->close ();
455+
456+ Ref<FileAccess> startup_scene = FileAccess::open (XR_STARTUP_SCENE_PATH, FileAccess::WRITE);
457+ startup_scene->store_string (String (xr_startup_tscn));
458+ startup_scene->close ();
459+
460+ project_settings->set_setting (" application/run/main_scene" , XR_STARTUP_SCENE_PATH);
461+ editor_interface->get_resource_filesystem ()->scan ();
462+ editor_interface->open_scene_from_path (XR_STARTUP_SCENE_PATH);
463+
464+ hide ();
465+ }
466+
403467void MetaProjectSetupDialog::apply_recommendation (int p_rec_index) {
404468 ProjectSettings *project_settings = ProjectSettings::get_singleton ();
405469 ERR_FAIL_NULL (project_settings);
@@ -414,7 +478,7 @@ void MetaProjectSetupDialog::apply_recommendation(int p_rec_index) {
414478 recommendation.entry .icon_container ->hide ();
415479 }
416480
417- if (recommendation.is_high_priority ) {
481+ if (recommendation.alert_type == ALERT_TYPE_ERROR ) {
418482 recommendation.entry .description_label ->set_text (" Restart editor to apply updated setting" );
419483 recommendation.entry .description_label ->add_theme_color_override (" font_color" , warning_color);
420484 } else {
0 commit comments