its coming together
This commit is contained in:
parent
3e0e23c28c
commit
1dadffeac4
11 changed files with 290 additions and 28 deletions
9
addons/Fantail-Interactive.top_down_camera/README.md
Normal file
9
addons/Fantail-Interactive.top_down_camera/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Top Down Camera
|
||||
This addon aims to provide a general purposed 2D camera for use in top-down games where the mouse is used to move the pan and zoom the camera. Ideal for strategy/simulation games
|
||||
|
||||
# Installation
|
||||
Install from the AssetLib or download archive from [Github releases](https://github.com/TimCoraxAudio/top_down_camera/releases) and extract `addons` directory to
|
||||
your project directory. Activate plugin in `Project` → `Project Settings` → `Plugins`
|
||||
|
||||
# Usage
|
||||
The node comes with (hopefully) plenty of built-in documentation. Please reach out if something is missing
|
||||
BIN
addons/Fantail-Interactive.top_down_camera/icon.png
Normal file
BIN
addons/Fantail-Interactive.top_down_camera/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 282 B |
34
addons/Fantail-Interactive.top_down_camera/icon.png.import
Normal file
34
addons/Fantail-Interactive.top_down_camera/icon.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://can5lubu4sv0o"
|
||||
path="res://.godot/imported/icon.png-51d88dd58ca6134a790389f43b8f17f3.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Fantail-Interactive.top_down_camera/icon.png"
|
||||
dest_files=["res://.godot/imported/icon.png-51d88dd58ca6134a790389f43b8f17f3.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
6
addons/Fantail-Interactive.top_down_camera/plugin.cfg
Normal file
6
addons/Fantail-Interactive.top_down_camera/plugin.cfg
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[plugin]
|
||||
name="Top Down Camera"
|
||||
description="A top-down 2D camera."
|
||||
author="Fantail Interactive"
|
||||
version="1.0"
|
||||
script="plugin.gd"
|
||||
9
addons/Fantail-Interactive.top_down_camera/plugin.gd
Normal file
9
addons/Fantail-Interactive.top_down_camera/plugin.gd
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
@tool
|
||||
extends EditorPlugin
|
||||
|
||||
|
||||
func _enter_tree():
|
||||
add_custom_type("TDCamera2D", "Camera2D", preload("td_camera_2d.gd"), null)
|
||||
|
||||
func _exit_tree():
|
||||
remove_custom_type("TDCamera2D")
|
||||
1
addons/Fantail-Interactive.top_down_camera/plugin.gd.uid
Normal file
1
addons/Fantail-Interactive.top_down_camera/plugin.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://c7paptfc4q1ft
|
||||
129
addons/Fantail-Interactive.top_down_camera/td_camera_2d.gd
Normal file
129
addons/Fantail-Interactive.top_down_camera/td_camera_2d.gd
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
extends Camera2D
|
||||
|
||||
## Scroll by using ui direction actions
|
||||
@export var keyboard_pan := true
|
||||
@export_group("Keyboard Settings")
|
||||
@export var move_left_action := "ui_left"
|
||||
@export var move_right_action := "ui_right"
|
||||
@export var move_up_action := "ui_up"
|
||||
@export var move_down_action := "ui_down"
|
||||
@export_group("")
|
||||
## Scroll by clicking right mouse button
|
||||
@export var mouse_drag_pan := true
|
||||
@export_group("Drag Settings")
|
||||
@export var drag_action := "drag_camera"
|
||||
@export_group("")
|
||||
## Scroll by moving mouse to the window edge
|
||||
@export var mouse_edge_pan := false
|
||||
@export var use_mouse_wheel := true
|
||||
@export_group("Zoom Settings")
|
||||
@export var min_zoom := 2.0
|
||||
@export var max_zoom := 0.5
|
||||
@export var zoom_speed := 0.1
|
||||
@export var zoom_in_action := "zoom_in"
|
||||
@export var zoom_out_action := "zoom_out"
|
||||
@export_group("")
|
||||
## How close should the mouse cursor be to the window edge (in pixels) before it starts
|
||||
## to pan the camera
|
||||
@export var edge_margin := 50
|
||||
## Camera speed (pixels/s)
|
||||
@export var pan_speed := 450
|
||||
|
||||
var prev_mouse_pos := Vector2.ZERO
|
||||
var dragging := false
|
||||
var move_left := false
|
||||
var move_right := false
|
||||
var move_up := false
|
||||
var move_down := false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
# We want the camera to move when we set position
|
||||
set_drag_horizontal_enabled(false)
|
||||
set_drag_vertical_enabled(false)
|
||||
|
||||
## Check for events detected by _unhandled_input and handle them
|
||||
func _process(delta: float) -> void:
|
||||
var motion := Vector2.ZERO
|
||||
if keyboard_pan:
|
||||
if move_left:
|
||||
motion += Vector2.LEFT
|
||||
if move_up:
|
||||
motion += Vector2.UP
|
||||
if move_right:
|
||||
motion += Vector2.RIGHT
|
||||
if move_down:
|
||||
motion += Vector2.DOWN
|
||||
|
||||
var mouse_pos := get_local_mouse_position()
|
||||
# Pan camera when the mouse has been moved to the window edges
|
||||
if mouse_edge_pan:
|
||||
var rect := get_viewport().get_visible_rect()
|
||||
var margin_rect = rect.grow(-edge_margin)
|
||||
margin_rect.position -= rect.size / 2
|
||||
if not margin_rect.has_point(mouse_pos):
|
||||
motion += margin_rect.get_center().direction_to(mouse_pos)
|
||||
|
||||
motion *= (pan_speed * (1 / zoom.x)) * delta / Engine.time_scale
|
||||
|
||||
if mouse_drag_pan and dragging:
|
||||
motion = prev_mouse_pos - mouse_pos
|
||||
|
||||
# Update position of the camera.
|
||||
position += motion
|
||||
clamp_position_to_limits()
|
||||
|
||||
if use_mouse_wheel:
|
||||
if Input.is_action_just_released(zoom_in_action):
|
||||
zoom += Vector2(zoom_speed, zoom_speed)
|
||||
if Input.is_action_just_released(zoom_out_action):
|
||||
zoom -= Vector2(zoom_speed, zoom_speed)
|
||||
|
||||
zoom.x = clampf(zoom.x, max_zoom, min_zoom)
|
||||
zoom.y = zoom.x
|
||||
|
||||
prev_mouse_pos = get_local_mouse_position()
|
||||
|
||||
## Check for any unhandled input events and take note of them
|
||||
##
|
||||
## We are taking press/release events and turning them into a flag of whether the
|
||||
## button is being held down
|
||||
##
|
||||
## NOTE: This is done here to ensure that we only consume input events if no other node does.
|
||||
## i.e. the camera won't move if the player is moving through menus
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
# TODO: Change to input action
|
||||
#print(event)
|
||||
if event.is_action(drag_action):
|
||||
dragging = event.is_pressed()
|
||||
return
|
||||
|
||||
# Transform a key change event into a "pressed" flag.
|
||||
# We do it this way because we're checking against an InputEvent, not Input
|
||||
if event.is_action_pressed(move_left_action):
|
||||
move_left = true
|
||||
if event.is_action_pressed(move_up_action):
|
||||
move_up = true
|
||||
if event.is_action_pressed(move_right_action):
|
||||
move_right = true
|
||||
if event.is_action_pressed(move_down_action):
|
||||
move_down = true
|
||||
if event.is_action_released(move_left_action):
|
||||
move_left = false
|
||||
if event.is_action_released(move_up_action):
|
||||
move_up = false
|
||||
if event.is_action_released(move_right_action):
|
||||
move_right = false
|
||||
if event.is_action_released(move_down_action):
|
||||
move_down = false
|
||||
|
||||
## Clamp the camera position to within the camera limits
|
||||
##
|
||||
## This fixes an issue where the camera can get "stuck" when in corners. I assume this
|
||||
## is due to stopping all movement when a limit is reached
|
||||
func clamp_position_to_limits() -> void:
|
||||
var view_size := get_viewport().get_visible_rect ().size * get_zoom().x
|
||||
var half_width := view_size.x / 2.0
|
||||
var half_height := view_size.y / 2.0
|
||||
position.x = clampf(position.x, limit_left + half_width, limit_right - half_width)
|
||||
position.y = clampf(position.y, limit_top + half_height, limit_bottom - half_height)
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://b1w10iwwhm5bj
|
||||
Loading…
Add table
Add a link
Reference in a new issue