How to tween Linear Velocity in rigidbody2d godot - godot

trying this code but it moves object diagonally(down-right)
func _ready():
tween = get_node("Tween")
pass
func _physics_process(_delta):
tween.interpolate_property(self,"linear_velocity",null,Vector2(0,0.1),1,Tween.TRANS_LINEAR,Tween.EASE_IN_OUT)
tween.start()
pass```

It's hard to figure out what you are trying to accomplish and with which types of Node, however you can try something like this:
var TARGET_VELOCITY = Vector2(0,0.1)
var LERP_SPEED = 1
func _physics_process(_delta):
var newVelocity = self.linear_velocity.linear_interpolate(TARGET_VELOCITY , delta * LERP_SPEED)
self.linear_velocity = newVelocity
From the interpolation tutorial:
https://docs.godotengine.org/en/stable/tutorials/math/interpolation.html

Related

I tried to shoot an object towards cursor position, but it has a problem

I'm a beginner in Godot I want to shoot an object that is already in the game towards where the cursor's position is, and the method I created for it works fine but depending on the distance between the object and the cursor the speed changes. can anyone please help me make the speed constant?
I used this:
func _process(_delta):
if Input.is_action_just_released("tap"):
var mousepos = get_viewport().get_mouse_position()
var ballpos = self.get_position()
var x = mousepos.x - ballpos.x
var y = mousepos.y - ballpos.y
velocity = Vector2(x,y)
You can normalize your vector, which gives you a vector of unit length:
velocity = Vector2(x,y).normalize()
And then scale it by the speed you want:
velocity = Vector2(x,y).normalize() * speed
Where speed is a previously defined variable or constant. Something like this will do:
var speed := 100.0
You, of course, will want to tweak the value. So perhaps you want to export it so you can set it form the inspector:
export var speed := 100.0
By the way, you can rewrite the code you have to this:
var mousepos = get_viewport().get_mouse_position()
var ballpos = self.get_position()
velocity = mousepos - ballpos
Adding the changes suggested above we have:
var mousepos = get_viewport().get_mouse_position()
var ballpos = self.get_position()
velocity = (mousepos - ballpos).normalize() * speed
Which you can rewrite to this:
var mousepos = get_viewport().get_mouse_position()
var ballpos = self.get_position()
velocity = ballpos.direction_to(mousepos) * speed

Player not looking in the right direction

I have a player that you can move by clicking in a location. They are guided by pathfinding to also move around any potential obstacles in their way. Here is my script:
extends KinematicBody2D
export var speed = 200
var velocity = Vector2.ZERO
onready var navigation_agent = $NavigationAgent2D
func _ready():
navigation_agent.connect("velocity_computed", self, "move")
func _input(event):
if event.is_action_pressed("mouse_right"):
navigation_agent.set_target_location(event.get_global_position())
func _process(_delta):
if $RayCast2D.is_colliding():
if $RayCast2D.get_collider().is_in_group("enemy_ground_troop"):
self.velocity = Vector2.ZERO
ranged_attack()
if navigation_agent.is_navigation_finished():
return
var overlapping_areas = $EnemyDetector.get_overlapping_areas()
for area in overlapping_areas:
if area.is_in_group("enemy_ground_troop"):
navigation_agent.set_target_location(area.get_global_position())
look_at(area.get_global_position())
velocity = global_position.direction_to(navigation_agent.get_next_location()) * speed
look_at(global_position.direction_to(navigation_agent.get_next_location()))
$RayCast2D.global_rotation = self.global_rotation
navigation_agent.set_velocity(velocity)
func move(velocity):
velocity = move_and_slide(velocity)
func ranged_attack():
print_debug("fired ranged attack")
When I run the scene, the player is not looking where I want them too based on the look at commands. How can I fix this?
The look_at method takes a target position, not a direction.
So, instead of this:
look_at(global_position.direction_to(navigation_agent.get_next_location()))
Try this:
look_at(navigation_agent.get_next_location())

Raycast2D end not detecting collision

I have a Raycast2D where I want to detect collision with the enemy, but it does not collide at the end. What I'm saying is that it only detects collision at the place where it originates. Here is my code:
extends KinematicBody2D
export var speed = 200
var velocity = Vector2.ZERO
var enemy = 0
onready var navigation_agent = $NavigationAgent2D
onready var bullet = preload("res://Bullet.tscn").instance()
func _ready():
navigation_agent.connect("velocity_computed", self, "move")
$RayCast2D.global_rotation = self.global_rotation - 90
func _input(event):
if event.is_action_pressed("mouse_right"):
navigation_agent.set_target_location(event.get_global_position())
func _process(_delta):
if $RayCast2D.is_colliding():
if $RayCast2D.get_collider().is_in_group("enemy_ground_troop"):
enemy = $RayCast2D.get_collider()
velocity = Vector2.ZERO
ranged_attack()
if navigation_agent.is_navigation_finished():
return
velocity = global_position.direction_to(navigation_agent.get_next_location()) * speed
look_at(navigation_agent.get_next_location())
navigation_agent.set_velocity(velocity)
func move(velocity):
velocity = move_and_slide(velocity)
func ranged_attack():
add_child(bullet)
bullet.global_position = self.global_position
bullet.target = enemy.global_position
Could someone help me fix this?
are you debugging the physics collisions during runtime? you should be able to see if the line is intersecting or not.
look under Debug > Visible Collision Shapes
also try
$RayCast2D.force_raycast_update() inside of _process and see if that makes some difference.
Are you sure the raycast is enabled under the inspector?

Kinematic Body 2D not moving

I'm trying to game a game using the Godot Engine but I'm stuck at the beginning! I can't make my KinematicBody2D move!
This is my Player.GD script
extends KinematicBody2D
var velocity = Vector2.ZERO
var move_speed = 480
var gravity = 1200
var jump_force = -720
var right = Input.is_action_pressed("move_right")
var left = Input.is_action_pressed("move_left")
var jump = Input.is_action_pressed("jump")
func _ready():
pass
func _physics_process(_delta):
var move_direction = int(right) - int(left)
velocity.x = move_speed * move_direction
move_and_collide(velocity)
Can someone, please, help me?
All this code will run when the KinematicBody2D is initialized:
var velocity = Vector2.ZERO
var move_speed = 480
var gravity = 1200
var jump_force = -720
var right = Input.is_action_pressed("move_right")
var left = Input.is_action_pressed("move_left")
var jump = Input.is_action_pressed("jump")
In consequence, it will not be taking input in real time. Instead you want the last three lines here:
func _physics_process(_delta):
var right = Input.is_action_pressed("move_right")
var left = Input.is_action_pressed("move_left")
var jump = Input.is_action_pressed("jump")
# …
Those are boolean, by the way. You can get a float from 0.0 to 1.0 if you use Input.get_action_strength instead. Which will also let your code ready for analog input.
I also want to point out that move_and_collide does not take a velocity, but a displacement vector. So to call it correctly, you want to multiply the velocity by delta:
func _physics_process(delta):
# …
move_and_collide(velocity * delta)
Or use move_and_slide, which does take a velocity. By the way, the up parameter that move_and_slide takes is to discern between floor, ceiling, and walls. Without, everything is considered a wall.

my get_viewport().get_mouse_position() isn't working right godot GDscript

I'm trying to make a 2d platformer where you spawn an object and try to jump on it in the air before it falls.
the problem is when I try to spawn the tile it doesn't spawn where Is the cursor at
it adds a relative value to the position that I don't know how to get rid of it.
you see when I try to instance a scene it takes the cursor position and viewport value into account but then something happens and I fount the object spawning way too far.
see where is the cursor at and where did the tile spawn
, same thing here
, and here
-here is how I'm grouping the nodes and scenes-
and this is the script I'm using, it's in the player1 scene
extends KinematicBody2D
#
var score : int = 0
export var speed : int = 200
export var jumpforce : int = 600
export var gravity : int = 800
onready var AB1 = preload("res://player1AB.tscn")
var vel :Vector2 = Vector2()
onready var sprite : Sprite = get_node("sprite_idile")
onready var ui : Node = get_node("/root/mainscene1/CanvasLayer/ui")
onready var audioplayer : Node = get_node("/root/mainscene1/Camera2D/audio_player")
func _physics_process(delta):
vel.x = 0
# movement inputs
if Input.is_action_pressed("move_left"):
vel.x -= speed
if Input.is_action_pressed("move_right"):
vel.x += speed
# applying the velcoty
vel = move_and_slide(vel,Vector2.UP)
#apllying gravty
vel.y += gravity * delta
#jump input
if Input.is_action_just_pressed("jump") and is_on_floor():
vel.y -= jumpforce
# where the sprite facing
if vel.x < 0:
sprite.flip_h = true
if vel.x > 0:
sprite.flip_h = false
if Input.is_action_just_pressed("restart"):
death()
func death ():
get_tree().reload_current_scene()
func collect_coin (value):
score += value
ui.set_score_text(score)
audioplayer.play_coin_sfx()
func _input(event):
if event.is_action_pressed("click"):
var ABT1 = AB1.instance()
add_child(ABT1)
var XN = null
XN = get_viewport().get_mouse_position()
ABT1.position = XN
important stuff
onready var AB1 = preload("res://player1AB.tscn")
func _input(event):
if event.is_action_pressed("click"):
var ABT1 = AB1.instance()
add_child(ABT1)
var XN = null
XN = get_viewport().get_mouse_position()
ABT1.position = XN
this the same problem in Godot form check it out if possible in case someone answered there
https://godotforums.org/discussion/27007/my-get-viewport-get-mouse-position-isnt-working-right#latest
If you don't have an extra Viewport
My first intuition is to get get_global_mouse_position and set global_position. That way you don't have to deal with any relative positioning:
ABT1.global_position = get_global_mouse_position()
Alternatively, you can check if the event is InputEventMouse, make it local with make_input_local, and get InputEventMouse.position from it:
func _input(event):
if event is InputEventMouse and event.is_action_pressed("click"):
var ABT1 = AB1.instance()
add_child(ABT1)
event = make_input_local(event)
ABT1.position = event.position
This approach would make it easier to then add touch support, because it does not rely on any function that gives you the mouse position. See my answer for Holding screen touch in godot.
If you have an extra Viewport
First of all, make sure you put your Viewport inside a ViewportContainer (otherwise it does not get input, see _input not called for a node inside a Viewport). Then we can use that ViewportContainer to get our coordinates.
Something like this:
func _input(event):
if event is InputEventMouse and event.is_action_pressed("click"):
var ABT1 = AB1.instance()
add_child(ABT1)
var container = find_parent("ViewportContainer") as ViewportContainer
if container != null:
event = container.make_input_local(event)
event = make_input_local(event)
ABT1.position = event.position
Notice there I'm using the function find_parent. It matches by name of the Node, not by type. Another approach you can try is using get_viewport().get_parent().
And yes, that should work regardless of stretch mode.

Resources