im making a wolfenstein 3d clone, and im using a delta counter for fire delay of the fully automatic weapon, but with he chaingun weapon im using a frame_changed signal to fire on the second frame (the weapon has 2 frames in its firing animation each lasting 3 frames in 35fps, the sprite fps and game fps have the exact same frame rate of 35, and the animation doesnt loop), i did this to make it when you one tap the weapon it will fire a burst of two shots kinda like wolfenstein or doom

the problem is that after it fires a couple normal shots while holding down fire, the signal will just stop, then after a couple more shots it will go back to normal, then repeat.

also, im confident the issue is the signal or has something directly do with the signal, i have another weapon in the game that doesnt use the signal and only uses the counter and it works perfectly as intended

video showcasing issue, its doing the issue that ive eplained before, but it should be firing consistant full auto and not switching fire rate because the frame_changed signal for some reason will do the issue that ive explained before:

code:

extends Node3D

@onready var Weapon_Sprite = $CanvasLayer/Control/WeaponSprite

@onready var Hitscan = $Hitscan.get_children()

#var can_fire = true
var fire_rate = 6
var fire_timer = fire_rate

func _ready():
	Weapon_Sprite.play("Idle")
	
func check_hit():
	for ray in Hitscan:
		if ray.is_colliding():
			if ray.get_collider().is_in_group("Enemy"):
				ray.get_collider().take_damage(5)
	
func _process(delta):
	#ask godot forums for help with animaion bullshit
	if Input.is_action_pressed("main_fire_weapon"):
		Weapon_Sprite.play("Fire")
		if fire_timer == fire_rate:
			Fire()
		if fire_timer > 0:
			fire_timer -= 1
		if fire_timer == 0:
			fire_timer = fire_rate
	if not Input.is_action_pressed("main_fire_weapon"):
		if fire_timer == fire_rate:
			Weapon_Sprite.play("Idle")
		elif fire_timer > 0:
			fire_timer -= 1
			if fire_timer == 0:
				fire_timer = fire_rate
				Weapon_Sprite.play("Idle")
		
func Fire():
	check_hit()
        #$Fire is just the goddamn sound effect player
	$Fire.play()
	
#ask godot forums to help with the fact that this shit for 
#some reason goes between the 3 frame fire rate and 6 frame fire rate
#also fix obs
func _on_weapon_sprite_frame_changed():
	if Weapon_Sprite.animation == ("Fire"):
		if Weapon_Sprite.frame == 1:
			Fire()
  • xyz replied to this.

    JetteBoyTV Sprite animation frames and main engine frames are not the same thing. Sprite fps can be set to any arbitrary value. Nothing guarantees it will be in sync with main fps. So you can't just "count" sprite animation frames in _process()

      xyz the animation frame rate and game frame rate are set to the same value of 35, and the issue im is related to the frame_changed signal, not the counter, the counter works perfectly fine

      • xyz replied to this.

        JetteBoyTV How did you set game's framerate to 35 fps?
        The only "issue" is buggy logic in your code. It's the same problem you had with your previous question. And the "fix" is the same: concentrate, write down in plain language the logic/flowchart of how the weapon should behave, and then translate that into code.

          xyz i set the games framerate to 35 fps in the project settings, also dude, it feels like your avoiding actually trying to help me resolve the issue i have at hand, i can write down plain logic and translate that into code all i want, that isnt gonna resolve the fact that for some reason the frame_changed signal will just stop a bit into firing and after a bit it will start back, then repeat, why is it doing this, how do i resolve the issue?

          • xyz replied to this.

            JetteBoyTV No. I'm not avoiding helping you. Nobody can help you here. Why? Because you formulated the problem poorly. There's not enough information. The weak problem formulation is also the reason why you yourself have hard time figuring it out. When you can describe the problem well, with all its relevant parameters - then it will be much easier for you to think clearly about it and possibly solve it.

            What information is/was missing?

            • We never heard that your sprite and game fps are identical. Noone will just presume this, because forcing a game to run at 35 fps is highly unusual. No sane person would limit the framerate to such a low and weird value.
            • The description of the weapon behavior (logic) is not given clearly. And it can't be deduced from your code because the code you have is haphazard. And we cannot read your mind. You need to be much much clearer and provide ALL the information, even the things that look self evident from your perspective.
            • We don't know how many frames are in the animation
            • We don't know the looping status of your animations
            • We don't know what $Fire is and what $Fire.play() does
            • From the video you posted, It's not really clear what's bothering you. It doesn't illustrate it well, and you haven't provided a mockup that, in contrast, may show how exactly you want it to behave.
            • etc...

            Also, you insist that the problem is with the signal. What makes you so sure? If you're so confident that you identified the source of the problem, then exercise that same level of confidence in fixing it.

            The reality is - there's no issue with Godot's signal here. You produced some buggy code that fails at basic logic, but you're even unwilling to verbally formulate that logic in a precise manner. If you expect someone else to implement it for free - respect their time and be thoughtful about making their effort as easy as possible by providing all the information they may need to help you. Always better to err on the side of redundancy in cases like this.

            All this, more or less, applies to your previous questions as well. And that's the main reason you're not getting satisfactory "answers".

              JetteBoyTV Anyway, regardless of the logic, run the game at standard fps and don't count sprite frames on your own in _process(). Why do it yourself when the engine is already keeping track of it? The AnimatedSprite node is always counting animation frames and is sending a signal whenever the next frame is counted (frame_changed signal). So anything regarding the frame count should be done in the signal handler using sprite's current frame value. This is the proper way to do it as it will decouple the counting from the game's fps. And it should be done like that even if you insist on capping the main fps to 35.

              xyz im sorry that i explained my issue poorly, i admit fault, ive edited the post to better explain it and include information that was missing, the $Fire is just the sound effect and ive added a code comment that explains that, also, im confident the issue is with the signal or has something directly do with the signal, i have another weapon in the game that doesnt use the signal and only uses the counter and it works perfectly as intended, but i dont know the specific reason why the signal isnt working properly or how to solve the issue, which is the whole reason why im here asking for help, also theres a reason why i have the game at 35fps, i mod doom a lot, doom runs at 35fps, so my understanding of how 35fps looks and feels is practically 2nd nature to me, so theres a reason why im using a "low and weird" value for the fps rate

              • xyz replied to this.

                JetteBoyTV As I said, don't count frames in _process(), count them in frame_changed callback.