mirror of
https://github.com/godotengine/godot.git
synced 2025-11-01 14:11:15 +00:00
Improve "Snap Object to Floor" functionality
- Display an error message if no selected nodes could be snapped - Only register an undo/redo action if at least one node could be snapped - Increase the maximum snapping height to 20 - Increase the negative snapping limit to 0.2
This commit is contained in:
parent
cc9f2a2d8b
commit
78878fbc97
1 changed files with 39 additions and 14 deletions
|
|
@ -5176,7 +5176,7 @@ void SpatialEditor::snap_selected_nodes_to_floor() {
|
||||||
// We add a bit of margin to the from position to avoid it from snapping
|
// We add a bit of margin to the from position to avoid it from snapping
|
||||||
// when the spatial is already on a floor and there's another floor under
|
// when the spatial is already on a floor and there's another floor under
|
||||||
// it
|
// it
|
||||||
from = from + Vector3(0.0, 0.1, 0.0);
|
from = from + Vector3(0.0, 0.2, 0.0);
|
||||||
|
|
||||||
Dictionary d;
|
Dictionary d;
|
||||||
|
|
||||||
|
|
@ -5191,31 +5191,56 @@ void SpatialEditor::snap_selected_nodes_to_floor() {
|
||||||
|
|
||||||
Array keys = snap_data.keys();
|
Array keys = snap_data.keys();
|
||||||
|
|
||||||
if (keys.size()) {
|
// The maximum height an object can travel to be snapped
|
||||||
undo_redo->create_action(TTR("Snap Nodes To Floor"));
|
const float max_snap_height = 20.0;
|
||||||
|
|
||||||
|
// Will be set to `true` if at least one node from the selection was sucessfully snapped
|
||||||
|
bool snapped_to_floor = false;
|
||||||
|
|
||||||
|
if (keys.size()) {
|
||||||
|
// For snapping to be performed, there must be solid geometry under at least one of the selected nodes.
|
||||||
|
// We need to check this before snapping to register the undo/redo action only if needed.
|
||||||
for (int i = 0; i < keys.size(); i++) {
|
for (int i = 0; i < keys.size(); i++) {
|
||||||
Node *node = keys[i];
|
Node *node = keys[i];
|
||||||
Spatial *sp = Object::cast_to<Spatial>(node);
|
Spatial *sp = Object::cast_to<Spatial>(node);
|
||||||
|
|
||||||
Dictionary d = snap_data[node];
|
Dictionary d = snap_data[node];
|
||||||
Vector3 from = d["from"];
|
Vector3 from = d["from"];
|
||||||
Vector3 position_offset = d["position_offset"];
|
Vector3 to = from - Vector3(0.0, max_snap_height, 0.0);
|
||||||
|
|
||||||
Vector3 to = from - Vector3(0.0, 10.0, 0.0);
|
|
||||||
Set<RID> excluded = _get_physics_bodies_rid(sp);
|
Set<RID> excluded = _get_physics_bodies_rid(sp);
|
||||||
|
|
||||||
if (ss->intersect_ray(from, to, result, excluded)) {
|
if (ss->intersect_ray(from, to, result, excluded)) {
|
||||||
Transform new_transform = sp->get_global_transform();
|
snapped_to_floor = true;
|
||||||
new_transform.origin.y = result.position.y;
|
|
||||||
new_transform.origin = new_transform.origin - position_offset;
|
|
||||||
|
|
||||||
undo_redo->add_do_method(sp, "set_global_transform", new_transform);
|
|
||||||
undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_transform());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
undo_redo->commit_action();
|
if (snapped_to_floor) {
|
||||||
|
undo_redo->create_action(TTR("Snap Nodes To Floor"));
|
||||||
|
|
||||||
|
// Perform snapping if at least one node can be snapped
|
||||||
|
for (int i = 0; i < keys.size(); i++) {
|
||||||
|
Node *node = keys[i];
|
||||||
|
Spatial *sp = Object::cast_to<Spatial>(node);
|
||||||
|
Dictionary d = snap_data[node];
|
||||||
|
Vector3 from = d["from"];
|
||||||
|
Vector3 to = from - Vector3(0.0, max_snap_height, 0.0);
|
||||||
|
Set<RID> excluded = _get_physics_bodies_rid(sp);
|
||||||
|
|
||||||
|
if (ss->intersect_ray(from, to, result, excluded)) {
|
||||||
|
Vector3 position_offset = d["position_offset"];
|
||||||
|
Transform new_transform = sp->get_global_transform();
|
||||||
|
|
||||||
|
new_transform.origin.y = result.position.y;
|
||||||
|
new_transform.origin = new_transform.origin - position_offset;
|
||||||
|
|
||||||
|
undo_redo->add_do_method(sp, "set_global_transform", new_transform);
|
||||||
|
undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_transform());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
undo_redo->commit_action();
|
||||||
|
} else {
|
||||||
|
EditorNode::get_singleton()->show_warning(TTR("Couldn't find a solid floor to snap the selection to."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue