72 lines
1.9 KiB
GDScript3
72 lines
1.9 KiB
GDScript3
|
class_name PerformanceComponent
|
||
|
extends VisibleOnScreenNotifier3D
|
||
|
|
||
|
const SKIP_FRAMES_INVISIBLE := 16
|
||
|
const SKIP_FRAMES_VISIBLE := 8
|
||
|
|
||
|
static var quality_budget: Array[int] = [
|
||
|
10, # 0 skipped frames
|
||
|
10, # 1 skipped frame
|
||
|
10, # 2 skipped frames
|
||
|
10, # 3 skipped frames
|
||
|
10, # 4 skipped frames
|
||
|
10, # 5 skipped frames
|
||
|
10, # 6 skipped frames
|
||
|
10, # 7 skipped frames
|
||
|
]
|
||
|
|
||
|
@export var animation: AnimationComponent
|
||
|
|
||
|
var camera_distance_squared: float
|
||
|
var on_screen: bool
|
||
|
var skip_frames_visible: int
|
||
|
|
||
|
func _ready():
|
||
|
assert(animation)
|
||
|
screen_entered.connect(on_screen_entered)
|
||
|
screen_exited.connect(on_screen_exited)
|
||
|
|
||
|
func on_screen_entered():
|
||
|
on_screen = true
|
||
|
animation.skip_frames = skip_frames_visible
|
||
|
|
||
|
func on_screen_exited():
|
||
|
on_screen = false
|
||
|
animation.skip_frames = SKIP_FRAMES_INVISIBLE
|
||
|
|
||
|
static func update_all_animations():
|
||
|
var visible_players: Array[Player] = []
|
||
|
|
||
|
for player in Global.players.id_to_player.values():
|
||
|
player.performance.camera_distance_squared = player.global_position.distance_squared_to(Global.camera.global_position)
|
||
|
|
||
|
if player.performance.on_screen:
|
||
|
visible_players.append(player)
|
||
|
else:
|
||
|
player.performance.animation.skip_frames = SKIP_FRAMES_INVISIBLE
|
||
|
|
||
|
if Global.player:
|
||
|
Global.player.performance.camera_distance_squared = 0
|
||
|
|
||
|
visible_players.sort_custom(PerformanceComponent.distance_sort)
|
||
|
|
||
|
var skip_frames := 0
|
||
|
var count := 0
|
||
|
|
||
|
for player in visible_players:
|
||
|
if skip_frames >= quality_budget.size():
|
||
|
player.performance.skip_frames_visible = SKIP_FRAMES_VISIBLE
|
||
|
player.animation.skip_frames = SKIP_FRAMES_VISIBLE
|
||
|
continue
|
||
|
|
||
|
player.performance.skip_frames_visible = skip_frames
|
||
|
player.animation.skip_frames = skip_frames
|
||
|
count += 1
|
||
|
|
||
|
if count >= quality_budget[skip_frames]:
|
||
|
skip_frames += 1
|
||
|
count = 0
|
||
|
|
||
|
static func distance_sort(a: Player, b: Player) -> bool:
|
||
|
return a.performance.camera_distance_squared < b.performance.camera_distance_squared
|
||
|
|