0 votes

The title's super vague for the question I have, but bear with me here. The game I'm working on references a rotating hitbox around the player that tracks your mouse movement, and when you click, checks for collision. I've been trying to figure out the best way to go about this, trying to get it to work optimally with the physics ordering.

Originally the hitbox rotation would be set to the mouse's position during process, as I also had tied to it a visual representation of where it was. I had the hitbox as a child of the player node, however in that situation when the player would move the hitbox and click, because the click processing was being called from the player script (i.e. $attack.getoverlappingbodies()), the actual rotation of the hitbox wasn't being performed until after the collision check had already been done.

In order to fix this, I moved the hitbox and the visual off of the player node, separated them, and moved them to be different nodes that were higher up on the tree than the player node. The visual operates by itself now and is irrelevant now, but they both track the player's position in the world and position themselves at the same location. What I'm doing now for the rotation is still having the hitbox track the mouse in process, but on a mouse click, it locks its position until the next physics frame, at which point it will unlock again.

This seems to be working as I want it to, but I'm curious if there's a better way to do this. Was there a way for me to just modify something about the hitbox node to get it to actually process its rotate before its parent would call it for collision checking?

EDIT: It's not working, I was wrong. I'm still not sure of how to rotate a collision shape before the called collision check occurs. Any suggestions or explanations would be greatly appreciated lol.

EDIT2: So I guess essentially my question is why does this code:

    if Input.is_action_just_pressed("attack1"):
    rotation = (get_global_mouse_position() - position).angle()

Rotate BEFORE collision checks if its in physics process, but AFTER if its in process?

EDIT3: It's got something to do with the Input call. If I use the following code:

func _process(delta):
    if Input.is_action_just_pressed("attack1"):
         attack = true

func _physics_process(delta):
    if attack:
       rotation = (get_global_mouse_position() - position).angle()
       attack = false

It stops working.

TL;DR - A hitbox child was getting told to rotate and then check for collision, both calls coming from its parent. The rotation call was during process, the collision check during physics_process, and this cause the collision check to activate BEFORE the rotation. What's the best way to get the rotation to happen first?

in Engine by (436 points)
edited by

1 Answer

0 votes

So I was unable to find a solution using the basic CollisionShapes. I thought that force_transform_update() would work, but it didn't.

My workaround is using raycasts. When a click is registered in process, I store the mouse position. On the next physics frame, I construct my "hitbox" outline using raycasts, using the mouse position to calculate what their position is supposed to be, and then force_raycast_update() for each of them. This gets me same-frame "rotation", by not actually rotating, but completely constructing a new pseudo shape.

If there's a way to do while still using the CollisionShapes, I'm still interested in how that'd be done, but the raycasts gets the job done.

by (436 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.