|
@@ -31,6 +31,7 @@
|
|
|
#include "navigation_polygon_editor_plugin.h"
|
|
|
|
|
|
#include "editor/editor_node.h"
|
|
|
+#include "editor/editor_settings.h"
|
|
|
#include "editor/editor_undo_redo_manager.h"
|
|
|
#include "scene/2d/navigation_region_2d.h"
|
|
|
#include "scene/gui/dialogs.h"
|
|
@@ -50,6 +51,13 @@ Node2D *NavigationPolygonEditor::_get_node() const {
|
|
|
|
|
|
void NavigationPolygonEditor::_set_node(Node *p_polygon) {
|
|
|
node = Object::cast_to<NavigationRegion2D>(p_polygon);
|
|
|
+ if (node) {
|
|
|
+ Ref<NavigationPolygon> navpoly = node->get_navigation_polygon();
|
|
|
+ if (navpoly.is_valid() && navpoly->get_outline_count() > 0 && navpoly->get_polygon_count() == 0) {
|
|
|
+ // We have outlines drawn / added by the user but no polygons were created for this navmesh yet so let's bake once immediately.
|
|
|
+ _rebake_timer_timeout();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
int NavigationPolygonEditor::_get_polygon_count() const {
|
|
@@ -73,6 +81,10 @@ Variant NavigationPolygonEditor::_get_polygon(int p_idx) const {
|
|
|
void NavigationPolygonEditor::_set_polygon(int p_idx, const Variant &p_polygon) const {
|
|
|
Ref<NavigationPolygon> navpoly = _ensure_navpoly();
|
|
|
navpoly->set_outline(p_idx, p_polygon);
|
|
|
+
|
|
|
+ if (rebake_timer && _rebake_timer_delay >= 0.0) {
|
|
|
+ rebake_timer->start();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void NavigationPolygonEditor::_action_add_polygon(const Variant &p_polygon) {
|
|
@@ -80,6 +92,10 @@ void NavigationPolygonEditor::_action_add_polygon(const Variant &p_polygon) {
|
|
|
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
|
|
|
undo_redo->add_do_method(navpoly.ptr(), "add_outline", p_polygon);
|
|
|
undo_redo->add_undo_method(navpoly.ptr(), "remove_outline", navpoly->get_outline_count());
|
|
|
+
|
|
|
+ if (rebake_timer && _rebake_timer_delay >= 0.0) {
|
|
|
+ rebake_timer->start();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void NavigationPolygonEditor::_action_remove_polygon(int p_idx) {
|
|
@@ -87,6 +103,10 @@ void NavigationPolygonEditor::_action_remove_polygon(int p_idx) {
|
|
|
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
|
|
|
undo_redo->add_do_method(navpoly.ptr(), "remove_outline", p_idx);
|
|
|
undo_redo->add_undo_method(navpoly.ptr(), "add_outline_at_index", navpoly->get_outline(p_idx), p_idx);
|
|
|
+
|
|
|
+ if (rebake_timer && _rebake_timer_delay >= 0.0) {
|
|
|
+ rebake_timer->start();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void NavigationPolygonEditor::_action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) {
|
|
@@ -94,6 +114,10 @@ void NavigationPolygonEditor::_action_set_polygon(int p_idx, const Variant &p_pr
|
|
|
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
|
|
|
undo_redo->add_do_method(navpoly.ptr(), "set_outline", p_idx, p_polygon);
|
|
|
undo_redo->add_undo_method(navpoly.ptr(), "set_outline", p_idx, p_previous);
|
|
|
+
|
|
|
+ if (rebake_timer && _rebake_timer_delay >= 0.0) {
|
|
|
+ rebake_timer->start();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
bool NavigationPolygonEditor::_has_resource() const {
|
|
@@ -136,6 +160,15 @@ NavigationPolygonEditor::NavigationPolygonEditor() {
|
|
|
bake_info = memnew(Label);
|
|
|
bake_hbox->add_child(bake_info);
|
|
|
|
|
|
+ rebake_timer = memnew(Timer);
|
|
|
+ add_child(rebake_timer);
|
|
|
+ rebake_timer->set_one_shot(true);
|
|
|
+ _rebake_timer_delay = EDITOR_GET("editors/polygon_editor/auto_bake_delay");
|
|
|
+ if (_rebake_timer_delay >= 0.0) {
|
|
|
+ rebake_timer->set_wait_time(_rebake_timer_delay);
|
|
|
+ }
|
|
|
+ rebake_timer->connect("timeout", callable_mp(this, &NavigationPolygonEditor::_rebake_timer_timeout));
|
|
|
+
|
|
|
err_dialog = memnew(AcceptDialog);
|
|
|
add_child(err_dialog);
|
|
|
node = nullptr;
|
|
@@ -147,15 +180,26 @@ void NavigationPolygonEditor::_notification(int p_what) {
|
|
|
button_bake->set_icon(get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
|
|
|
button_reset->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
|
|
|
} break;
|
|
|
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
|
|
|
+ if (rebake_timer) {
|
|
|
+ _rebake_timer_delay = EDITOR_GET("editors/polygon_editor/auto_bake_delay");
|
|
|
+ if (_rebake_timer_delay >= 0.0) {
|
|
|
+ rebake_timer->set_wait_time(_rebake_timer_delay);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void NavigationPolygonEditor::_bake_pressed() {
|
|
|
+ if (rebake_timer) {
|
|
|
+ rebake_timer->stop();
|
|
|
+ }
|
|
|
button_bake->set_pressed(false);
|
|
|
|
|
|
ERR_FAIL_NULL(node);
|
|
|
Ref<NavigationPolygon> navigation_polygon = node->get_navigation_polygon();
|
|
|
- if (!navigation_polygon.is_valid()) {
|
|
|
+ if (navigation_polygon.is_null()) {
|
|
|
err_dialog->set_text(TTR("A NavigationPolygon resource must be set or created for this node to work."));
|
|
|
err_dialog->popup_centered();
|
|
|
return;
|
|
@@ -167,6 +211,9 @@ void NavigationPolygonEditor::_bake_pressed() {
|
|
|
}
|
|
|
|
|
|
void NavigationPolygonEditor::_clear_pressed() {
|
|
|
+ if (rebake_timer) {
|
|
|
+ rebake_timer->stop();
|
|
|
+ }
|
|
|
if (node) {
|
|
|
if (node->get_navigation_polygon().is_valid()) {
|
|
|
node->get_navigation_polygon()->clear();
|
|
@@ -193,6 +240,19 @@ void NavigationPolygonEditor::_update_polygon_editing_state() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void NavigationPolygonEditor::_rebake_timer_timeout() {
|
|
|
+ if (!node) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Ref<NavigationPolygon> navigation_polygon = node->get_navigation_polygon();
|
|
|
+ if (!navigation_polygon.is_valid()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ node->bake_navigation_polygon(true);
|
|
|
+ node->queue_redraw();
|
|
|
+}
|
|
|
+
|
|
|
NavigationPolygonEditorPlugin::NavigationPolygonEditorPlugin() :
|
|
|
AbstractPolygon2DEditorPlugin(memnew(NavigationPolygonEditor), "NavigationRegion2D") {
|
|
|
}
|