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.
58 lines
2.0 KiB
58 lines
2.0 KiB
@tool |
|
extends EditorPlugin |
|
|
|
const CONTAINER := CustomControlContainer.CONTAINER_SPATIAL_EDITOR_SIDE_RIGHT |
|
@onready var controls_scene := preload("terrain_editing_controls.tscn") |
|
@onready var controls : TerrainEditingControls = controls_scene.instantiate() |
|
|
|
var current_terrain : StaticBody3D |
|
|
|
func _handles(object: Object) -> bool: |
|
return is_terrain(object) |
|
|
|
func _make_visible(visible: bool) -> void: |
|
if visible: |
|
add_control_to_container(CONTAINER, controls) |
|
elif controls and controls.get_parent(): |
|
remove_control_from_container(CONTAINER, controls) |
|
if current_terrain: |
|
current_terrain.EditorUnfocus() |
|
current_terrain = null |
|
|
|
func _forward_3d_gui_input(camera: Camera3D, event: InputEvent) -> int: |
|
var position := Vector3.ZERO |
|
|
|
if event is InputEventMouse: |
|
var previous_terrain := current_terrain |
|
current_terrain = null |
|
|
|
var viewport := EditorInterface.get_editor_viewport_3d() |
|
if viewport.get_visible_rect().has_point(event.position): |
|
var from := camera.project_ray_origin(event.position) |
|
var to := from + camera.project_ray_normal(event.position) * camera.far |
|
|
|
var root := EditorInterface.get_edited_scene_root() as Node3D |
|
var space := root.get_world_3d().direct_space_state |
|
var query := PhysicsRayQueryParameters3D.create(from, to) |
|
|
|
var result := space.intersect_ray(query) |
|
var terrain := result.get("collider") as StaticBody3D |
|
if is_terrain(terrain): |
|
current_terrain = terrain |
|
position = result["position"] |
|
|
|
if previous_terrain and previous_terrain != current_terrain: |
|
previous_terrain.EditorUnfocus() |
|
|
|
if current_terrain: |
|
# Allow terrain access to editor undo redo functionality. |
|
current_terrain.EditorUndoRedo = get_undo_redo() |
|
if current_terrain.EditorInput(event, controls, position): |
|
return AFTER_GUI_INPUT_STOP |
|
|
|
return AFTER_GUI_INPUT_PASS |
|
|
|
func is_terrain(object: Object) -> bool: |
|
if not object: return false |
|
var script := object.get_script() as CSharpScript |
|
return script and script.resource_path.ends_with("/Terrain.cs")
|
|
|