How to adjust launch angle of projectile

Godot Version

<stable4.2>

Question

<Hello community. As the title says, I would appreciate if you could teach me how to change launch angle of projectile when instantiating, so the projectile will launch upward like 80 degree. Right now with my code, the projectile will be simply launched downward.

func _shoot01():
	var slimeBall01 = slimeball01Scene.instantiate()
	get_parent().add_child(slimeBall01)
	slimeBall01.global_position = $SlimeBallSpawningPoint.global_position
	slimeBall01.transform = $SlimeBallSpawningPoint.global_transform
	slimeBall01.scale *= 1.2
	if direction == -1:
		slimeBall01.velocity = slimeBall01.transform.x * Vector2(-150, -350)
	else:
		slimeBall01.velocity = slimeBall01.transform.x * Vector2(150, -350)

the projectile script:

extends CharacterBody2D

var speed := 120
const gravity = 300
var max_range := 650.0
var _travelled_distance = 0.0
var rotate_speed_degps = 360.0
var direction = Vector2.ZERO

func _init():
	set_as_top_level(true)

func _ready():
	velocity = speed * direction


func _physics_process(delta: float) -> void:

	var distance := speed * delta

	velocity.y += gravity * delta

	#rotate(deg_to_rad(rotate_speed_degps) * delta)

	var collision = move_and_collide(velocity * delta)
	if collision:
		$AnimationPlayer.play("ground")
		velocity = velocity.bounce(collision.get_normal())

		var normalized_velocity_x = velocity.x / abs(velocity.x)
		velocity.x = normalized_velocity_x * speed

		if is_on_wall():  # Check if colliding with a vertical surface (wall)
			velocity.x = abs(speed) * sign(collision.get_normal().x)
			$AnimationPlayer.play("wall")

		if collision.get_normal().y < 0:
			var jump_height = 120
			var jump_force = -sqrt(2 * gravity * jump_height)
			velocity.y = jump_force
			#print("Current jump_height:", jump_height)

	_travelled_distance += distance
	if _travelled_distance > max_range:
		queue_free()

Hey i do not know that the direction variable does but after instantiating the slimeball u can just rotate it by any value and apply a initial velocity. using transform.y gives us its rotated vector so initial velocity is 80 degrees from the ground

func _shoot01():
	var slimeBall01 = slimeball01Scene.instantiate()
	get_parent().add_child(slimeBall01)
	slimeBall01.global_position = $SlimeBallSpawningPoint.global_position
	slimeBall01.transform = $SlimeBallSpawningPoint.global_transform
	slimeBall01.scale *= 1.2
	
	slimeBall01.rotate(deg_to_rad(10)) ### rotate it by 10 degrees so relative to ground its 80 degrees
	slimeBall01.velocity = transform.y * -100  ### u can use any value instead of 100 but it needs to be negative in order for it to go up
	
	if direction == -1:
		slimeBall01.velocity = slimeBall01.transform.x * Vector2(-150, -350)
	else:
		slimeBall01.velocity = slimeBall01.transform.x * Vector2(150, -350)

hope this helps.

1 Like

Thank you for an answer. This worked perfectly, however adding rotation will screw the projectile animation (will shrink if collided to floor). is there any other way to launch upward instead of adding rotation?

alr so this might be a bit wacky solution

func _shoot01():
	var slimeBall01 = slimeball01Scene.instantiate()
	get_parent().add_child(slimeBall01)
	slimeBall01.global_position = $SlimeBallSpawningPoint.global_position
	slimeBall01.transform = $SlimeBallSpawningPoint.global_transform
	slimeBall01.scale *= 1.2
	
	slimeBall01.rotate(deg_to_rad(10)) ### rotate it by 10 degrees so relative to ground its 80 degrees
	slimeBall01.velocity = transform.y * -100  ### u can use any value instead of 100 but it needs to be negative in order for it to go up
    slimeBall01.rotate(deg_to_rad(-10)) #### this would fix the oriantion back
	
	if direction == -1:
		slimeBall01.velocity = slimeBall01.transform.x * Vector2(-150, -350)
	else:
		slimeBall01.velocity = slimeBall01.transform.x * Vector2(150, -350)

there is probably a better solution but i believe this would also work