Arrow rotation and launch position around launcherObject

Godot Version

4.4

Question

Hello there! I need to configure correctly my arrow rotation on launch start and it’s position.

What i want as img…

What i get…

Current arrow script:

But it works terribly, as if I’m retarded and wrote shitty code…

Thanks for any help!

P.S. radius can be increased for not colliding with character hitbox collision or I can add another special layer? jeez don’t know…

your constant linear velocity should be a vector from your spawn position to your destination position ( = destPos - spawnPos).
I think that’s your problem

1 Like

Unfortunately no, but your answer made me think about my own mediocrity, which in turn led me to a geometry textbook and “this” was born:

func getPointInsideCircleRadiusFromDirection(centerX: float, centerY: float, radius: float, direction: Vector2) -> Vector2:
	return Vector2(centerX + radius * cos(direction.angle()), centerY + radius * sin(direction.angle()))

function return Vector2 from a given centrerX/Y/Radius of circle and direction (like a mouse click)

Thanks for the good kick to get me going - to study basic math. :grinning:

P.S> it’s about angle from radius circle

But dont udnerstand why this happens:

Feels like center of circle and his global position is moving. It happens when we start moving.



Normalized vectors are your friend here. If you haven’t run into them, a normalized vector is a vector whose total length is 1.0. Godot has functions to produce them. Once you have a normalized vector, you can do all sorts of things with it.

You can get a normalized vector from a position to a target:

var norm_vec = (target - position).normalized()

You can scale that by the speed of the arrow:

var arrow_vec = norm_vec * ARROW_SPEED

You can determine the angle the arrow should be facing:

var angle = norm_vec.angle()

My suspicion is that your “shoots itself” problem looks like you’re pulling the launch position from the animation, and the animation may be lagging. I think you probably want to drive the animation off the shooting, not the reverse.

You could use your normalized vector multiplied by a fixed radius to choose the launch position:

launch_pos = norm_vec * LAUNCH_RADIUS

Thank you for your answer! I think I have a poor understanding of what I wrote.

How I imagined the shot:

  1. When the mouse clicks on any part of the viewport, unhandled_input is called, which stores the click coordinates via get_global_mouse_poistion
  2. An Arrow object is created, into which the mouse click coordinates are passed
  3. _ready() for Arrow, having received the mouse coordinates, sets the starting position (global_position) and calculates global_rotation
  4. Then hitTimer starts, which in my case starts the attackDelay process, during which the animation is played
  5. When the timer ends, the previously created Arrow is sent to add_child of the player’s parent (i.e. the map/level).
  6. the arrow with the calculated linear_velocity flies to the previously stored mouse click coordinates - profit

But I get some kind of nonsense)))

The problem I don’t understand is not hitting myself, but shifting everything that is on the x coordinate plus or minus depending on where the shooter is now. Next - the center of the circle will be the end point of my collision-radius of the arrow or to the right. If the current x coordinates of the shooter > 0, then the center point of the circle (aka the spawn position of the arrow) will shift to the right, if x < 0 then the shift will be to the left. If the x coordinate == 0 then everything works as I would like ;D.

I think this code which calculate startPos for arrow is wrong.

func getPointInsideCircleRadiusFromDirection(position: Vector2, radius: float, direction: Vector2) -> Vector2:
	var radians: float = direction.angle()
	var cos: float = cos(radians)
	var sin: float = sin(radians)
	var vect: Vector2 = Vector2(position.x + radius * cos, position.y + radius * sin)
	return vect

And I would be very grateful if you could help me with some advice on this piece of code I wrote. :grinning:

Vector2 comming from:

You can simplify that to:

func getPointInsideCircleRadiusFromDirection(pos: Vector2, radius: float, dir: Vector2) -> Vector2:
    return pos + (dir.normalized() * radius)
1 Like

Thanks! Updated it.
P.S. Maybe the problem is in my move_and_collide?

I think the problem might be that you’re creating the arrow, then waiting for the timer, then launching it. If anything changes while the clock is running, your arrow is no longer where it’s supposed to be.

1 Like

Should I then do the creation and arrows during the atkDelay ending? How would you do it?

You could still create them before, but maybe redo the position/direction math at the moment of launch to make sure they’re where they’re supposed to be. If you do that and see them snapping around between creation and launch, that’ll be what’s going on.

1 Like

Now it’s worked. Thank you very much!
This is the second time you’ve saved me. :pray:

1 Like