diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp
index 6723ca04b93..025253583b5 100644
--- a/scene/3d/skeleton_3d.cpp
+++ b/scene/3d/skeleton_3d.cpp
@@ -439,6 +439,17 @@ String Skeleton3D::get_bone_name(int p_bone) const {
 
 	return bones[p_bone].name;
 }
+void Skeleton3D::set_bone_name(int p_bone, const String &p_name) {
+	ERR_FAIL_INDEX(p_bone, bones.size());
+
+	for (int i = 0; i < bones.size(); i++) {
+		if (i != p_bone) {
+			ERR_FAIL_COND(bones[i].name == p_name);
+		}
+	}
+
+	bones.write[p_bone].name = p_name;
+}
 
 bool Skeleton3D::is_bone_parent_of(int p_bone, int p_parent_bone_id) const {
 	int parent_of_bone = get_bone_parent(p_bone);
@@ -869,6 +880,7 @@ void Skeleton3D::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("add_bone", "name"), &Skeleton3D::add_bone);
 	ClassDB::bind_method(D_METHOD("find_bone", "name"), &Skeleton3D::find_bone);
 	ClassDB::bind_method(D_METHOD("get_bone_name", "bone_idx"), &Skeleton3D::get_bone_name);
+	ClassDB::bind_method(D_METHOD("set_bone_name", "bone_idx", "name"), &Skeleton3D::set_bone_name);
 
 	ClassDB::bind_method(D_METHOD("get_bone_parent", "bone_idx"), &Skeleton3D::get_bone_parent);
 	ClassDB::bind_method(D_METHOD("set_bone_parent", "bone_idx", "parent_idx"), &Skeleton3D::set_bone_parent);
diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h
index a21891a32e9..44387d4e48d 100644
--- a/scene/3d/skeleton_3d.h
+++ b/scene/3d/skeleton_3d.h
@@ -157,6 +157,7 @@ public:
 	void add_bone(const String &p_name);
 	int find_bone(const String &p_name) const;
 	String get_bone_name(int p_bone) const;
+	void set_bone_name(int p_bone, const String &p_name);
 
 	bool is_bone_parent_of(int p_bone_id, int p_parent_bone_id) const;
 
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index e9606e03e6c..35b377abbed 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -1172,6 +1172,22 @@ StringName ArrayMesh::get_blend_shape_name(int p_index) const {
 	return blend_shapes[p_index];
 }
 
+void ArrayMesh::set_blend_shape_name(int p_index, const StringName &p_name) {
+	ERR_FAIL_INDEX(p_index, blend_shapes.size());
+
+	StringName name = p_name;
+	int found = blend_shapes.find(name);
+	if (found != -1 && found != p_index) {
+		int count = 2;
+		do {
+			name = String(p_name) + " " + itos(count);
+			count++;
+		} while (blend_shapes.find(name) != -1);
+	}
+
+	blend_shapes.write[p_index] = name;
+}
+
 void ArrayMesh::clear_blend_shapes() {
 	ERR_FAIL_COND_MSG(surfaces.size(), "Can't set shape key count if surfaces are already created.");
 
@@ -1508,6 +1524,7 @@ void ArrayMesh::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &ArrayMesh::add_blend_shape);
 	ClassDB::bind_method(D_METHOD("get_blend_shape_count"), &ArrayMesh::get_blend_shape_count);
 	ClassDB::bind_method(D_METHOD("get_blend_shape_name", "index"), &ArrayMesh::get_blend_shape_name);
+	ClassDB::bind_method(D_METHOD("set_blend_shape_name", "index", "name"), &ArrayMesh::set_blend_shape_name);
 	ClassDB::bind_method(D_METHOD("clear_blend_shapes"), &ArrayMesh::clear_blend_shapes);
 	ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &ArrayMesh::set_blend_shape_mode);
 	ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ArrayMesh::get_blend_shape_mode);
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index b0a30a56276..ac8932dbe8f 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -125,6 +125,7 @@ public:
 	virtual Ref<Material> surface_get_material(int p_idx) const = 0;
 	virtual int get_blend_shape_count() const = 0;
 	virtual StringName get_blend_shape_name(int p_index) const = 0;
+	virtual void set_blend_shape_name(int p_index, const StringName &p_name) = 0;
 
 	Vector<Face3> get_faces() const;
 	Ref<TriangleMesh> generate_triangle_mesh() const;
@@ -201,6 +202,7 @@ public:
 	void add_blend_shape(const StringName &p_name);
 	int get_blend_shape_count() const override;
 	StringName get_blend_shape_name(int p_index) const override;
+	void set_blend_shape_name(int p_index, const StringName &p_name) override;
 	void clear_blend_shapes();
 
 	void set_blend_shape_mode(BlendShapeMode p_mode);
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index 8d9c5f07b21..1436d069445 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -175,6 +175,9 @@ StringName PrimitiveMesh::get_blend_shape_name(int p_index) const {
 	return StringName();
 }
 
+void PrimitiveMesh::set_blend_shape_name(int p_index, const StringName &p_name) {
+}
+
 AABB PrimitiveMesh::get_aabb() const {
 	if (pending_request) {
 		_update();
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index f0ae611b5e3..d89db173565 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -79,6 +79,7 @@ public:
 	virtual Ref<Material> surface_get_material(int p_idx) const override;
 	virtual int get_blend_shape_count() const override;
 	virtual StringName get_blend_shape_name(int p_index) const override;
+	virtual void set_blend_shape_name(int p_index, const StringName &p_name) override;
 	virtual AABB get_aabb() const override;
 	virtual RID get_rid() const override;