1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

Improve usability of Camera2D

This commit is contained in:
Lazy-Rabbit-2001
2025-03-12 09:57:31 +08:00
parent 0a30831bed
commit 5ca70d88a7
6 changed files with 378 additions and 5 deletions

View File

@@ -31,8 +31,61 @@
#include "camera_2d.h"
#include "core/config/project_settings.h"
#include "core/input/input.h"
#include "scene/main/viewport.h"
#ifdef TOOLS_ENABLED
Dictionary Camera2D::_edit_get_state() const {
Dictionary state = Node2D::_edit_get_state();
state["limit_rect"] = get_limit_rect();
return state;
}
void Camera2D::_edit_set_state(const Dictionary &p_state) {
if (p_state.has("limit_rect")) {
_set_limit_rect(p_state["limit_rect"]);
}
Node2D::_edit_set_state(p_state);
}
void Camera2D::_edit_set_position(const Point2 &p_position) {
if (_is_dragging_limit_rect()) {
Rect2 rect = get_limit_rect();
rect.position = p_position;
_set_limit_rect(rect);
} else {
Node2D::_edit_set_position(p_position);
}
}
Point2 Camera2D::_edit_get_position() const {
return _is_dragging_limit_rect() ? get_limit_rect().position : Node2D::_edit_get_position();
}
void Camera2D::_edit_set_rect(const Rect2 &p_rect) {
ERR_FAIL_COND(limit_enabled && !_edit_use_rect());
Rect2 rect = p_rect;
Vector2 scl = get_global_scale().abs();
rect.size *= scl;
rect.position = (rect.position + get_global_position()) * scl;
_set_limit_rect(rect);
}
#endif // TOOLS_ENABLED
#ifdef DEBUG_ENABLED
Rect2 Camera2D::_edit_get_rect() const {
Rect2 rect = get_limit_rect();
Vector2 scl = get_global_scale().abs();
rect.size /= scl;
rect.position = (rect.position - get_global_position()) / scl;
return rect;
}
bool Camera2D::_edit_use_rect() const {
return limit_enabled;
}
#endif // DEBUG_ENABLED
bool Camera2D::_is_editing_in_editor() const {
#ifdef TOOLS_ENABLED
return is_part_of_edited_scene();
@@ -75,6 +128,10 @@ void Camera2D::_update_scroll() {
}
#ifdef TOOLS_ENABLED
bool Camera2D::_is_dragging_limit_rect() const {
return _edit_use_rect() && Input::get_singleton()->is_key_pressed(Key::CTRL);
}
void Camera2D::_project_settings_changed() {
if (screen_drawing_enabled) {
queue_redraw();
@@ -169,7 +226,7 @@ Transform2D Camera2D::get_camera_transform() {
Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom_scale) : Point2());
Rect2 screen_rect(-screen_offset + camera_pos, screen_size * zoom_scale);
if (limit_smoothing_enabled) {
if (limit_enabled && limit_smoothing_enabled) {
if (screen_rect.position.x < limit[SIDE_LEFT]) {
camera_pos.x -= screen_rect.position.x - limit[SIDE_LEFT];
}
@@ -222,7 +279,7 @@ Transform2D Camera2D::get_camera_transform() {
Rect2 screen_rect(-screen_offset + ret_camera_pos, screen_size * zoom_scale);
if (!position_smoothing_enabled || !limit_smoothing_enabled) {
if (limit_enabled && (!position_smoothing_enabled || !limit_smoothing_enabled)) {
if (screen_rect.position.x < limit[SIDE_LEFT]) {
screen_rect.position.x = limit[SIDE_LEFT];
}
@@ -398,8 +455,7 @@ void Camera2D::_notification(int p_what) {
}
}
if (limit_drawing_enabled) {
Color limit_drawing_color(1, 1, 0.25, 0.63);
if (limit_enabled && limit_drawing_enabled) {
real_t limit_drawing_width = -1;
if (is_current()) {
limit_drawing_width = 3;
@@ -415,7 +471,7 @@ void Camera2D::_notification(int p_what) {
};
for (int i = 0; i < 4; i++) {
draw_line(limit_points[i], limit_points[(i + 1) % 4], limit_drawing_color, limit_drawing_width);
draw_line(limit_points[i], limit_points[(i + 1) % 4], Color(1, 1, 0.25, 0.63), limit_drawing_width);
}
}
@@ -484,6 +540,22 @@ bool Camera2D::is_ignoring_rotation() const {
return ignore_rotation;
}
void Camera2D::set_limit_enabled(bool p_limit_enabled) {
if (p_limit_enabled == limit_enabled) {
return;
}
limit_enabled = p_limit_enabled;
_update_scroll();
#ifdef TOOLS_ENABLED
emit_signal("_camera_limit_enabled_updated"); // Used for Camera2DEditorPlugin
#endif
notify_property_list_changed();
}
bool Camera2D::is_limit_enabled() const {
return limit_enabled;
}
void Camera2D::set_process_callback(Camera2DProcessCallback p_mode) {
if (process_callback == p_mode) {
return;
@@ -548,6 +620,18 @@ void Camera2D::_update_process_internal_for_smoothing() {
set_process_internal(enable);
}
void Camera2D::_set_limit_rect(const Rect2 &p_limit_rect) {
Point2 limit_rect_end = p_limit_rect.get_end();
set_limit(SIDE_LEFT, p_limit_rect.position.x);
set_limit(SIDE_TOP, p_limit_rect.position.y);
set_limit(SIDE_RIGHT, limit_rect_end.x);
set_limit(SIDE_BOTTOM, limit_rect_end.y);
}
Rect2 Camera2D::get_limit_rect() const {
return Rect2(limit[SIDE_LEFT], limit[SIDE_TOP], limit[SIDE_RIGHT] - limit[SIDE_LEFT], limit[SIDE_BOTTOM] - limit[SIDE_TOP]);
}
void Camera2D::make_current() {
ERR_FAIL_COND(!enabled || !is_inside_tree());
get_tree()->call_group(group_name, "_make_current", this);
@@ -817,6 +901,9 @@ bool Camera2D::is_margin_drawing_enabled() const {
}
void Camera2D::_validate_property(PropertyInfo &p_property) const {
if (!limit_enabled && (p_property.name == "limit_smoothed" || p_property.name == "limit_left" || p_property.name == "limit_top" || p_property.name == "limit_right" || p_property.name == "limit_bottom")) {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
}
if (!position_smoothing_enabled && p_property.name == "position_smoothing_speed") {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
}
@@ -847,6 +934,9 @@ void Camera2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_current"), &Camera2D::is_current);
ClassDB::bind_method(D_METHOD("_make_current"), &Camera2D::_make_current);
ClassDB::bind_method(D_METHOD("set_limit_enabled", "limit_enabled"), &Camera2D::set_limit_enabled);
ClassDB::bind_method(D_METHOD("is_limit_enabled"), &Camera2D::is_limit_enabled);
ClassDB::bind_method(D_METHOD("set_limit", "margin", "limit"), &Camera2D::set_limit);
ClassDB::bind_method(D_METHOD("get_limit", "margin"), &Camera2D::get_limit);
@@ -913,6 +1003,7 @@ void Camera2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_callback", "get_process_callback");
ADD_GROUP("Limit", "limit_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "limit_enabled"), "set_limit_enabled", "is_limit_enabled");
ADD_PROPERTYI(PropertyInfo(Variant::INT, "limit_left", PROPERTY_HINT_NONE, "suffix:px"), "set_limit", "get_limit", SIDE_LEFT);
ADD_PROPERTYI(PropertyInfo(Variant::INT, "limit_top", PROPERTY_HINT_NONE, "suffix:px"), "set_limit", "get_limit", SIDE_TOP);
ADD_PROPERTYI(PropertyInfo(Variant::INT, "limit_right", PROPERTY_HINT_NONE, "suffix:px"), "set_limit", "get_limit", SIDE_RIGHT);
@@ -961,4 +1052,8 @@ Camera2D::Camera2D() {
set_notify_transform(true);
set_hide_clip_children(true);
#ifdef TOOLS_ENABLED
add_user_signal(MethodInfo("_camera_limit_enabled_updated")); // Camera2DEditorPlugin listens to this
#endif
}