How come emit_signal doesn't work when putting it into an if-argument?

SameSame Posts: 12Member
edited July 2 in Programming

My head hurts after trying to troubleshoot this for way too long so I'll be brief:

func _physics_process(delta):
    var collision = move_and_collide(velocity*delta)
    if collision:
        emit_signal("hit")

doesn't work, but:

func _physics_process(delta):
    var collision = move_and_collide(velocity*delta)
    emit_signal("hit")

Works just fine. I cannot comprehend why.
The recieveing code is the following:

func _on_Bullet_hit():
    health -= 1
    if(health < 0):
        position.x = 0
        position.y = 0
        health = 3

what is going on?


Tags :

Best Answers

  • MegalomaniakMegalomaniak Posts: 2,768
    Accepted Answer

    There, I've edited your previous post and formatted the code, you can go to edit it to see how it's formatted.

    Anyways, if you comment out the _on_AnimationPlayer_animation_finished(_anim_name) function might that fix it?

  • SameSame Posts: 12
    Accepted Answer

    Thank you, I see how it works now.

    I tried removing the function and it just made the animation repeat ad infinitum, I decided to rework the code from the ground up utilizing a bunch of Area2Ds. It's not as elegant but it works.

    Thank you very much for the assistance though!

Answers

  • TwistedTwiglegTwistedTwigleg Posts: 2,847Admin

    Maybe try the following:

    func _physics_process(delta):
        var collision = move_and_collide(velocity*delta)
        print ("Collision is: ", collision)
        if collision:
            print ("Emitting signal...")
            emit_signal("hit")
    

    That way, you may be better able to see what is going on.

  • SameSame Posts: 12Member

    Now I'm even more confused...

    The full code under if(collision) is:

    if collision:
    print("emitting...")
    emit_signal("hit")
    $explosion/AnimationPlayer.play("explosion")
    $tankshot.hide()
    velocity = Vector2(0, 0)

    The animation plays, it hides the bullet, and (in a separate function) it deletes the instance, but printing and emitting a signal doesn't work, what?

  • MegalomaniakMegalomaniak Posts: 2,768Admin

    if collision is true, but does the variable hold a boolean value?

  • SameSame Posts: 12Member
    edited July 2

    No, it doesn't seem to, according to the docs:

    "If the engine detects a collision anywhere along this vector, the body will immediately stop moving. If this happens, the method will return a KinematicCollision2D object."

    The object contains a bunch of info such as the kind of collider it interacts with, but no boolean. The docs also elaborate with:

    Using move_and_collide.
    var collision = move_and_collide(velocity * delta)
    if collision:
    print("I collided with ", collision.collider.name)

    I'm assuming basically what happens is that the variable is only filled when a collision is found, which in turn triggers the if-argument, but I don't know.

    Either way, the issue remains strange, considering that only the calls for other nodes seem to be triggered...

  • TwistedTwiglegTwistedTwigleg Posts: 2,847Admin
    edited July 3

    Maybe perform a null check and see if that works? Something like if if collision != null:

  • SameSame Posts: 12Member

    I tried that, then I removed the check and now it works just fine (when printing something). However, the signal still doesn't get emitted for some reason (even with the check). I double-checked the signal link and it seems to be fine so something is going wrong in the emit_signal() method, which is weird because it's very simple:

    signal hit()
    (...)
    emit_signal("hit")

    Which should be correct, no?

  • MegalomaniakMegalomaniak Posts: 2,768Admin

    Have you made sure the signal is properly connected?

  • SameSame Posts: 12Member

    As I said in my OP, when the signal is placed outside of the if()-argument it transmits just fine, it's specifically when it's in the if() that it breaks, that's why it's spinning my head.

    Just to make sure it hadn't resolved itself like the print() issue I tested the signal by moving it in and out of if() and restarting through f6, and sure enough, the problem remains the same

  • TwistedTwiglegTwistedTwigleg Posts: 2,847Admin

    What does print(collision) show? It sounds like there is something relating to the collision variable that is causing the issue, though honestly, given the code and how it is functioning, this may be a bug.

  • SameSame Posts: 12Member
    edited July 4

    Print collision returns:

    [KinematicCollision2D:1622]
    

    It's an object with the following properties:

    Object  collider     
    int         collider_id                 0
    Variant     collider_metadata    
    Object  collider_shape   
    int         collider_shape_index    0
    Vector2     collider_velocity           Vector2( 0, 0 )
    Object  local_shape      
    Vector2     normal                  Vector2( 0, 0 )
    Vector2     position                    Vector2( 0, 0 )
    Vector2     remainder               Vector2( 0, 0 )
    Vector2     travel                      Vector2( 0, 0 )
    

    It would seem like a bug, any ideas on how i would go about resolving it?

  • MegalomaniakMegalomaniak Posts: 2,768Admin

    Any chance you have some code somewhere causing your object to be removed before it gets to emit the signal?

  • TwistedTwiglegTwistedTwigleg Posts: 2,847Admin
    edited July 4

    Hmm, so it looks like it is returning an empty or newly initialized KinematicCollision2D object, rather than something like null. For testing for actual collisions, you could try the following:

    func _physics_process(delta):
    var collision = move_and_collide(velocity*delta)
    if collision:
        # Every collision should have a normal, as it has to hit something
        # (and bounce off) to return a collision.
        if collision.normal.length_squared() != 0:
            print ("Emitting signal...")
            emit_signal("hit")
    

    Though that doesn't solve the signal not being emitted. I would suggest looking to see if there is perhaps something operating on the object before the signal gets to be emitted, like Megalomaniak suggested. Outside of that, I'm not sure right off on what could be causing the issue.

  • SameSame Posts: 12Member
    edited July 5

    I have a signal that gets emitted to the instance itself, it's a prebuilt one but it essentially just deletes the instance once the animation finishes, but I emit the signal before even starting to play the animation so it should get sent just fine, right?

    here's the code for it:

    func _physics_process(delta):
        var collision = move_and_collide(velocity*delta)
        if collision:
            if collision.normal.length_squared() != 0:
                emit_signal("hit")
                $explosion/AnimationPlayer.play("explosion")
                $tankshot.hide()
                velocity = Vector2(0, 0)
    
    
    func _on_AnimationPlayer_animation_finished(_anim_name):
        get_parent().remove_child(self) 
    
  • MegalomaniakMegalomaniak Posts: 2,768Admin

    You can encapsulate the lines of code with ~~~ at both ends.

  • SameSame Posts: 12Member

    Isn't that the formatting for strikethroughs?

  • MegalomaniakMegalomaniak Posts: 2,768Admin
    edited July 5

    No, it's a codeblock highlight. `` is for inline code. You can also just indent your whole code once before copying it and then paste it here, that will have the same effect as ~~~, strikethrough is two ~~.

        the ``` can be used too though, but again in threes then
    

    Mind, we are considering switching from markdown to the new WYSIWYG editor. You can test it in the testing forum by logging in with the same account. You can find a sticky/announced topic linking the testing forum if you are interested to try it out. We could use the user feedback before we make a decision.

  • SameSame Posts: 12Member

    Alright, I've been playing around with it for some time now but it doesn't seem to be working at least not for the kind of code blocks like @TwistedTwigleg is using.

    Either way, this is a bit of a tangent, as I said before, the code to emit the signal is placed before the signal to start the animation which in turn is linked to the instance deleting itself.

    So theoretically it should be fine? Is there anything to do at this point other than just trying to rebuild the tree? If so, what?

  • MegalomaniakMegalomaniak Posts: 2,768Admin
    Accepted Answer

    There, I've edited your previous post and formatted the code, you can go to edit it to see how it's formatted.

    Anyways, if you comment out the _on_AnimationPlayer_animation_finished(_anim_name) function might that fix it?

  • SameSame Posts: 12Member
    Accepted Answer

    Thank you, I see how it works now.

    I tried removing the function and it just made the animation repeat ad infinitum, I decided to rework the code from the ground up utilizing a bunch of Area2Ds. It's not as elegant but it works.

    Thank you very much for the assistance though!

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file