PlayerCamera2 WIP
This commit is contained in:
parent
7641aa5d3e
commit
d343c458a2
9 changed files with 147 additions and 30 deletions
|
@ -190,4 +190,3 @@ func _on_filter_text_changed() -> void:
|
|||
var sf = get_node(stat_filter)
|
||||
for child in categories.get_children():
|
||||
child.visible = child.name.contains(sf.text) || sf.text == ""
|
||||
|
||||
|
|
|
@ -1,22 +1,10 @@
|
|||
extends Node2D
|
||||
class_name CameraProperties
|
||||
|
||||
## In the camera stack, all these values have to be set at some point.
|
||||
|
||||
## x: transition time, y: completeness of transition (0.0 to 1.0)
|
||||
@export var transform_curve: Curve = null
|
||||
## x: transition time, y: completeness of transition (0.0 to 1.0)
|
||||
@export var limits_curve: Curve = null
|
||||
## x: transition time, y: completeness of transition (0.0 to 1.0)
|
||||
@export var smoothing_curve: Curve = null
|
||||
|
||||
## The leftomost point of the screen will not pass this coordinate
|
||||
@export var limit_left := -10000000
|
||||
## -||-
|
||||
@export var limit_right := 10000000
|
||||
## -||-
|
||||
@export var limit_top := -10000000
|
||||
## -||-
|
||||
@export var limit_bottom := 10000000
|
||||
|
||||
## The smoothing of the camera.
|
||||
@export var smoothing := 8.0
|
||||
@export var limits: Limits = null
|
||||
@export var smoothing : Float = null
|
||||
|
||||
|
|
19
project2-godot/global/camera/Limits.gd
Normal file
19
project2-godot/global/camera/Limits.gd
Normal file
|
@ -0,0 +1,19 @@
|
|||
extends Resource
|
||||
class_name Limits
|
||||
|
||||
@export var left: float
|
||||
@export var right: float
|
||||
@export var top: float
|
||||
@export var bottom: float
|
||||
|
||||
func _init(
|
||||
p_left = -10000000,
|
||||
p_right = 10000000,
|
||||
p_top = - 10000000,
|
||||
p_bottom = 10000000
|
||||
):
|
||||
left = p_left
|
||||
right = p_right
|
||||
top = p_top
|
||||
bottom = p_bottom
|
||||
|
1
project2-godot/global/camera/Limits.gd.uid
Normal file
1
project2-godot/global/camera/Limits.gd.uid
Normal file
|
@ -0,0 +1 @@
|
|||
uid://dbhp6ek2kwibq
|
|
@ -1,7 +1,6 @@
|
|||
extends Node2D
|
||||
|
||||
# TODO make "original properties" into "previous targets" for more natural
|
||||
# transitions.
|
||||
@export var original_properties: NodePath
|
||||
|
||||
## If enabled, takes control of viewport transform.
|
||||
@export var enabled := false
|
||||
|
@ -49,7 +48,6 @@ var example_properties := {
|
|||
@onready var camera_stack : Array[CameraProperties] = [ get_node(fallback_properties) ]
|
||||
## Schema: { <property_name>: <property_progress> (seconds) }
|
||||
var property_progress := {}
|
||||
var original_properties := {}
|
||||
## Used for smoothing
|
||||
## Schema: { <property_name>: <reference to node> }
|
||||
var current_properties := {}
|
||||
|
@ -99,7 +97,7 @@ func _reset(op):
|
|||
if p_to_c[key] != new_p_to_c[key]:
|
||||
# reset timer
|
||||
property_progress[key] = 0.0
|
||||
original_properties[key] = p_to_c[key]
|
||||
get_node(original_properties)[key] = p_to_c[key]
|
||||
|
||||
func remove_camera(c):
|
||||
var op = func(): camera_stack.erase(c)
|
||||
|
@ -134,6 +132,9 @@ func reset_smoothing():
|
|||
for p in properties:
|
||||
original_properties[p] = _get_camera(p)
|
||||
|
||||
func _clamp_with_limits(value: Vector2, limits_node) -> Vector2:
|
||||
pass
|
||||
|
||||
func _process(delta: float):
|
||||
# Lookaside (x-pan)
|
||||
var target_pos = look_aside if looking_right else - look_aside
|
||||
|
@ -155,18 +156,16 @@ func _process(delta: float):
|
|||
)
|
||||
var smoothing = current_properties["smoothing"]
|
||||
_property_step("limits", func(fraction, old, target_node):
|
||||
var intermediate_left = lerpf(old.limit_left, target_node.limit_left, fraction)
|
||||
current_properties["limits"]["left"] = lerpf(current_properties["limits"]["left"], intermediate_left, smoothing * delta)
|
||||
var intermediate_right = lerpf(old.limit_right, target_node.limit_right, fraction)
|
||||
current_properties["limits"]["right"] = lerpf(current_properties["limits"]["right"], intermediate_right, smoothing * delta)
|
||||
var intermediate_top = lerpf(old.limit_top, target_node.limit_top, fraction)
|
||||
current_properties["limits"]["top"] = lerpf(current_properties["limits"]["top"], intermediate_top, smoothing * delta)
|
||||
var intermediate_bottom = lerpf(old.limit_bottom, target_node.limit_bottom, fraction)
|
||||
current_properties["limits"]["bottom"] = lerpf(current_properties["limits"]["bottom"], intermediate_bottom, smoothing * delta)
|
||||
current_properties["limits"]["left"] = target_node.limit_left
|
||||
current_properties["limits"]["right"] = target_node.limit_right
|
||||
current_properties["limits"]["top"] = target_node.limit_top
|
||||
current_properties["limits"]["bottom"] = target_node.limit_bottom
|
||||
)
|
||||
_property_step("transform", func(fraction, old, target_node):
|
||||
# We are not interested in inherited transform properties except for position
|
||||
var end_target = target_node.transform.translated(target_node.global_transform.origin)
|
||||
var end_target_pos = _clamp_with_limits(target_node.transform.global_transform, _get_camera("limits"))
|
||||
var end_target = target_node.transform.translated(end_target_pos)
|
||||
|
||||
var old_target = old.transform.translated(old.global_transform.origin)
|
||||
|
||||
var intermediate_target: Transform2D = old_target.interpolate_with(end_target, fraction)
|
||||
|
|
101
project2-godot/global/camera/PlayerCamera2.gd
Normal file
101
project2-godot/global/camera/PlayerCamera2.gd
Normal file
|
@ -0,0 +1,101 @@
|
|||
extends Node
|
||||
|
||||
## If enabled, takes control of viewport transform.
|
||||
@export var enabled := false
|
||||
|
||||
## Enables outputting debug info for this camera. Shows center of camera gizmo if gizmos are turned on.
|
||||
## Outputs properties to debug screen.
|
||||
@export var debug_show := false
|
||||
|
||||
var properties := ["transform", "smoothing", "limits"]
|
||||
|
||||
## The default camera properties.
|
||||
@export var fallback_properties: NodePath
|
||||
|
||||
## Used to store nodes of properties of A during transition A -> B.
|
||||
var _original_properties := {}
|
||||
|
||||
|
||||
## Stack of references to CamerProperties
|
||||
@onready var _camera_stack : Array[CameraProperties] = [ get_node(fallback_properties) ]
|
||||
|
||||
var _transition_progress := 1.0
|
||||
var _current_transform: Transform2D = Transform2D.IDENTITY
|
||||
|
||||
func reset_smoothing():
|
||||
_transition_progress = 1.0
|
||||
|
||||
|
||||
## Finds the active CameraProperties for a given property.
|
||||
## depth can be specified to get the camera of second/third/... priority.
|
||||
func _get_camera(property: String, depth: int = 0):
|
||||
var current_depth := depth
|
||||
|
||||
for i in _camera_stack.size():
|
||||
var index = _camera_stack.size() -1 -i
|
||||
var c = _camera_stack[index]
|
||||
# Clean up destroyed cameras
|
||||
if c == null:
|
||||
_camera_stack.remove_at(index)
|
||||
else:
|
||||
var null_check_name = "transform_curve" if property == "transform" else property
|
||||
if c[null_check_name] != null:
|
||||
if current_depth <= 0:
|
||||
return c
|
||||
else:
|
||||
current_depth -= 1
|
||||
# there wasn't a camera with this depth? try getting one with higher priority
|
||||
return _get_camera(property, depth - 1)
|
||||
|
||||
|
||||
## Set timers and original properties on properites that changed after operation "op".
|
||||
func _reset(op):
|
||||
var p_to_c := {}
|
||||
# get list of destination cameras for every property
|
||||
for p in properties:
|
||||
p_to_c[p] = _get_camera(p)
|
||||
# remove/add camera
|
||||
op.call()
|
||||
# get list of destination cameras for every property
|
||||
var new_p_to_c := {}
|
||||
for p in properties:
|
||||
new_p_to_c[p] = _get_camera(p)
|
||||
# reset transition timer
|
||||
if p_to_c["transform"] != new_p_to_c["transform"]:
|
||||
_transition_progress = 1.0
|
||||
# set original properties
|
||||
for key in p_to_c:
|
||||
if p_to_c[key] != new_p_to_c[key]:
|
||||
_original_properties[key] = p_to_c[key]
|
||||
|
||||
func _clamp_with_limits(value: Vector2, limits: Limits, middle_offset: Vector2) -> Vector2:
|
||||
return Vector2(
|
||||
clampf(value.x, limits.left + middle_offset.x, limits.right - middle_offset.x),
|
||||
clampf(value.y, limits.top + middle_offset.y, limits.bottom - middle_offset.y)
|
||||
)
|
||||
|
||||
func _process(delta: float):
|
||||
if enabled:
|
||||
# the offset of the viewport to account for the screen size
|
||||
var middle_offset: Vector2 = get_viewport().content_scale_size / 2
|
||||
|
||||
# update position
|
||||
var target_node = _get_camera("transform")
|
||||
var target_pos = _clamp_with_limits(target_node.transform.global_transform, _get_camera("limits").limits, middle_offset)
|
||||
var target_transform = target_node.transform.translated(target_pos)
|
||||
|
||||
var original_node = _original_properties["transform"]
|
||||
var original_pos = _clamp_with_limits(target_node.transform.global_transform, _original_properties["limits"].limits, middle_offset)
|
||||
var original_transform = original_node.transform.translated(original_pos)
|
||||
|
||||
var intermediate_fraction = _get_camera("transform").transform_curve.sample(_transition_progress)
|
||||
var intermediate_transform: Transform2D = original_transform.interpolate_with(target_transform, intermediate_fraction)
|
||||
|
||||
var smoothing = _get_camera("smoothing").smoothing.value
|
||||
|
||||
# interpolate between _current_transform and intermediate_transform
|
||||
_current_transform.interpolate_with(intermediate_transform, smoothing * delta)
|
||||
|
||||
# apply to viewport
|
||||
get_viewport().canvas_transform = _current_transform.inverse().translated(middle_offset)
|
||||
|
1
project2-godot/global/camera/PlayerCamera2.gd.uid
Normal file
1
project2-godot/global/camera/PlayerCamera2.gd.uid
Normal file
|
@ -0,0 +1 @@
|
|||
uid://60wby2r3n4tx
|
8
project2-godot/global/hacks/Float.gd
Normal file
8
project2-godot/global/hacks/Float.gd
Normal file
|
@ -0,0 +1,8 @@
|
|||
extends Resource
|
||||
class_name Float
|
||||
|
||||
@export var val: float = 0.0
|
||||
|
||||
func _init(p_val = 0.0):
|
||||
val = p_val
|
||||
|
1
project2-godot/global/hacks/Float.gd.uid
Normal file
1
project2-godot/global/hacks/Float.gd.uid
Normal file
|
@ -0,0 +1 @@
|
|||
uid://bmuu0n34auwaq
|
Loading…
Add table
Add a link
Reference in a new issue