Projectile behavior issue
-
Not sure what my issue is, I am new to Godot and am having a small issue with a rigidbody2d. I have a player with 2 actions can shoot laser and secondary action is a grenade. The grenade is rigidbody2d and shows a somewhat strange behavior only when shooting either left or right but not up or down. I shall attach a video: https://imgur.com/a/R6Wuw1d
Here is my code:
Grenade scene:
extends RigidBody2D
@export var speed: int = 800
var direction: Vector2 = Vector2.UP
func _process(delta):
position += direction * speed * deltaPlayer scene:
extends CharacterBody2D
signal laser(pos, direction)
signal grenade(pos, direction)var can_laser: bool = true
var can_grenade: bool = true
var speed = 200
var using_controller: bool = falsefunc _process(_delta):# Called every frame. 'delta' is the elapsed time since the previous frame
var controllers = Input.get_connected_joypads()
using_controller = controllers.size() > 0
if using_controller:
# Use joystick input for rotation
rslook()
else:
# Use mouse for rotation
look_at(get_global_mouse_position())var direction = Input.get_vector("left", "right", "up", "down") # Input velocity = direction * 800 # Movement speed move_and_slide() # Built in function for move and slide againts objects if Input.is_action_pressed("main action") and can_laser: # Laser shooting input can_laser = false $"Laser Timer".start() # Starts a reset timer from Laser Timer node to reset laser function var laser_markers = $LaserStartPositions.get_children() # Gets the position of the marker nodes that are children of LaserStartPositions node var selected_laser = laser_markers[randi() % laser_markers.size()] #randomly select marker for the laser to start # emit the position we selected laser.emit(selected_laser.global_position, rotation_degrees) if Input.is_action_pressed("secondary action") and can_grenade: can_grenade = false $"Grenade Timer".start() var pos = $LaserStartPositions.get_children()[0].global_position grenade.emit(pos, rotation_degrees)
var rs_look = Vector2(0,0)
var deadzone = 0.3func _physics_process(_delta):
rslook()func rslook():
rs_look.y = Input.get_joy_axis(0, JOY_AXIS_RIGHT_Y)
rs_look.x = Input.get_joy_axis(0, JOY_AXIS_RIGHT_X)
if rs_look.length() >= deadzone:
rotation = rs_look.angle()
#_____________________________________________________________func _on_grenade_timer_timeout():
can_grenade = truefunc _on_laser_timer_timeout():
can_laser = trueLevel scene:
extends Node2D
var laser_scene: PackedScene = preload("res://scenes/projectiles/laser.tscn")
var grenade_scene: PackedScene = preload("res://scenes/projectiles/grenade.tscn")func _on_gate_player_entered_gate(body):
print("player entered gate")
print(body)func _on_gate_player_exited_gate(body):
print("player exited gate")
print(body)func _on_player_grenade(pos, player_rotation_degrees):
var grenade = grenade_scene.instantiate() as RigidBody2D
var direction = Vector2(1, 0).rotated(deg_to_rad(player_rotation_degrees))
grenade.position = pos
$Projectiles.add_child(grenade)
grenade.linear_velocity = direction * 800func _on_player_laser(pos, player_rotation_degrees):
var laser = laser_scene.instantiate() as Area2D
var direction = Vector2(1, 0).rotated(deg_to_rad(player_rotation_degrees))
laser.rotation_degrees = rad_to_deg(direction.angle())
laser.position = pos
laser.direction = direction
$Projectiles.add_child(laser)Any insight on this would be much appreciated.
-
The video was really helpful.
I watched it in slow motion and I realized that for all of your shots (not just horizontal), your grenade would go upwards just a little bit, then quickly corrects itself to go the right way. So it seems like something in the grenade code is making it go up when it gets made.Sure enough, the direction starts at Vector2.UP, and the _process function makes it move in that direction.
But at the same time, in the "Level" scene you properly set the grenade's "linear_velocity" to its direction right after making it. So my thinking is that it takes a little bit of time to set the linear_velocity so the grenade defaults to going up for a split second.I believe the solution would be to make the starting direction (in Grenade scene) to Vector2.ZERO, that way it doesn't try to move when it gets made.