You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							49 lines
						
					
					
						
							2.0 KiB
						
					
					
				
			
		
		
	
	
							49 lines
						
					
					
						
							2.0 KiB
						
					
					
				| #if TOOLS | |
| [Tool] | |
| public partial class ReceiveInputInEditorPlugin | |
| 	: EditorPlugin | |
| { | |
| 	public override bool _Handles(GodotObject obj) | |
| 		=> true; | |
| 
 | |
| 	public override int _Forward3DGuiInput(Camera3D camera, InputEvent ev) | |
| 	{ | |
| 		var root = (Node3D)EditorInterface.Singleton.GetEditedSceneRoot(); | |
| 
 | |
| 		var viewport = root.GetViewport(); | |
| 		// Don't know about any negative effect of changing these and leaving them like that. | |
| 		viewport.GuiDisableInput    = false; // Re-enable input, required for `PushInput` to work at all. | |
| 		viewport.HandleInputLocally = true;  // Let sub-viewport handle its own input, makes `SetInputAsHandled` work as expected? | |
| 
 | |
| 		// This will propagate input events into the edited scene, | |
| 		// including regular, GUI, shortcut, unhandled key and unhandled. | |
| 		viewport.PushInput(ev); | |
| 
 | |
| 		// Enabling `PhysicsObjectPicking` causes `IsInputHandled()` to always | |
| 		// return true, and object picking isn't immediate anyway, so let's just | |
| 		// do it ourselves. This doesn't support touch input, though. | |
| 		if (!viewport.IsInputHandled() && (ev is InputEventMouse { Position: var mouse })) { | |
| 			// Ray is cast from the editor camera's view. | |
| 			var from = camera.ProjectRayOrigin(mouse); | |
| 			var to   = from + camera.ProjectRayNormal(mouse) * camera.Far; | |
| 
 | |
| 			// Actual collision is done in the edited scene though. | |
| 			var space = root.GetWorld3D().DirectSpaceState; | |
| 			var query = PhysicsRayQueryParameters3D.Create(from, to); | |
| 
 | |
| 			var result = space.IntersectRay(query); | |
| 			// The collider object isn't necessarily a `CollisionObject3D`. | |
| 			var collider = (GodotObject)result.GetValueOrDefault("collider"); | |
| 			if (collider is CollisionObject3D { Visible: true } obj) { | |
| 				var pos    = (Vector3)result["position"]; | |
| 				var normal = (Vector3)result["normal"]; | |
| 				var shape  = (int)result["shape"]; | |
| 				obj._InputEvent(camera, ev, pos, normal, shape); | |
| 			} | |
| 		} | |
| 
 | |
| 		// If any node calls `SetInputAsHandled()`, the event is not passed on to other editor gizmos / plugins. | |
| 		return viewport.IsInputHandled() ? (int)AfterGuiInput.Stop : (int)AfterGuiInput.Pass; | |
| 	} | |
| } | |
| #endif
 | |
| 
 |