Add rotation smoothing to Camera2D
Camera2D has follow smoothing to interpolate towards a target position, but no rotation smoothing to align with the target rotation. This adds rotation smoothing directly into the Camera2D API by having two new properties: - `rotation_smoothing_enabled` - `rotation_smoothing_speed`
This commit is contained in:
parent
e5aa5eb806
commit
c262589e26
|
@ -150,6 +150,13 @@
|
|||
<member name="process_callback" type="int" setter="set_process_callback" getter="get_process_callback" enum="Camera2D.Camera2DProcessCallback" default="1">
|
||||
The camera's process callback. See [enum Camera2DProcessCallback].
|
||||
</member>
|
||||
<member name="rotation_smoothing_enabled" type="bool" setter="set_rotation_smoothing_enabled" getter="is_rotation_smoothing_enabled" default="false">
|
||||
If [code]true[/code], the camera's view smoothly rotates, via asymptotic smoothing, to align with its target rotation at [member rotation_smoothing_speed].
|
||||
[b]Note:[/b] This property has no effect if [member ignore_rotation] is [code]true[/code].
|
||||
</member>
|
||||
<member name="rotation_smoothing_speed" type="float" setter="set_rotation_smoothing_speed" getter="get_rotation_smoothing_speed" default="5.0">
|
||||
The angular, asymptotic speed of the camera's rotation smoothing effect when [member rotation_smoothing_enabled] is [code]true[/code].
|
||||
</member>
|
||||
<member name="smoothing_enabled" type="bool" setter="set_enable_follow_smoothing" getter="is_follow_smoothing_enabled" default="false">
|
||||
If [code]true[/code], the camera smoothly moves towards the target at [member smoothing_speed].
|
||||
</member>
|
||||
|
|
|
@ -171,9 +171,14 @@ Transform2D Camera2D::get_camera_transform() {
|
|||
|
||||
Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom_scale) : Point2());
|
||||
|
||||
real_t angle = get_global_rotation();
|
||||
if (!ignore_rotation) {
|
||||
screen_offset = screen_offset.rotated(angle);
|
||||
if (rotation_smoothing_enabled && !Engine::get_singleton()->is_editor_hint()) {
|
||||
real_t step = rotation_smoothing_speed * (process_callback == CAMERA2D_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time());
|
||||
camera_angle = Math::lerp_angle(camera_angle, get_global_rotation(), step);
|
||||
} else {
|
||||
camera_angle = get_global_rotation();
|
||||
}
|
||||
screen_offset = screen_offset.rotated(camera_angle);
|
||||
}
|
||||
|
||||
Rect2 screen_rect(-screen_offset + ret_camera_pos, screen_size * zoom_scale);
|
||||
|
@ -205,7 +210,7 @@ Transform2D Camera2D::get_camera_transform() {
|
|||
Transform2D xform;
|
||||
xform.scale_basis(zoom_scale);
|
||||
if (!ignore_rotation) {
|
||||
xform.set_rotation(angle);
|
||||
xform.set_rotation(camera_angle);
|
||||
}
|
||||
xform.set_origin(screen_rect.position);
|
||||
|
||||
|
@ -366,6 +371,12 @@ Camera2D::AnchorMode Camera2D::get_anchor_mode() const {
|
|||
void Camera2D::set_ignore_rotation(bool p_ignore) {
|
||||
ignore_rotation = p_ignore;
|
||||
Point2 old_smoothed_camera_pos = smoothed_camera_pos;
|
||||
|
||||
// Reset back to zero so it matches the camera rotation when ignore_rotation is enabled.
|
||||
if (ignore_rotation) {
|
||||
camera_angle = 0.0;
|
||||
}
|
||||
|
||||
_update_scroll();
|
||||
smoothed_camera_pos = old_smoothed_camera_pos;
|
||||
}
|
||||
|
@ -415,6 +426,14 @@ void Camera2D::set_current(bool p_current) {
|
|||
}
|
||||
}
|
||||
|
||||
void Camera2D::_update_process_internal_for_smoothing() {
|
||||
bool is_not_in_scene_or_editor = !(is_inside_tree() && Engine::get_singleton()->is_editor_hint());
|
||||
bool is_any_smoothing_valid = smoothing > 0 || rotation_smoothing_speed > 0;
|
||||
|
||||
bool enabled = is_any_smoothing_valid && is_not_in_scene_or_editor;
|
||||
set_process_internal(enabled);
|
||||
}
|
||||
|
||||
bool Camera2D::is_current() const {
|
||||
return current;
|
||||
}
|
||||
|
@ -508,17 +527,31 @@ void Camera2D::align() {
|
|||
|
||||
void Camera2D::set_follow_smoothing(real_t p_speed) {
|
||||
smoothing = p_speed;
|
||||
if (smoothing > 0 && !(is_inside_tree() && Engine::get_singleton()->is_editor_hint())) {
|
||||
set_process_internal(true);
|
||||
} else {
|
||||
set_process_internal(false);
|
||||
}
|
||||
_update_process_internal_for_smoothing();
|
||||
}
|
||||
|
||||
real_t Camera2D::get_follow_smoothing() const {
|
||||
return smoothing;
|
||||
}
|
||||
|
||||
void Camera2D::set_rotation_smoothing_speed(real_t p_speed) {
|
||||
rotation_smoothing_speed = p_speed;
|
||||
_update_process_internal_for_smoothing();
|
||||
}
|
||||
|
||||
real_t Camera2D::get_rotation_smoothing_speed() const {
|
||||
return rotation_smoothing_speed;
|
||||
}
|
||||
|
||||
void Camera2D::set_rotation_smoothing_enabled(bool p_enabled) {
|
||||
rotation_smoothing_enabled = p_enabled;
|
||||
notify_property_list_changed();
|
||||
}
|
||||
|
||||
bool Camera2D::is_rotation_smoothing_enabled() const {
|
||||
return rotation_smoothing_enabled;
|
||||
}
|
||||
|
||||
Point2 Camera2D::get_camera_screen_center() const {
|
||||
return camera_screen_center;
|
||||
}
|
||||
|
@ -659,6 +692,9 @@ void Camera2D::_validate_property(PropertyInfo &p_property) const {
|
|||
if (!smoothing_enabled && p_property.name == "smoothing_speed") {
|
||||
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
|
||||
}
|
||||
if (!rotation_smoothing_enabled && p_property.name == "rotation_smoothing_speed") {
|
||||
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
|
||||
}
|
||||
}
|
||||
|
||||
void Camera2D::_bind_methods() {
|
||||
|
@ -716,6 +752,12 @@ void Camera2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_enable_follow_smoothing", "follow_smoothing"), &Camera2D::set_enable_follow_smoothing);
|
||||
ClassDB::bind_method(D_METHOD("is_follow_smoothing_enabled"), &Camera2D::is_follow_smoothing_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_rotation_smoothing_enabled", "enabled"), &Camera2D::set_rotation_smoothing_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_rotation_smoothing_enabled"), &Camera2D::is_rotation_smoothing_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_rotation_smoothing_speed", "speed"), &Camera2D::set_rotation_smoothing_speed);
|
||||
ClassDB::bind_method(D_METHOD("get_rotation_smoothing_speed"), &Camera2D::get_rotation_smoothing_speed);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("force_update_scroll"), &Camera2D::force_update_scroll);
|
||||
ClassDB::bind_method(D_METHOD("reset_smoothing"), &Camera2D::reset_smoothing);
|
||||
ClassDB::bind_method(D_METHOD("align"), &Camera2D::align);
|
||||
|
@ -750,6 +792,10 @@ void Camera2D::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smoothing_enabled"), "set_enable_follow_smoothing", "is_follow_smoothing_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "smoothing_speed", PROPERTY_HINT_NONE, "suffix:px/s"), "set_follow_smoothing", "get_follow_smoothing");
|
||||
|
||||
ADD_GROUP("Rotation Smoothing", "rotation_smoothing_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotation_smoothing_enabled"), "set_rotation_smoothing_enabled", "is_rotation_smoothing_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation_smoothing_speed"), "set_rotation_smoothing_speed", "get_rotation_smoothing_speed");
|
||||
|
||||
ADD_GROUP("Drag", "drag_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_horizontal_enabled"), "set_drag_horizontal_enabled", "is_drag_horizontal_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_vertical_enabled"), "set_drag_vertical_enabled", "is_drag_vertical_enabled");
|
||||
|
|
|
@ -67,6 +67,11 @@ protected:
|
|||
bool current = false;
|
||||
real_t smoothing = 5.0;
|
||||
bool smoothing_enabled = false;
|
||||
|
||||
real_t camera_angle = 0.0;
|
||||
real_t rotation_smoothing_speed = 5.0;
|
||||
bool rotation_smoothing_enabled = false;
|
||||
|
||||
int limit[4];
|
||||
bool limit_smoothing_enabled = false;
|
||||
|
||||
|
@ -87,6 +92,8 @@ protected:
|
|||
|
||||
void _set_old_smoothing(real_t p_enable);
|
||||
|
||||
void _update_process_internal_for_smoothing();
|
||||
|
||||
bool screen_drawing_enabled = true;
|
||||
bool limit_drawing_enabled = false;
|
||||
bool margin_drawing_enabled = false;
|
||||
|
@ -139,6 +146,12 @@ public:
|
|||
void set_follow_smoothing(real_t p_speed);
|
||||
real_t get_follow_smoothing() const;
|
||||
|
||||
void set_rotation_smoothing_speed(real_t p_speed);
|
||||
real_t get_rotation_smoothing_speed() const;
|
||||
|
||||
void set_rotation_smoothing_enabled(bool p_enabled);
|
||||
bool is_rotation_smoothing_enabled() const;
|
||||
|
||||
void set_process_callback(Camera2DProcessCallback p_mode);
|
||||
Camera2DProcessCallback get_process_callback() const;
|
||||
|
||||
|
|
Loading…
Reference in New Issue