mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-12-24 12:47:12 +01:00
Ported: Rework how current Camera2D is determined
7e2a8afb57
- KoBeWi and Fix Camera2D crashes724d6581d6
- KoBeWi From godot4. Also fixed issues with active Camera2D switching.
This commit is contained in:
parent
c54ad5594b
commit
15bf4aefd0
@ -54,6 +54,18 @@
|
||||
Returns the specified camera limit. See also [member limit_bottom], [member limit_top], [member limit_left], and [member limit_right].
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_current" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<description>
|
||||
Returns [code]true[/code] if this [Camera2D] is the active camera (see [method Viewport.get_camera_2d]).
|
||||
</description>
|
||||
</method>
|
||||
<method name="make_current">
|
||||
<return type="void" />
|
||||
<description>
|
||||
Forces this [Camera2D] to become the current active one. [member enabled] must be [code]true[/code].
|
||||
</description>
|
||||
</method>
|
||||
<method name="reset_smoothing">
|
||||
<return type="void" />
|
||||
<description>
|
||||
@ -82,9 +94,6 @@
|
||||
<member name="anchor_mode" type="int" setter="set_anchor_mode" getter="get_anchor_mode" enum="Camera2D.AnchorMode" default="1">
|
||||
The Camera2D's anchor point. See [enum AnchorMode] constants.
|
||||
</member>
|
||||
<member name="current" type="bool" setter="set_current" getter="is_current" default="false">
|
||||
If [code]true[/code], the camera is the active camera for the current scene. Only one camera can be current, so setting a different camera [code]current[/code] will disable this one.
|
||||
</member>
|
||||
<member name="custom_viewport" type="Node" setter="set_custom_viewport" getter="get_custom_viewport">
|
||||
The custom [Viewport] node attached to the [Camera2D]. If [code]null[/code] or not a [Viewport], uses the default viewport instead.
|
||||
</member>
|
||||
@ -106,6 +115,10 @@
|
||||
<member name="drag_margin_v_enabled" type="bool" setter="set_v_drag_enabled" getter="is_v_drag_enabled" default="false">
|
||||
If [code]true[/code], the camera only moves when reaching the vertical drag margins. If [code]false[/code], the camera moves vertically regardless of margins.
|
||||
</member>
|
||||
<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true">
|
||||
Controls whether the camera can be active or not. If [code]true[/code], the [Camera2D] will become the main camera when it enters the scene tree and there is no active camera currently (see [method Viewport.get_camera_2d]).
|
||||
When the camera is currently active and [member enabled] is set to [code]false[/code], the next enabled [Camera2D] in the scene tree will become active.
|
||||
</member>
|
||||
<member name="editor_draw_drag_margin" type="bool" setter="set_margin_drawing_enabled" getter="is_margin_drawing_enabled" default="false">
|
||||
If [code]true[/code], draws the camera's drag margin rectangle in the editor.
|
||||
</member>
|
||||
|
@ -50,7 +50,7 @@ void Camera2D::_update_scroll() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (current) {
|
||||
if (is_current()) {
|
||||
ERR_FAIL_COND(custom_viewport && !ObjectDB::get_instance(custom_viewport_id));
|
||||
|
||||
Transform2D xform = get_camera_transform();
|
||||
@ -252,32 +252,25 @@ void Camera2D::_notification(int p_what) {
|
||||
_setup_viewport();
|
||||
_update_process_mode();
|
||||
|
||||
if (is_current()) {
|
||||
// if a camera enters the tree that is set to current,
|
||||
// it should take over as the current camera, and mark
|
||||
// all other cameras as non current
|
||||
if (viewport->get_camera_2d() == NULL) {
|
||||
first = true;
|
||||
viewport->_camera_2d_set(this);
|
||||
} else {
|
||||
first = false;
|
||||
if (!Engine::get_singleton()->is_editor_hint() && enabled && !viewport->get_camera_2d()) {
|
||||
make_current();
|
||||
}
|
||||
}
|
||||
|
||||
first = true;
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
const bool viewport_valid = !custom_viewport || ObjectDB::get_instance(custom_viewport_id);
|
||||
remove_from_group(group_name);
|
||||
remove_from_group(canvas_group_name);
|
||||
|
||||
if (is_current()) {
|
||||
if (viewport && viewport_valid) {
|
||||
viewport->set_canvas_transform(Transform2D());
|
||||
clear_current();
|
||||
}
|
||||
}
|
||||
|
||||
const bool viewport_valid = !custom_viewport || ObjectDB::get_instance(custom_viewport_id);
|
||||
if (viewport && viewport_valid) {
|
||||
viewport->disconnect("size_changed", this, "_update_scroll");
|
||||
}
|
||||
remove_from_group(group_name);
|
||||
remove_from_group(canvas_group_name);
|
||||
|
||||
viewport = nullptr;
|
||||
|
||||
} break;
|
||||
@ -404,11 +397,26 @@ Camera2D::Camera2DProcessMode Camera2D::get_process_mode() const {
|
||||
return process_mode;
|
||||
}
|
||||
|
||||
void Camera2D::set_enabled(bool p_enabled) {
|
||||
enabled = p_enabled;
|
||||
|
||||
if (enabled && is_inside_tree() && !viewport->get_camera_2d()) {
|
||||
make_current();
|
||||
} else if (!enabled && is_current()) {
|
||||
clear_current();
|
||||
}
|
||||
}
|
||||
|
||||
bool Camera2D::is_enabled() const {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void Camera2D::_make_current(Object *p_which) {
|
||||
if (p_which == this) {
|
||||
if (is_inside_tree()) {
|
||||
get_viewport()->_camera_2d_set(this);
|
||||
update();
|
||||
_update_scroll();
|
||||
}
|
||||
} else {
|
||||
if (is_inside_tree()) {
|
||||
@ -420,42 +428,26 @@ void Camera2D::_make_current(Object *p_which) {
|
||||
}
|
||||
}
|
||||
|
||||
void Camera2D::set_current(bool p_current) {
|
||||
current = p_current;
|
||||
|
||||
if (is_inside_tree()) {
|
||||
if (p_current) {
|
||||
make_current();
|
||||
} else {
|
||||
if (get_viewport()->get_camera_2d() == this) {
|
||||
clear_current();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Camera2D::is_current() const {
|
||||
if (is_inside_tree()) {
|
||||
return (get_viewport()->get_camera_2d() == this);
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
void Camera2D::make_current() {
|
||||
if (is_inside_tree()) {
|
||||
get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, group_name, "_make_current", this);
|
||||
}
|
||||
|
||||
ERR_FAIL_COND(!enabled || !is_inside_tree());
|
||||
get_tree()->call_group(group_name, "_make_current", this);
|
||||
_update_scroll();
|
||||
}
|
||||
|
||||
void Camera2D::clear_current() {
|
||||
if (is_inside_tree()) {
|
||||
get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, group_name, "_make_current", (Object *)nullptr);
|
||||
ERR_FAIL_COND(!is_current());
|
||||
if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) {
|
||||
viewport->assign_next_enabled_camera_2d(group_name);
|
||||
}
|
||||
}
|
||||
|
||||
bool Camera2D::is_current() const {
|
||||
if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) {
|
||||
return viewport->get_camera_2d() == this;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Camera2D::set_limit(Margin p_margin, int p_limit) {
|
||||
ERR_FAIL_INDEX((int)p_margin, 4);
|
||||
limit[p_margin] = p_limit;
|
||||
@ -676,7 +668,10 @@ void Camera2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Camera2D::set_process_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_process_mode"), &Camera2D::get_process_mode);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_current", "current"), &Camera2D::set_current);
|
||||
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &Camera2D::set_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_enabled"), &Camera2D::is_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("make_current"), &Camera2D::make_current);
|
||||
ClassDB::bind_method(D_METHOD("is_current"), &Camera2D::is_current);
|
||||
ClassDB::bind_method(D_METHOD("_make_current"), &Camera2D::_make_current);
|
||||
|
||||
@ -732,7 +727,7 @@ void Camera2D::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_mode", PROPERTY_HINT_ENUM, "Fixed TopLeft,Drag Center"), "set_anchor_mode", "get_anchor_mode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotating"), "set_rotating", "is_rotating");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "zoom", PROPERTY_HINT_LINK), "set_zoom", "get_zoom");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", 0), "set_custom_viewport", "get_custom_viewport");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode");
|
||||
@ -776,7 +771,7 @@ void Camera2D::_bind_methods() {
|
||||
Camera2D::Camera2D() {
|
||||
anchor_mode = ANCHOR_MODE_DRAG_CENTER;
|
||||
rotating = false;
|
||||
current = false;
|
||||
enabled = true;
|
||||
limit[MARGIN_LEFT] = -10000000;
|
||||
limit[MARGIN_TOP] = -10000000;
|
||||
limit[MARGIN_RIGHT] = 10000000;
|
||||
|
@ -64,7 +64,7 @@ protected:
|
||||
Vector2 zoom;
|
||||
AnchorMode anchor_mode;
|
||||
bool rotating;
|
||||
bool current;
|
||||
bool enabled;
|
||||
float smoothing;
|
||||
bool smoothing_enabled;
|
||||
bool smoothing_active; // smoothing can be enabled but not active in the editor
|
||||
@ -86,7 +86,6 @@ protected:
|
||||
void _setup_viewport();
|
||||
|
||||
void _make_current(Object *p_which);
|
||||
void set_current(bool p_current);
|
||||
|
||||
bool screen_drawing_enabled;
|
||||
bool limit_drawing_enabled;
|
||||
@ -139,6 +138,9 @@ public:
|
||||
void set_process_mode(Camera2DProcessMode p_mode);
|
||||
Camera2DProcessMode get_process_mode() const;
|
||||
|
||||
void set_enabled(bool p_enabled);
|
||||
bool is_enabled() const;
|
||||
|
||||
void make_current();
|
||||
void clear_current();
|
||||
bool is_current() const;
|
||||
|
@ -1159,6 +1159,28 @@ Transform2D Viewport::get_final_transform() const {
|
||||
return stretch_transform * global_canvas_transform;
|
||||
}
|
||||
|
||||
void Viewport::assign_next_enabled_camera_2d(const StringName &p_camera_group) {
|
||||
List<Node *> camera_list;
|
||||
get_tree()->get_nodes_in_group(p_camera_group, &camera_list);
|
||||
|
||||
Camera2D *new_camera = nullptr;
|
||||
for (List<Node *>::Element *E = camera_list.front(); E; E = E->next()) {
|
||||
Camera2D *cam = Object::cast_to<Camera2D>(E->get());
|
||||
if (cam->is_enabled()) {
|
||||
new_camera = cam;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
camera_2d = NULL;
|
||||
|
||||
if (!new_camera) {
|
||||
set_canvas_transform(Transform2D());
|
||||
} else {
|
||||
new_camera->make_current();
|
||||
}
|
||||
}
|
||||
|
||||
void Viewport::_update_canvas_items(Node *p_node) {
|
||||
if (p_node != this) {
|
||||
Viewport *vp = Object::cast_to<Viewport>(p_node);
|
||||
|
@ -193,6 +193,7 @@ public:
|
||||
Transform2D get_global_canvas_transform() const;
|
||||
|
||||
Transform2D get_final_transform() const;
|
||||
void assign_next_enabled_camera_2d(const StringName &p_camera_group);
|
||||
|
||||
void set_transparent_background(bool p_enable);
|
||||
bool has_transparent_background() const;
|
||||
|
Loading…
Reference in New Issue
Block a user