2
0
Эх сурвалжийг харах

Merge pull request #43081 from KoBeWi/property_keeper

Keep property values when extending script
Rémi Verschelde 3 жил өмнө
parent
commit
74d92bf459

+ 8 - 0
editor/editor_properties.cpp

@@ -3603,7 +3603,10 @@ void EditorPropertyResource::_resource_selected(const Ref<Resource> &p_resource,
 void EditorPropertyResource::_resource_changed(const Ref<Resource> &p_resource) {
 	// Make visual script the correct type.
 	Ref<Script> s = p_resource;
+	bool is_script = false;
 	if (get_edited_object() && s.is_valid()) {
+		is_script = true;
+		InspectorDock::get_singleton()->store_script_properties(get_edited_object());
 		s->call("set_instance_base_type", get_edited_object()->get_class());
 	}
 
@@ -3629,6 +3632,11 @@ void EditorPropertyResource::_resource_changed(const Ref<Resource> &p_resource)
 	emit_changed(get_edited_property(), p_resource);
 	update_property();
 
+	if (is_script) {
+		// Restore properties if script was changed.
+		InspectorDock::get_singleton()->apply_script_properties(get_edited_object());
+	}
+
 	// Automatically suggest setting up the path for a ViewportTexture.
 	if (vpt.is_valid() && vpt->get_viewport_path_in_scene().is_empty()) {
 		if (!scene_tree) {

+ 28 - 0
editor/inspector_dock.cpp

@@ -453,6 +453,9 @@ void InspectorDock::_bind_methods() {
 
 	ClassDB::bind_method("edit_resource", &InspectorDock::edit_resource);
 
+	ClassDB::bind_method("store_script_properties", &InspectorDock::store_script_properties);
+	ClassDB::bind_method("apply_script_properties", &InspectorDock::apply_script_properties);
+
 	ADD_SIGNAL(MethodInfo("request_help"));
 }
 
@@ -565,6 +568,31 @@ EditorPropertyNameProcessor::Style InspectorDock::get_property_name_style() cons
 	return property_name_style;
 }
 
+void InspectorDock::store_script_properties(Object *p_object) {
+	ERR_FAIL_NULL(p_object);
+	ScriptInstance *si = p_object->get_script_instance();
+	if (!si) {
+		return;
+	}
+	si->get_property_state(stored_properties);
+}
+
+void InspectorDock::apply_script_properties(Object *p_object) {
+	ERR_FAIL_NULL(p_object);
+	ScriptInstance *si = p_object->get_script_instance();
+	if (!si) {
+		return;
+	}
+
+	for (const Pair<StringName, Variant> &E : stored_properties) {
+		Variant current;
+		if (si->get(E.first, current) && current.get_type() == E.second.get_type()) {
+			si->set(E.first, E.second);
+		}
+	}
+	stored_properties.clear();
+}
+
 InspectorDock::InspectorDock(EditorData &p_editor_data) {
 	singleton = this;
 	set_name("Inspector");

+ 4 - 0
editor/inspector_dock.h

@@ -100,6 +100,7 @@ class InspectorDock : public VBoxContainer {
 	Tree *unique_resources_list_tree = nullptr;
 
 	EditorPropertyNameProcessor::Style property_name_style;
+	List<Pair<StringName, Variant>> stored_properties;
 
 	void _prepare_menu();
 	void _menu_option(int p_option);
@@ -149,6 +150,9 @@ public:
 
 	EditorPropertyNameProcessor::Style get_property_name_style() const;
 
+	void store_script_properties(Object *p_object);
+	void apply_script_properties(Object *p_object);
+
 	InspectorDock(EditorData &p_editor_data);
 	~InspectorDock();
 };

+ 31 - 9
editor/scene_tree_dock.cpp

@@ -1952,17 +1952,36 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) {
 		return;
 	}
 
-	editor_data->get_undo_redo().create_action(TTR("Attach Script"));
-	for (Node *E : selected) {
-		Ref<Script> existing = E->get_script();
-		editor_data->get_undo_redo().add_do_method(E, "set_script", p_script);
-		editor_data->get_undo_redo().add_undo_method(E, "set_script", existing);
+	if (selected.size() == 1) {
+		Node *node = selected.front()->get();
+		Ref<Script> existing = node->get_script();
+
+		editor_data->get_undo_redo().create_action(TTR("Attach Script"));
+		editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "store_script_properties", node);
+		editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "store_script_properties", node);
+		editor_data->get_undo_redo().add_do_method(node, "set_script", p_script);
+		editor_data->get_undo_redo().add_undo_method(node, "set_script", existing);
+		editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "apply_script_properties", node);
+		editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", node);
 		editor_data->get_undo_redo().add_do_method(this, "_update_script_button");
 		editor_data->get_undo_redo().add_undo_method(this, "_update_script_button");
+		editor_data->get_undo_redo().commit_action();
+	} else {
+		editor_data->get_undo_redo().create_action(TTR("Attach Script"));
+		for (List<Node *>::Element *E = selected.front(); E; E = E->next()) {
+			Ref<Script> existing = E->get()->get_script();
+			editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "store_script_properties", E->get());
+			editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "store_script_properties", E->get());
+			editor_data->get_undo_redo().add_do_method(E->get(), "set_script", p_script);
+			editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing);
+			editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "apply_script_properties", E->get());
+			editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", E->get());
+			editor_data->get_undo_redo().add_do_method(this, "_update_script_button");
+			editor_data->get_undo_redo().add_undo_method(this, "_update_script_button");
+		}
+		editor_data->get_undo_redo().commit_action();
 	}
 
-	editor_data->get_undo_redo().commit_action();
-
 	_push_item(p_script.operator->());
 	_update_script_button();
 }
@@ -2586,11 +2605,14 @@ void SceneTreeDock::_files_dropped(Vector<String> p_files, NodePath p_to, int p_
 void SceneTreeDock::_script_dropped(String p_file, NodePath p_to) {
 	Ref<Script> scr = ResourceLoader::load(p_file);
 	ERR_FAIL_COND(!scr.is_valid());
-	Node *n = get_node(p_to);
-	if (n) {
+	if (Node *n = get_node(p_to)) {
 		editor_data->get_undo_redo().create_action(TTR("Attach Script"));
+		editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "store_script_properties", n);
+		editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "store_script_properties", n);
 		editor_data->get_undo_redo().add_do_method(n, "set_script", scr);
 		editor_data->get_undo_redo().add_undo_method(n, "set_script", n->get_script());
+		editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "apply_script_properties", n);
+		editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", n);
 		editor_data->get_undo_redo().add_do_method(this, "_update_script_button");
 		editor_data->get_undo_redo().add_undo_method(this, "_update_script_button");
 		editor_data->get_undo_redo().commit_action();