I'm having a hard time wrapping my brain around how to code shooting an arrow with an arc. There have been plenty of tutorials for how to do this in 2d, but I haven't found one that explains for 3d and I can't figure out how to translate between the two in this case.

I have the attacker and the target's translations. My current version uses moveandcollide

The attacker instances a kinematic arrow (don't know which physics body to use) and should pass it the initial angle. The arrow has an initial force(?) or velocity vector.

I can't figure out how to calculate the initial angle in 3d. Including the possibility of differing heights.
I also know that there should be 2 possible angles as well. I'd also like the arrow to point in the direction of travel, which again is a 3d angle I can't figure out.

This is my first 3d project using physics so I'm pretty much in the dark on this one and frustrated that this shouldn't be terribly difficult math. It's just that I've forgotten it all.

Any assistance would be greatly appreciated.

Godot version 3.3.2
in Engine

Alright, so I figured it out. First, terminology is important. I should have been searching for Projectile motion. Secondly, having an understanding of transforms was what I lacked.

I'm going to post the code I cobbled together to make it work for anyone else who runs into the same problem.

``````extends KinematicBody

# force is the forward movement of the projectile
export var force = 20.0
export var g = Vector3.DOWN * 9.8
# t was just to keep track of time
var t = 0
# speed is just to make things move faster
export var speed = 1

var velocity = Vector3()

# init_xy is the initial upward angle while init_xz is the angle pointing toward the target.
var init_xy = 0
var init_xz = 0

# I initialized the angles beforehand in a different scene so all I had to do was
# add the arrow to the tree for it to shoot.
rotate_x(init_xy)
rotate_y(init_xz)
velocity += -transform.basis.z * force

# Just to keep time and free the arrow after a bit.
func _process(delta):
if t > 10:
queue_free()
t += delta

func _physics_process(delta):