Godot Version
v 4.4.1 (Steam)
Question
“There is code that drains the flashlight. The thing is, when the scene (game) starts, the flashlight drains in 2-3 seconds, regardless of the drain_rate values—whether it’s 0.001 or 5. I can’t figure out what the problem might be.”
extends Node3D
@onready var flashlight_model = $flashlightwithhand
@onready var spot_light = $flashlightwithhand/SpotLight3D
@onready var flashlight_sound = $FlashlightSound
@onready var flicker_sound = $FlickerSound
@onready var label = $“../../../HUD/BatteryLabel”
@onready var charge_label = $“../../../HUD/LabelPercent”
@export var camera_3d: Camera3D
@export var smooth_factor : float = 0.025
@export var flashlight_intensity = 1.5
@export var drain_rate = 0.001
@export var intense_boost_duration = 2.0
var log_timer := 0.0
var flashlight_battery := 100
var boosted = false
var boost_timer = 0.0
var flicker_timer = 0.0
var flicker_active = false
var is_near_battery = false
var last_printed_battery = -1
func _ready():
label.text = “E”
label.visible = false
randomize()
func _process(delta):
# Разрядка фонаря
if spot_light.visible and flashlight_battery > 0 and not boosted:
var effective_drain: float = max(drain_rate, 0.01) # даже при 0 будет медленно садиться
flashlight_battery -= effective_drain * delta
flashlight_battery = clamp(flashlight_battery, 0, 100)
# 🚀 Обработка буста
if boosted:
boost_timer = max(boost_timer - delta, 0.0)
var t = 1.0 - (boost_timer / intense_boost_duration)
spot_light.light_energy = lerp(3.0, flashlight_intensity, t)
if boost_timer <= 0.0:
boosted = false
spot_light.light_energy = flashlight_intensity
# 🔘On/off flashlight
if Input.is_action_just_pressed("flashlight") and flashlight_battery > 0:
if flashlight_battery < 15:
start_flicker_sequence(true)
else:
spot_light.visible = !spot_light.visible
flashlight_sound.play()
# 🪫 Auto off
if flashlight_battery <= 0.0 and spot_light.visible:
spot_light.visible = false
spot_light.light_energy = 0.0
# 🔋 E (take)
label.visible = is_near_battery
if is_near_battery:
label.text = "%d%%\n[Нажмите E]" % int(flashlight_battery)
if Input.is_action_just_pressed("interact"):
charge_flashlight()
# 🧪 Отображение процентов (дебаг)
_update_battery_label()
# 🎮 Anim
var sway_amount = Vector3.ZERO
var start_position = Vector3(-0.368, -0.02, -19.127)
flashlight_model.position = flashlight_model.position.lerp(start_position + sway_amount, smooth_factor)
# 🌩️ Flicker
call_deferred("handle_flicker", delta)
# ⏱️ Лог состояния
log_timer += delta
if log_timer >= 0.5:
log_timer = 0.0
var time_sec := Time.get_ticks_msec() / 1000.0
print("⏱ Time: %.1fs | 🔋 Battery: %d%% | ⚡ Drain rate: %.2f" % [time_sec, flashlight_battery, drain_rate])
# 🚀 Log boost
if boosted:
print("BOOST: ", "%.2f" % (intense_boost_duration - boost_timer), " сек | ЭНЕРГИЯ:", "%.2f" % spot_light.light_energy)
func charge_flashlight():
flashlight_battery = 100
boosted = true
boost_timer = intense_boost_duration
spot_light.visible = true
spot_light.light_energy = 3.0
flashlight_sound.play()
is_near_battery = false
label.visible = false
_update_battery_label()
func _update_battery_label():
var current = int(flashlight_battery)
if current != last_printed_battery and charge_label:
charge_label.text = str(current) + “%”
last_printed_battery = current
func handle_flicker(delta: float) → void:
if flashlight_battery >= 70 or flicker_active:
return
# Постоянное мерцание при <10%
if flashlight_battery < 10:
flicker_timer -= delta
if flicker_timer <= 0:
spot_light.light_energy = randf_range(0.1, 1.0)
spot_light.visible = !spot_light.visible
flicker_timer = randf_range(0.05, 0.2)
if flicker_sound:
flicker_sound.play()
if flashlight_battery <= 0:
spot_light.visible = false
spot_light.light_energy = 0.0
return
# Разовые мигания
var should_flicker = false
match int(flashlight_battery):
70, 50, 30, 25, 20, 15:
should_flicker = true
if should_flicker:
start_flicker_sequence(flashlight_battery <= 30)
func start_flicker_sequence(with_intensity := false) → void:
if flicker_active:
return
flicker_active = true
var blinks = randi_range(1, 3)
flicker_sequence(blinks, with_intensity)
func flicker_sequence(blinks: int, with_intensity := false) → void:
for i in range(blinks):
var delay = randf_range(0.05, 0.15)
spot_light.visible = false
await get_tree().create_timer(delay).timeout
if with_intensity and randi_range(0, 2) == 1:
spot_light.light_energy = randf_range(0.2, 2.5)
else:
spot_light.light_energy = flashlight_intensity
spot_light.visible = true
if flicker_sound:
flicker_sound.play()
await get_tree().create_timer(delay).timeout
flicker_active = false
Sorry. The forum somehow split my post, but it goes from top to bottom correctly