KinematicBody won't move along z-axis (Godot) - godot

I'm beginning a new project and just started coding the movement script. I'm using the same old method I use every time but for some reason I cant move forward and backwards(z-axis). This is odd because left and right (x-axis) uses functionally identical code and works fine. Here's my code:
func _physics_process(delta):
velocity += gravity * delta
_get_input()
velocity = move_and_slide(velocity, Vector3.UP)
func _get_input():
var vy = velocity.y
var dir = Vector3()
velocity = Vector3()
if Input.is_action_pressed("forward"):
dir += -transform.basis.z * speed
if Input.is_action_pressed("back"):
dir += transform.basis.z * speed
if Input.is_action_pressed("left"):
dir += -transform.basis.x * speed
if Input.is_action_pressed("right"):
dir += transform.basis.x * speed
velocity.y = vy
velocity.x = dir.x
velocity.z = dir.z
What is wrong?

Here is an alternative approach based on the following assumptions:
Gravity direction is global.
The KinematicBody can be oriented freely.
The controls follow that orientation.
The speed is global (this would only matter if the physics body is scaled, and you should avoid scaling physic bodies anyway).
We start by building a local direction vector:
var local_direction:Vector3
if Input.is_action_pressed("forward"):
local_direction += Vector3.FORWARD
if Input.is_action_pressed("back"):
local_direction += Vector3.BACK
if Input.is_action_pressed("left"):
local_direction += Vector3.LEFT
if Input.is_action_pressed("right"):
local_direction += Vector3.RIGHT
In fact, we can do that better than that:
var local_direction := Vector3(
Input.get_action_strength("right") - Input.get_action_strength("left"),
0.0,
Input.get_action_strength("back") - Input.get_action_strength("forward")
)
Then we transform it with the global basis:
var direction := global_transform.basis.xform(local_direction).normalize()
Then we can get rid of the y component:
direction.y = 0.0
And scale it, so it is a velocity:
velocity = direction * speed
And, of course, you would set the y component of the velocity we have, because the gravity computation handles care of that:
var v_velocity := velocity.y
velocity = direction * speed
velocity.y = v_velocity
All toghether:
var local_direction := Vector3(
Input.get_action_strength("right") - Input.get_action_strength("left"),
0.0,
Input.get_action_strength("back") - Input.get_action_strength("forward")
)
var direction := global_transform.basis.xform(local_direction)
direction.y = 0.0
var v_velocity := velocity.y
velocity = direction * speed
velocity.y = v_velocity

Related

Can jump a kinematic body from a rigidbody in godot?

I found this code to push a rigidbody with a kinematic body in godot:
for index in get_slide_count():
var collision = get_slide_collision(index)
if collision.collider.is_in_group("bodies"):
collision.collider.apply_central_impulse(-collision.normal * push)
This code works but when the player stand on rigidbody can't jump!!
P.S. I have set the infinite_inertia to false. All code is this:
extends KinematicBody2D
onready var animation = $AnimationPlayer
export (int, 0, 200) var push = 30
var velocity :=Vector2.ZERO
var gravity := 30
var speed := 50
var jumpforce = 300
func _physics_process(delta) -> void:
#Push()
if Input.is_action_pressed("right"):
$Sprite.flip_h=false
velocity.x += speed
animation.play("Walk")
elif Input.is_action_pressed("left"):
$Sprite.flip_h=true
velocity.x -= speed
animation.play("Walk")
else:
animation.play("Idle")
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y =- jumpforce
animation.play("Idle")
velocity.y += gravity
Push()
velocity=move_and_slide(velocity,Vector2.UP, false, 4, PI/4, false)
velocity.x= lerp(velocity.x,0,0.2)
func Push():
for index in get_slide_count():
var collision = get_slide_collision(index)
if collision.collider.is_in_group("bodies"):
collision.collider.apply_central_impulse(-collision.normal * push)
I found the solution to this problem!!! I set the rigitbody 's mass property from editor to 2 instead 1 . Is working now :)

Why i cant place is_on_floor here

Basicly this is my first time using godot and writing code int it and i dont have any past expirience so i wanna says sorry in advance if the problem sounds very stupid.My movment is almost compleated and i have one last probelem that was if there is any way to make the engine knows when i colide with the ground i searched up a bit and i found the is_on_floor method but when i tyed to use it it gave me this eror(18,41) misplaced and but evrything seems fine to me please help if you can and also here is the code if it will be useful to find the problem.
extends KinematicBody2D
var velocity = Vector2(0,0)
const wspeed = 195
const GRAVITY = 30
var JUMPHIGHT = -600
func _physics_process(idle):
velocity.y = velocity.y + GRAVITY
if Input.is_action_pressed("right"):
velocity.x = wspeed
if Input.is_action_pressed("left"):
velocity.x = -wspeed
velocity.y = velocity.y + GRAVITY
if Input.is_action_just_pressed("up"): and is_on_floor():
velocity.y = JUMPHIGHT
move_and_slide(velocity,Vector2.UP)
The answer is simple. You have put : before and is_on_floor(). Also i want to change a little bit your code to be more efficient
extends KinematicBody2D
var velocity = Vector2(0,0)
const wspeed = 195
const GRAVITY = 30
var JUMPHIGHT = -600
func _physics_process(_delta):
if Input.is_action_pressed("right"):
velocity.x += wspeed
if Input.is_action_pressed("left"):
velocity.x =-wspeed
if Input.is_action_just_pressed("up") and is_on_floor():
velocity.y = JUMPHIGHT
velocity.y = velocity.y + GRAVITY
move_and_slide(velocity,Vector2.UP)

Godot Slowing down Area2d objects

I'm making a prototype for my 2d top-down space game and I'm using area2d for my *ship object since most of its mechanics rely only in collisions. Is there a way i can slow down then stop my ship after it is launched, because as for now it just fly continuously.
Here is my basic code:
var jump_speed = 500
var velocity = Vector2()
func get_input(delta):
if Input.is_action_pressed("click"):
look_at(get_global_mouse_position())
if Input.is_action_just_released("click"):
velocity = transform.x * jump_speed
func _physics_process(delta):
get_input(delta)
position -= velocity * delta```
In general the idea is to reduce the length of the velocity vector over time. We could define a deceleration for that (this is not the only way to go about it):
var deceleration := 10.0
And then in _physics_process we can compute by how much the velocity would be reduced:
var speed_reduction := deceleration * delta
Compare it with the magnitud of velocity, if it is more, just set the velocity to Vector2.ZERO otherwise we want to scale velocity appropriately:
var current_speed := velocity.length()
if current_speed > speed_reduction:
velocity = Vector2.ZERO
else:
velocity = velocity * (current_speed - speed_reduction) / current_speed
By the way, from Godot 3.5 onward there is a limit_length method in Vector2 and Vector3 that can make this simpler to implement.

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.

How To Make KinematicBody2D Move By Drag in One Direction in GDScript?

I wanted to create a game similar to this (Slyway), but I had a problem with the child's movement, so I don't know what to use to do the movement during the draw. Is InputEventScreenTouch Or InputEventScreenDrag, all I come up with is this code that isn't working
extends KinematicBody2D
var velocity = Vector2.ZERO
var direction = Vector2.ZERO
var speed = 200
func input(event):
if event is InputEventScreenTouch:
if event.ispressed():
direction.x -= 1
func physicsprocess(delta):
if velocity.length() == 0:
_input(event)
velocity = Vector2.ZERO
velocity += direction * speed
velocity = moveand_slide (velocity)

Resources