123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- @tool
- extends Control
- var zoom_level := 0
- var is_panning = false
- var pan_center: Vector2
- var viewport_center: Vector2
- var view_mode_index := 0
- var editor_interface: EditorInterface # Set in node25d_plugin.gd
- var moving = false
- @onready var viewport_2d = $Viewport2D
- @onready var viewport_overlay = $ViewportOverlay
- @onready var view_mode_button_group: ButtonGroup = $"../TopBar/ViewModeButtons/45Degree".group
- @onready var zoom_label: Label = $"../TopBar/Zoom/ZoomPercent"
- @onready var gizmo_25d_scene = preload("res://addons/node25d-cs/main_screen/gizmo_25d.tscn")
- func _ready():
- # Give Godot a chance to fully load the scene. Should take two frames.
- await get_tree().process_frame
- await get_tree().process_frame
- var edited_scene_root = get_tree().edited_scene_root
- if not edited_scene_root:
- # Godot hasn't finished loading yet, so try loading the plugin again.
- editor_interface.set_plugin_enabled("node25d", false)
- editor_interface.set_plugin_enabled("node25d", true)
- return
- # Alright, we're loaded up. Now check if we have a valid world and assign it.
- var world_2d = edited_scene_root.get_viewport().world_2d
- if world_2d == get_viewport().world_2d:
- return # This is the MainScreen25D scene opened in the editor!
- viewport_2d.world_2d = world_2d
- func _process(delta):
- if not editor_interface: # Something's not right... bail!
- return
- # View mode polling.
- var view_mode_changed_this_frame = false
- var new_view_mode = view_mode_button_group.get_pressed_button().get_index()
- if view_mode_index != new_view_mode:
- view_mode_index = new_view_mode
- view_mode_changed_this_frame = true
- _recursive_change_view_mode(get_tree().edited_scene_root)
- # Zooming.
- if Input.is_mouse_button_pressed(MOUSE_BUTTON_WHEEL_UP):
- zoom_level += 1
- elif Input.is_mouse_button_pressed(MOUSE_BUTTON_WHEEL_DOWN):
- zoom_level -= 1
- var zoom = _get_zoom_amount()
- # SubViewport size.
- var size = get_global_rect().size
- viewport_2d.size = size
- # SubViewport transform.
- var viewport_trans = Transform2D.IDENTITY
- viewport_trans.x *= zoom
- viewport_trans.y *= zoom
- viewport_trans.origin = viewport_trans.basis_xform(viewport_center) + size / 2
- viewport_2d.canvas_transform = viewport_trans
- viewport_overlay.canvas_transform = viewport_trans
- # Delete unused gizmos.
- var selection = editor_interface.get_selection().get_selected_nodes()
- var overlay_children = viewport_overlay.get_children()
- for overlay_child in overlay_children:
- var contains = false
- for selected in selection:
- if selected == overlay_child.get("node25d") and not view_mode_changed_this_frame:
- contains = true
- if not contains:
- overlay_child.queue_free()
- # Add new gizmos.
- for selected in selection:
- if selected.has_method("Node25DReady"):
- var new = true
- for overlay_child in overlay_children:
- if selected == overlay_child.get("node25d"):
- new = false
- if new:
- var gizmo = gizmo_25d_scene.instantiate()
- viewport_overlay.add_child(gizmo)
- gizmo.set("node25d", selected)
- gizmo.call("Initialize")
- # This only accepts input when the mouse is inside of the 2.5D viewport.
- func _gui_input(event):
- if event is InputEventMouseButton:
- if event.is_pressed():
- if event.button_index == MOUSE_BUTTON_WHEEL_UP:
- zoom_level += 1
- accept_event()
- elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
- zoom_level -= 1
- accept_event()
- elif event.button_index == MOUSE_BUTTON_MIDDLE:
- is_panning = true
- pan_center = viewport_center - event.position
- accept_event()
- elif event.button_index == MOUSE_BUTTON_LEFT:
- var overlay_children = viewport_overlay.get_children()
- for overlay_child in overlay_children:
- overlay_child.set("wantsToMove", true)
- accept_event()
- elif event.button_index == MOUSE_BUTTON_MIDDLE:
- is_panning = false
- accept_event()
- elif event.button_index == MOUSE_BUTTON_LEFT:
- var overlay_children = viewport_overlay.get_children()
- for overlay_child in overlay_children:
- overlay_child.set("wantsToMove", false)
- accept_event()
- elif event is InputEventMouseMotion:
- if is_panning:
- viewport_center = pan_center + event.position
- accept_event()
- func _recursive_change_view_mode(current_node):
- if current_node.has_method("set_view_mode"):
- current_node.set_view_mode(view_mode_index) # GDScript.
- if current_node.has_method("SetViewMode"):
- current_node.call("SetViewMode", view_mode_index) # C#.
- for child in current_node.get_children():
- _recursive_change_view_mode(child)
- func _get_zoom_amount():
- var zoom_amount = pow(1.05476607648, zoom_level) # 13th root of 2.
- zoom_label.text = str(round(zoom_amount * 1000) / 10) + "%"
- return zoom_amount
- func _on_ZoomOut_pressed():
- zoom_level -= 1
- func _on_ZoomIn_pressed():
- zoom_level += 1
- func _on_ZoomReset_pressed():
- zoom_level = 0
|