godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.07k stars 69 forks source link

Allow editor plugins to change the 3D editor's camera zoom, pan, orbit and freelook mode #3287

Open me2beats opened 2 years ago

me2beats commented 2 years ago

Describe the project you are working on

"Go to surface at mouse" plugin that should change editor camera zoom, pan etc.

Describe the problem or limitation you are having in your project

It seems currently there's no way to set editor 3D camera zoom, pan etc with a plugin. I tried to change the camera position (using forward_spatial_gui_input()), but Godot sets it back to previous state.

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

An ability to set camera pan, zoom etc would solve the problem.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

The methods could be added to SpatialEditor or SpatialEditorViewport for example. I found _nav_pan, _nav_zoom, _nav_orbit, _nav_look methods in SpatialEditorViewport source code, they all take Vector2 maybe these methods could just be exposed?

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

I couldn't find one

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

Nope.

prominentdetail commented 2 years ago

+1

Calinou commented 2 years ago

@prominentdetail Please don't bump issues without contributing significant new information. Use the :+1: reaction button on the first post instead.

prominentdetail commented 2 years ago

Does it bump if there is a reply? I wasn't aware of that, sorry. Just trying to show my support is all

btw, I have tried to work on my own plugin, and I ran into the same issue. The camera doesn't appear to have ways to set the position/rotation, etc. I can get the Transform, but I don't see any way to set it.

func forward_spatial_gui_input(camera, event)

So it still appears to not have a way to accomplish this yet, unless someone else has figured a workaround?

tebz commented 2 years ago

I would like to have the orientation, position, is focused, and so on, of the editor cameras exposed to be able to write a EditorPlugin tool that enables the use of 3D-mouse, in my case 3DConnexion, or other joysticks to navigate the Editor 3D Viewport.

By making the logic in a EditorPlugin the application are not limited to a properterry application/device.

I have made a hacky EditorPlugin that does that, by finding the editor interface cameras and manipulate them directly. Works fine until you do "something's" in the viewport, then the position are restored as [me2beats] also experienced.

3DConnexion are supported in a lot of 3D applications like Blender, Maya, and a lot of other applications: https://3dconnexion.com/se/supported-software/

me2beats commented 1 year ago

A problem i just encountered is I make a 3D game and I really would like to have something like "camera location points/presets". I mean I make a level and I often move the editor camera from one point to another. I can have several such points, from where I want to see the level.

The problem is I can't make a tool to move/rotate the editor camera to these points. I can use "split viewport" option (the Godot feature that adds new viewports) but it requires more CPU/GPU resources and still not so handy I guess)

GustJc commented 2 months ago

I'd also like to have the ability to change the editor viewport camera. I was trying to replicate blender's 'alt+middle click' to 'focus the camera at point' feature in an EditorPlugin. I find this really useful to quickly recenter the zoom focus point after flying around in the freelook.

But its just not possible without exposing at least some of the editor navigation methods.

Ideally, I think somehow exposing the Node3DEditorViewport cursor variable would help. https://github.com/godotengine/godot/blob/03e6fbb010c3546593bd91a0dabc045a9882705a/editor/plugins/node_3d_editor_plugin.cpp#L3279-L3281

It has a cursor.pos, cursor.eye_pos, cursor.x_rot, cursor.y_rot and cursor.distance for zoom . And changing it, will automatically smoothly lerp towards the position due to _update_camera()

All of Godot's focus and camera change shortcuts seems to use this, and it would certainly solve my use-case.

Sievaxx commented 2 months ago

I wrote a really dirty proof of concept by adding a "get view cursor" and "update view cursor" func, and it works pretty well. I'm not sure how best to expose this though, as the Node3DEditorViewport class is not visible from docs, and i dunno where in the editor plugin / editor interface classes to put them to access it, so in my example below i bound the methods and use .call() directly on the node I can make this into a proper PR of sorts if someone on the team could help me find a good place to expose the functionality.

https://github.com/godotengine/godot-proposals/assets/21314708/1a69980b-8962-4c9e-8936-9e73dbb761dd

GustJc commented 1 month ago

I found a hacky way to move the camera thanks to the SpatialGardner addon. Here's how:

## Hacky way to change focus
var editor_selection:EditorSelection = get_editor_interface().get_selection()
var previous_selection := editor_selection.get_selected_nodes()

editor_selection.clear()
var new_node := Node3D.new()
new_node.name = "placeholder"
new_node.position = raycast['position']
get_tree().edited_scene_root.add_child(new_node)
editor_selection.add_node(new_node)

simulate_key(KEY_F)
call_deferred("restore_selection", previous_selection, new_node)

And you can simulate a key press with the Input.parse_input_event(event)

Basically, we add a temp node, and use the editor's own focus shortcut to move the camera, and then destroy that node and restore the selection.

I've made the plugin that I wanted, using raycasts and aabb's to find the mouse click position. If anyone wants to check it for reference: https://github.com/GustJc/godot_focus_camera_with_mouse


Although the hacky way worked for my use-case, there is still very little control, so this feature request is still very much needed. For example, and can make the camera zoom to waypoints, but you can't control its rotation.