mirror of
https://github.com/godotengine/godot.git
synced 2025-01-22 10:32:54 -05:00
Add support for specifying whether to play the current scene or a specific scene in XR or regular mode
The functionality is only activated for the XR Editor, when a project has OpenXR enabled.
This commit is contained in:
parent
d79ff848fa
commit
4bc8918c19
5 changed files with 108 additions and 33 deletions
|
@ -46,7 +46,7 @@ String EditorRun::get_running_scene() const {
|
||||||
return running_scene;
|
return running_scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error EditorRun::run(const String &p_scene, const String &p_write_movie) {
|
Error EditorRun::run(const String &p_scene, const String &p_write_movie, const Vector<String> &p_run_args) {
|
||||||
List<String> args;
|
List<String> args;
|
||||||
|
|
||||||
for (const String &a : Main::get_forwardable_cli_arguments(Main::CLI_SCOPE_PROJECT)) {
|
for (const String &a : Main::get_forwardable_cli_arguments(Main::CLI_SCOPE_PROJECT)) {
|
||||||
|
@ -223,6 +223,12 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) {
|
||||||
args.push_back(p_scene);
|
args.push_back(p_scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!p_run_args.is_empty()) {
|
||||||
|
for (const String &run_arg : p_run_args) {
|
||||||
|
args.push_back(run_arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String exec = OS::get_singleton()->get_executable_path();
|
String exec = OS::get_singleton()->get_executable_path();
|
||||||
int instance_count = RunInstancesDialog::get_singleton()->get_instance_count();
|
int instance_count = RunInstancesDialog::get_singleton()->get_instance_count();
|
||||||
for (int i = 0; i < instance_count; i++) {
|
for (int i = 0; i < instance_count; i++) {
|
||||||
|
|
|
@ -55,7 +55,7 @@ public:
|
||||||
Status get_status() const;
|
Status get_status() const;
|
||||||
String get_running_scene() const;
|
String get_running_scene() const;
|
||||||
|
|
||||||
Error run(const String &p_scene, const String &p_write_movie = "");
|
Error run(const String &p_scene, const String &p_write_movie = "", const Vector<String> &p_run_args = Vector<String>());
|
||||||
void run_native_notify() { status = STATUS_PLAY; }
|
void run_native_notify() { status = STATUS_PLAY; }
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,13 @@
|
||||||
#include "editor/themes/editor_scale.h"
|
#include "editor/themes/editor_scale.h"
|
||||||
#include "scene/gui/box_container.h"
|
#include "scene/gui/box_container.h"
|
||||||
#include "scene/gui/button.h"
|
#include "scene/gui/button.h"
|
||||||
|
#include "scene/gui/menu_button.h"
|
||||||
#include "scene/gui/panel_container.h"
|
#include "scene/gui/panel_container.h"
|
||||||
|
|
||||||
|
#ifndef _3D_DISABLED
|
||||||
|
#include "servers/xr_server.h"
|
||||||
|
#endif // _3D_DISABLED
|
||||||
|
|
||||||
EditorRunBar *EditorRunBar::singleton = nullptr;
|
EditorRunBar *EditorRunBar::singleton = nullptr;
|
||||||
|
|
||||||
void EditorRunBar::_notification(int p_what) {
|
void EditorRunBar::_notification(int p_what) {
|
||||||
|
@ -162,33 +167,51 @@ void EditorRunBar::_write_movie_toggled(bool p_enabled) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorRunBar::_quick_run_selected(const String &p_file_path) {
|
Vector<String> EditorRunBar::_get_xr_mode_play_args(int p_xr_mode_id) {
|
||||||
play_custom_scene(p_file_path);
|
Vector<String> play_args;
|
||||||
|
if (p_xr_mode_id == 0) {
|
||||||
|
// Play in regular mode, xr mode off.
|
||||||
|
play_args.push_back("--xr-mode");
|
||||||
|
play_args.push_back("off");
|
||||||
|
} else if (p_xr_mode_id == 1) {
|
||||||
|
// Play in xr mode.
|
||||||
|
play_args.push_back("--xr-mode");
|
||||||
|
play_args.push_back("on");
|
||||||
|
}
|
||||||
|
return play_args;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorRunBar::_play_custom_pressed() {
|
void EditorRunBar::_quick_run_selected(const String &p_file_path, int p_id) {
|
||||||
|
play_custom_scene(p_file_path, _get_xr_mode_play_args(p_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorRunBar::_play_custom_pressed(int p_id) {
|
||||||
if (editor_run.get_status() == EditorRun::STATUS_STOP || current_mode != RunMode::RUN_CUSTOM) {
|
if (editor_run.get_status() == EditorRun::STATUS_STOP || current_mode != RunMode::RUN_CUSTOM) {
|
||||||
stop_playing();
|
stop_playing();
|
||||||
|
|
||||||
EditorNode::get_singleton()->get_quick_open_dialog()->popup_dialog({ "PackedScene" }, callable_mp(this, &EditorRunBar::_quick_run_selected));
|
EditorNode::get_singleton()->get_quick_open_dialog()->popup_dialog({ "PackedScene" }, callable_mp(this, &EditorRunBar::_quick_run_selected).bind(p_id));
|
||||||
play_custom_scene_button->set_pressed(false);
|
play_custom_scene_button->set_pressed(false);
|
||||||
} else {
|
} else {
|
||||||
|
Vector<String> play_args = _get_xr_mode_play_args(p_id);
|
||||||
|
|
||||||
// Reload if already running a custom scene.
|
// Reload if already running a custom scene.
|
||||||
String last_custom_scene = run_custom_filename; // This is necessary to have a copy of the string.
|
String last_custom_scene = run_custom_filename; // This is necessary to have a copy of the string.
|
||||||
play_custom_scene(last_custom_scene);
|
play_custom_scene(last_custom_scene, play_args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorRunBar::_play_current_pressed() {
|
void EditorRunBar::_play_current_pressed(int p_id) {
|
||||||
|
Vector<String> play_args = _get_xr_mode_play_args(p_id);
|
||||||
|
|
||||||
if (editor_run.get_status() == EditorRun::STATUS_STOP || current_mode != RunMode::RUN_CURRENT) {
|
if (editor_run.get_status() == EditorRun::STATUS_STOP || current_mode != RunMode::RUN_CURRENT) {
|
||||||
play_current_scene();
|
play_current_scene(false, play_args);
|
||||||
} else {
|
} else {
|
||||||
// Reload if already running the current scene.
|
// Reload if already running the current scene.
|
||||||
play_current_scene(true);
|
play_current_scene(true, play_args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorRunBar::_run_scene(const String &p_scene_path) {
|
void EditorRunBar::_run_scene(const String &p_scene_path, const Vector<String> &p_run_args) {
|
||||||
ERR_FAIL_COND_MSG(current_mode == RUN_CUSTOM && p_scene_path.is_empty(), "Attempting to run a custom scene with an empty path.");
|
ERR_FAIL_COND_MSG(current_mode == RUN_CUSTOM && p_scene_path.is_empty(), "Attempting to run a custom scene with an empty path.");
|
||||||
|
|
||||||
if (editor_run.get_status() == EditorRun::STATUS_PLAY) {
|
if (editor_run.get_status() == EditorRun::STATUS_PLAY) {
|
||||||
|
@ -273,7 +296,7 @@ void EditorRunBar::_run_scene(const String &p_scene_path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorDebuggerNode::get_singleton()->start();
|
EditorDebuggerNode::get_singleton()->start();
|
||||||
Error error = editor_run.run(run_filename, write_movie_file);
|
Error error = editor_run.run(run_filename, write_movie_file, p_run_args);
|
||||||
if (error != OK) {
|
if (error != OK) {
|
||||||
EditorDebuggerNode::get_singleton()->stop();
|
EditorDebuggerNode::get_singleton()->stop();
|
||||||
EditorNode::get_singleton()->show_accept(TTR("Could not start subprocess(es)!"), TTR("OK"));
|
EditorNode::get_singleton()->show_accept(TTR("Could not start subprocess(es)!"), TTR("OK"));
|
||||||
|
@ -340,7 +363,7 @@ void EditorRunBar::play_main_scene(bool p_from_native) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorRunBar::play_current_scene(bool p_reload) {
|
void EditorRunBar::play_current_scene(bool p_reload, const Vector<String> &p_play_args) {
|
||||||
if (Engine::get_singleton()->is_recovery_mode_hint()) {
|
if (Engine::get_singleton()->is_recovery_mode_hint()) {
|
||||||
EditorToaster::get_singleton()->popup_str(TTR("Recovery Mode is enabled. Disable it to run the project."), EditorToaster::SEVERITY_WARNING);
|
EditorToaster::get_singleton()->popup_str(TTR("Recovery Mode is enabled. Disable it to run the project."), EditorToaster::SEVERITY_WARNING);
|
||||||
return;
|
return;
|
||||||
|
@ -353,13 +376,13 @@ void EditorRunBar::play_current_scene(bool p_reload) {
|
||||||
|
|
||||||
current_mode = RunMode::RUN_CURRENT;
|
current_mode = RunMode::RUN_CURRENT;
|
||||||
if (p_reload) {
|
if (p_reload) {
|
||||||
_run_scene(last_current_scene);
|
_run_scene(last_current_scene, p_play_args);
|
||||||
} else {
|
} else {
|
||||||
_run_scene();
|
_run_scene("", p_play_args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorRunBar::play_custom_scene(const String &p_custom) {
|
void EditorRunBar::play_custom_scene(const String &p_custom, const Vector<String> &p_play_args) {
|
||||||
if (Engine::get_singleton()->is_recovery_mode_hint()) {
|
if (Engine::get_singleton()->is_recovery_mode_hint()) {
|
||||||
EditorToaster::get_singleton()->popup_str(TTR("Recovery Mode is enabled. Disable it to run the project."), EditorToaster::SEVERITY_WARNING);
|
EditorToaster::get_singleton()->popup_str(TTR("Recovery Mode is enabled. Disable it to run the project."), EditorToaster::SEVERITY_WARNING);
|
||||||
return;
|
return;
|
||||||
|
@ -368,7 +391,7 @@ void EditorRunBar::play_custom_scene(const String &p_custom) {
|
||||||
stop_playing();
|
stop_playing();
|
||||||
|
|
||||||
current_mode = RunMode::RUN_CUSTOM;
|
current_mode = RunMode::RUN_CUSTOM;
|
||||||
_run_scene(p_custom);
|
_run_scene(p_custom, p_play_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorRunBar::stop_playing() {
|
void EditorRunBar::stop_playing() {
|
||||||
|
@ -563,25 +586,55 @@ EditorRunBar::EditorRunBar() {
|
||||||
main_hbox->add_child(run_native);
|
main_hbox->add_child(run_native);
|
||||||
run_native->connect("native_run", callable_mp(this, &EditorRunBar::_run_native));
|
run_native->connect("native_run", callable_mp(this, &EditorRunBar::_run_native));
|
||||||
|
|
||||||
play_scene_button = memnew(Button);
|
bool add_play_xr_mode_options = false;
|
||||||
|
#ifndef _3D_DISABLED
|
||||||
|
if (OS::get_singleton()->has_feature("xr_editor") &&
|
||||||
|
(XRServer::get_xr_mode() == XRServer::XRMODE_ON ||
|
||||||
|
(XRServer::get_xr_mode() == XRServer::XRMODE_DEFAULT && GLOBAL_GET("xr/openxr/enabled")))) {
|
||||||
|
// If this is the XR editor and openxr is enabled, we turn the `play_scene_button` and
|
||||||
|
// `play_custom_scene_button` into MenuButtons to provide the option to start a scene in
|
||||||
|
// either regular mode or XR mode.
|
||||||
|
add_play_xr_mode_options = true;
|
||||||
|
}
|
||||||
|
#endif // _3D_DISABLED
|
||||||
|
|
||||||
|
if (add_play_xr_mode_options) {
|
||||||
|
MenuButton *menu_button = memnew(MenuButton);
|
||||||
|
PopupMenu *popup = menu_button->get_popup();
|
||||||
|
popup->add_item(TTRC("Run Scene in Regular Mode"), 0);
|
||||||
|
popup->add_item(TTRC("Run Scene in XR Mode"), 1);
|
||||||
|
popup->connect(SceneStringName(id_pressed), callable_mp(this, &EditorRunBar::_play_current_pressed));
|
||||||
|
play_scene_button = menu_button;
|
||||||
|
} else {
|
||||||
|
play_scene_button = memnew(Button);
|
||||||
|
play_scene_button->set_toggle_mode(true);
|
||||||
|
play_scene_button->connect(SceneStringName(pressed), callable_mp(this, &EditorRunBar::_play_current_pressed).bind(-1));
|
||||||
|
}
|
||||||
main_hbox->add_child(play_scene_button);
|
main_hbox->add_child(play_scene_button);
|
||||||
play_scene_button->set_theme_type_variation("RunBarButton");
|
play_scene_button->set_theme_type_variation("RunBarButton");
|
||||||
play_scene_button->set_toggle_mode(true);
|
|
||||||
play_scene_button->set_focus_mode(Control::FOCUS_NONE);
|
play_scene_button->set_focus_mode(Control::FOCUS_NONE);
|
||||||
play_scene_button->set_tooltip_text(TTRC("Run the currently edited scene."));
|
play_scene_button->set_tooltip_text(TTRC("Run the currently edited scene."));
|
||||||
play_scene_button->connect(SceneStringName(pressed), callable_mp(this, &EditorRunBar::_play_current_pressed));
|
|
||||||
|
|
||||||
ED_SHORTCUT_AND_COMMAND("editor/run_current_scene", TTRC("Run Current Scene"), Key::F6);
|
ED_SHORTCUT_AND_COMMAND("editor/run_current_scene", TTRC("Run Current Scene"), Key::F6);
|
||||||
ED_SHORTCUT_OVERRIDE("editor/run_current_scene", "macos", KeyModifierMask::META | Key::R);
|
ED_SHORTCUT_OVERRIDE("editor/run_current_scene", "macos", KeyModifierMask::META | Key::R);
|
||||||
play_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/run_current_scene"));
|
play_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/run_current_scene"));
|
||||||
|
|
||||||
play_custom_scene_button = memnew(Button);
|
if (add_play_xr_mode_options) {
|
||||||
|
MenuButton *menu_button = memnew(MenuButton);
|
||||||
|
PopupMenu *popup = menu_button->get_popup();
|
||||||
|
popup->add_item(TTRC("Run in Regular Mode"), 0);
|
||||||
|
popup->add_item(TTRC("Run in XR Mode"), 1);
|
||||||
|
popup->connect(SceneStringName(id_pressed), callable_mp(this, &EditorRunBar::_play_custom_pressed));
|
||||||
|
play_custom_scene_button = menu_button;
|
||||||
|
} else {
|
||||||
|
play_custom_scene_button = memnew(Button);
|
||||||
|
play_custom_scene_button->set_toggle_mode(true);
|
||||||
|
play_custom_scene_button->connect(SceneStringName(pressed), callable_mp(this, &EditorRunBar::_play_custom_pressed).bind(-1));
|
||||||
|
}
|
||||||
main_hbox->add_child(play_custom_scene_button);
|
main_hbox->add_child(play_custom_scene_button);
|
||||||
play_custom_scene_button->set_theme_type_variation("RunBarButton");
|
play_custom_scene_button->set_theme_type_variation("RunBarButton");
|
||||||
play_custom_scene_button->set_toggle_mode(true);
|
|
||||||
play_custom_scene_button->set_focus_mode(Control::FOCUS_NONE);
|
play_custom_scene_button->set_focus_mode(Control::FOCUS_NONE);
|
||||||
play_custom_scene_button->set_tooltip_text(TTRC("Run a specific scene."));
|
play_custom_scene_button->set_tooltip_text(TTRC("Run a specific scene."));
|
||||||
play_custom_scene_button->connect(SceneStringName(pressed), callable_mp(this, &EditorRunBar::_play_custom_pressed));
|
|
||||||
|
|
||||||
ED_SHORTCUT_AND_COMMAND("editor/run_specific_scene", TTRC("Run Specific Scene"), KeyModifierMask::CTRL | KeyModifierMask::SHIFT | Key::F5);
|
ED_SHORTCUT_AND_COMMAND("editor/run_specific_scene", TTRC("Run Specific Scene"), KeyModifierMask::CTRL | KeyModifierMask::SHIFT | Key::F5);
|
||||||
ED_SHORTCUT_OVERRIDE("editor/run_specific_scene", "macos", KeyModifierMask::META | KeyModifierMask::SHIFT | Key::R);
|
ED_SHORTCUT_OVERRIDE("editor/run_specific_scene", "macos", KeyModifierMask::META | KeyModifierMask::SHIFT | Key::R);
|
||||||
|
|
|
@ -84,16 +84,19 @@ class EditorRunBar : public MarginContainer {
|
||||||
void _update_play_buttons();
|
void _update_play_buttons();
|
||||||
|
|
||||||
void _write_movie_toggled(bool p_enabled);
|
void _write_movie_toggled(bool p_enabled);
|
||||||
void _quick_run_selected(const String &p_file_path);
|
void _quick_run_selected(const String &p_file_path, int p_id = -1);
|
||||||
|
|
||||||
void _play_current_pressed();
|
void _play_current_pressed(int p_id = -1);
|
||||||
void _play_custom_pressed();
|
void _play_custom_pressed(int p_id = -1);
|
||||||
|
|
||||||
void _run_scene(const String &p_scene_path = "");
|
void _run_scene(const String &p_scene_path = "", const Vector<String> &p_run_args = Vector<String>());
|
||||||
void _run_native(const Ref<EditorExportPreset> &p_preset);
|
void _run_native(const Ref<EditorExportPreset> &p_preset);
|
||||||
|
|
||||||
void _profiler_autostart_indicator_pressed();
|
void _profiler_autostart_indicator_pressed();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Vector<String> _get_xr_mode_play_args(int p_xr_mode_id);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
@ -105,8 +108,8 @@ public:
|
||||||
void recovery_mode_reload_project();
|
void recovery_mode_reload_project();
|
||||||
|
|
||||||
void play_main_scene(bool p_from_native = false);
|
void play_main_scene(bool p_from_native = false);
|
||||||
void play_current_scene(bool p_reload = false);
|
void play_current_scene(bool p_reload = false, const Vector<String> &p_play_args = Vector<String>());
|
||||||
void play_custom_scene(const String &p_custom);
|
void play_custom_scene(const String &p_custom, const Vector<String> &p_play_args = Vector<String>());
|
||||||
|
|
||||||
void stop_playing();
|
void stop_playing();
|
||||||
bool is_playing() const;
|
bool is_playing() const;
|
||||||
|
|
|
@ -43,6 +43,19 @@ open class GodotEditor : BaseGodotEditor() {
|
||||||
companion object {
|
companion object {
|
||||||
private val TAG = GodotEditor::class.java.simpleName
|
private val TAG = GodotEditor::class.java.simpleName
|
||||||
|
|
||||||
|
/** Default behavior, means we check project settings **/
|
||||||
|
private const val XR_MODE_DEFAULT = "default"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ignore project settings, OpenXR is disabled
|
||||||
|
*/
|
||||||
|
private const val XR_MODE_OFF = "off"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ignore project settings, OpenXR is enabled
|
||||||
|
*/
|
||||||
|
private const val XR_MODE_ON = "on"
|
||||||
|
|
||||||
internal val XR_RUN_GAME_INFO = EditorWindowInfo(GodotXRGame::class.java, 1667, ":GodotXRGame")
|
internal val XR_RUN_GAME_INFO = EditorWindowInfo(GodotXRGame::class.java, 1667, ":GodotXRGame")
|
||||||
|
|
||||||
internal val USE_SCENE_PERMISSIONS = listOf("com.oculus.permission.USE_SCENE", "horizonos.permission.USE_SCENE")
|
internal val USE_SCENE_PERMISSIONS = listOf("com.oculus.permission.USE_SCENE", "horizonos.permission.USE_SCENE")
|
||||||
|
@ -58,15 +71,14 @@ open class GodotEditor : BaseGodotEditor() {
|
||||||
|
|
||||||
override fun retrieveEditorWindowInfo(args: Array<String>): EditorWindowInfo {
|
override fun retrieveEditorWindowInfo(args: Array<String>): EditorWindowInfo {
|
||||||
var hasEditor = false
|
var hasEditor = false
|
||||||
var xrModeOn = false
|
var xrMode = XR_MODE_DEFAULT
|
||||||
|
|
||||||
var i = 0
|
var i = 0
|
||||||
while (i < args.size) {
|
while (i < args.size) {
|
||||||
when (args[i++]) {
|
when (args[i++]) {
|
||||||
EDITOR_ARG, EDITOR_ARG_SHORT, EDITOR_PROJECT_MANAGER_ARG, EDITOR_PROJECT_MANAGER_ARG_SHORT -> hasEditor = true
|
EDITOR_ARG, EDITOR_ARG_SHORT, EDITOR_PROJECT_MANAGER_ARG, EDITOR_PROJECT_MANAGER_ARG_SHORT -> hasEditor = true
|
||||||
XR_MODE_ARG -> {
|
XR_MODE_ARG -> {
|
||||||
val argValue = args[i++]
|
xrMode = args[i++]
|
||||||
xrModeOn = xrModeOn || ("on" == argValue)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +86,8 @@ open class GodotEditor : BaseGodotEditor() {
|
||||||
return if (hasEditor) {
|
return if (hasEditor) {
|
||||||
EDITOR_MAIN_INFO
|
EDITOR_MAIN_INFO
|
||||||
} else {
|
} else {
|
||||||
val openxrEnabled = GodotLib.getGlobal("xr/openxr/enabled").toBoolean()
|
val openxrEnabled = xrMode == XR_MODE_ON ||
|
||||||
|
(xrMode == XR_MODE_DEFAULT && GodotLib.getGlobal("xr/openxr/enabled").toBoolean())
|
||||||
if (openxrEnabled && isNativeXRDevice()) {
|
if (openxrEnabled && isNativeXRDevice()) {
|
||||||
XR_RUN_GAME_INFO
|
XR_RUN_GAME_INFO
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue