Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add object snapping to the floor/vertices for the 3D editor viewport #755

Open
Jummit opened this issue Apr 26, 2020 · 31 comments · Fixed by godotengine/godot#96740
Open

Comments

@Jummit
Copy link

Jummit commented Apr 26, 2020

Describe the project you are working on:

3D exploration game.

Describe the problem or limitation you are having in your project:

Placing objects in 3d is hard, because moving them is always aligned to the camera or to one of the axis.

Describe the feature / enhancement and how it helps to overcome the problem or limitation:

Snapping similar to Blender would make dragging-and-dropping objects into the scene much quicker. It would also make moving objects easier.

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:

2020-04-26-163227_2646x1024_scrot
ezgif-4-6f95030788e2

More examples from #21006:
Snap example

This is already implemented for when you drag a model into the scene, but just for a very short range:
ezgif-4-887632b844d3

Seems like the distance is hardcoded to 10 here:
https://github.com/godotengine/godot/blob/56437cddeb3b4ff362ff23db27e8eab84c820959/editor/plugins/spatial_editor_plugin.cpp#L3184-L3186

This should be used here if snapping is enabled.

If this enhancement will not be used often, can it be worked around with a few lines of script?:

You can use the "Snap to floor" option, but it is slower and not real time.

Is there a reason why this should be core and not an add-on in the asset library?:

It improves an existing feature and complements the core 3D editing experience well.

Bugsquad edit (keywords for easier searching): vertex

@Calinou
Copy link
Member

Calinou commented Apr 26, 2020

Someone should check if the "Snap to Floor" functionality is fast enough to be used in real-time (or semi-realtime, e.g. every two frames).

@Jummit
Copy link
Author

Jummit commented Apr 27, 2020

Someone should check if the "Snap to Floor" functionality is fast enough to be used in real-time (or semi-realtime, e.g. every two frames).

I think the already implemented method SpatialEditorViewport::_get_instance_position which is used when dropping objects into the scene should work.

@Zireael07
Copy link

Related issue: godotengine/godot#21006

@Calinou Calinou changed the title Object snapping for the 3D editor viewport Add object snapping to the floor/vertices for the 3D editor viewport Oct 31, 2020
@GuyUnger
Copy link

Unreal does this very well with "surface snapping". Also allowing the object to point up at the normal of the surface:

UnrealEditor_dXzy3JF0Oa

ZKt9iEjfml.mp4

@jordanlis
Copy link

It would be usefull for 2D Too I think, given sometimes or some project does not use a tilemap editor.

@YuriSizov
Copy link
Contributor

It would be usefull for 2D Too I think, given sometimes or some project does not use a tilemap editor.

Floor in 2D is a very arbitrary concept. You can always use grid snapping, even without tilemaps.

@Calinou
Copy link
Member

Calinou commented Oct 12, 2021

Seems like the distance is hardcoded to 10 here:

For drag-and-drop, the issue is that we can't increase this distance too much. Otherwise, objects would appear far away when you drag and drop them without any collider behind.

We could have a way to dynamically adjust the drag-and-drop maximum distance while dragging (e.g. by using the mouse wheel). This is how 3D entity distance is set during dragging in Cube 2 editors, but this is difficult to discover for new users.

o.mp4

@YuriSizov
Copy link
Contributor

For drag-and-drop, the issue is that we can't increase this distance too much. Otherwise, objects would appear far away when you drag and drop them without any collider behind.

Be that as it may, I personally have never found our current defaults usable. Objects just spawn in the face of the camera. Dropping to the scene dock is more useful than dropping to a scene directly.

@Calinou
Copy link
Member

Calinou commented Oct 12, 2021

I guess we could increase this snapping distance to 20-30 units (and perhaps add an editor setting for it, or the aforementioned mouse wheel adjustment).

We can also increase the distance threshold for the Snap Object to Floor functionality while we're at it. I already did this a while ago, but it likely needs further adjustments to be more usable in large-scale scenes.

@trommlbomml
Copy link

I really can encourage this issue regarding vertex snapping: if I use assets which are blocks it is not easy at the moment to place them one to another. It is a very useful feature from unity I loved a lot and would improve a lot of prototyping and placement works.

As far as I understand this issue tackles vertex and surface snapping? Maybe it makes sense to have separate issues for each feature?

@Calinou
Copy link
Member

Calinou commented Mar 31, 2022

I really can encourage this issue regarding vertex snapping: if I use assets which are blocks it is not easy at the moment to place them one to another. It is a very useful feature from unity I loved a lot and would improve a lot of prototyping and placement works.

As far as I understand this issue tackles vertex and surface snapping? Maybe it makes sense to have separate issues for each feature?

Vertex snapping doesn't need to rely on colliders being present, while surface snapping arguably requires collision meshes to be present for it to work reliably. Surface snapping based on colliders is already implemented in Godot, however:

  • It can only be triggered when drag-and-dropping a scene resource from the FileSystem dock to the 3D viewport. There is no way to trigger it otherwise.
  • It lacks a way to rotate the object according to the surface normal, and a setting to adjust the surface offset (required for some objects to be flush to the surface).

@Flavelius
Copy link

Flavelius commented Jul 7, 2022

I'm used to toggling to topdown perspective (y up) in ortho projection to place objects. In godot this just places the dragged objects ~100m above the ground for me, so i don't think increasing the distance by this little will be of any help.
I also don't see the issue in increasing it; Have the default placement plane be at a low distance, but when intersecting a collider (at whatever distance) use the distance to that hitpoint. The only place where this might unrealistically fail is if the sky/far plane counted as collider.

@jgillich
Copy link

I wrote an addon for vertex snapping: https://github.com/jgillich/godot-snappy

The code is not ideal, but it could be used as a starting point for a in-engine implementation

@sci-comp
Copy link

I love all the ideas in here!

This makes me think of Octave 3D World Builder over in Unity. It's a very large package full of essential features for making 3D environments. It's not unique, there are other tools, like Prefab World Builder or Rider's new integration. Unity has a more bare-bones tool called ProBuilder as well.

jgillich's solution looks like a great addition to Godot to me,

Where would this snippet fit in Godot?

@Calinou
Copy link
Member

Calinou commented Oct 17, 2022

Where would this snippet fit in Godot?

The core Godot editor is C++-only – it can't integrate add-ons written in GDScript. The add-on's code would have to be ported to C++ before it can be integrated in core Godot.

@CardboardCarl
Copy link

CardboardCarl commented Oct 26, 2023

I wrote an addon for vertex snapping: https://github.com/jgillich/godot-snappy

The code is not ideal, but it could be used as a starting point for a in-engine implementation

I'll try to port this to C++ over the next week or two and get it working in the engine. Will update on progress!

Depending on how much time I have, I might also be able to make this work in 2D with Polygon2Ds, perhaps CollisionShape2Ds as well.

@CardboardCarl
Copy link

Finished up with a preliminary pass through the 3D editor class (i.e. adding button connections and an enabler variable). Almost finished translating jgillich's script, just trying to match up the GDScript functions with their internal counterparts.

Thinking of also changing the key action from press-and-hold to toggle, like the other snap functions. I'd like some input on that if possible.

I'm also trying to decide where to add in the functionality. Should I implement it as a new gizmo (seeing as the highlighted vertex will need to be drawn), or should I add it to the 3D editor class file with the other snap functions?
@Calinou tagging because you would probably know better than me.

@Calinou
Copy link
Member

Calinou commented Oct 30, 2023

I'm also trying to decide where to add in the functionality. Should I implement it as a new gizmo (seeing as the highlighted vertex will need to be drawn), or should I add it to the 3D editor class file with the other snap functions?

I'd put it in the 3D editor class, like the existing manipulation gizmo.

@CardboardCarl
Copy link

Giving an update: I had to shelve my work on this for a little while due to some unforseen circumstances with my schedule. Going to be starting back this week.

@Ury18
Copy link

Ury18 commented Feb 1, 2024

This is a must have feature. When using modular meshes to build, for example, scenarios It's almost impossible to make things fit together as desired. The only workaround is changing de Translate Snap value to make it lower so the grid snap is more precise but it's still far from ideal and even in some cases doesn't quite work.

@CardboardCarl
Copy link

Another update. A sad one, unfortunately. I accidentally force-pushed the main Godot branch and overwrote all of my changes, so I'm going to have to start from scratch... The good news is that I have a better grasp of the editor code now, so it shouldn't take very long to catch back up!

I think I made a mistake by skipping porting the Snappy module to GDNative and instead directly integrating a translation of it into the editor. It gave me no working base to reference and likely slowed my progress down to a halt. Going to learn from my mistakes and start by actually porting Snappy to GDNative first.

@Calinou
Copy link
Member

Calinou commented Feb 4, 2024

Another update. A sad one, unfortunately. I accidentally force-pushed the main Godot branch and overwrote all of my changes, so I'm going to have to start from scratch... The good news is that I have a better grasp of the editor code now, so it shouldn't take very long to catch back up!

If you have a local copy of the repository before you've done the force push, you might be able to get the previous state of your code using git reflog and git checkout <reflog commit hash>. The reflog is essentially a local history that stores all commits for a certain duration even if they've been reset or force-pushed.

@CardboardCarl
Copy link

If you have a local copy of the repository before you've done the force push, you might be able to get the previous state of your code using git reflog and git checkout <reflog commit hash>. The reflog is essentially a local history that stores all commits for a certain duration even if they've been reset or force-pushed.

Unfortunately it looks like my reflog also got wiped... oh well. Probably better off starting from scratch anyways! 😅

@Reonu

This comment was marked as off-topic.

@Calinou
Copy link
Member

Calinou commented Feb 5, 2024

@Reonu Please don't bump issues without contributing significant new information. Use the 👍 reaction button on the first post instead.

@warent
Copy link

warent commented May 7, 2024

Hey folks, FYI someone just created a plugin for this, and it works great: https://github.com/mharitsnf/ExtraSnaps Would be amazing to get this built-in natively!

@ChildLearningClub
Copy link

ChildLearningClub commented Jun 21, 2024

The Mirror's implementation of snapping seems to work well. Can their code be added back into the Godot Engine?

godotengine/godot@master...the-mirror-gdp:godot:themirror

2024-06-21.11-42-20.mp4

@Calinou
Copy link
Member

Calinou commented Aug 5, 2024

Note that it might be worth considering a floating pivot toggle as well to go with vertex snapping, as described in #10359.

@jgillich
Copy link

PR looks fantastic, but unless I'm mistaken, it doesn't add vertex snapping. I think this needs to be reopened.

@Repiteo
Copy link

Repiteo commented Oct 14, 2024

Oop, the issue auto-closed when merging, my b

@Repiteo Repiteo reopened this Oct 14, 2024
@Repiteo
Copy link

Repiteo commented Oct 14, 2024

REALLY wish there was a "partially closed" equivalent for issues, because that PR does handle floor-snapping

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.