How to make player rotate smoothly - godot

Below is my entire player script (sorry if it is messy) and it would be really helpful if you could tell me why the rotation isn't working. I want the player to turn smoothly when the player presses a key. Thanks so much!
extends KinematicBody
var moveSpeed : float = 5.0
var jumpForce : float = 10.0
var gravity : float = 20
var vel : Vector3 = Vector3()
const _angular_speed:float = TAU
func _physics_process(delta):
vel.x = 0
vel.z = 0
var turn_input := Vector2(
Input.get_action_strength("move_left") - Input.get_action_strength("move_right"),
Input.get_action_strength("move_forward") - Input.get_action_strength("move_backward")
)
var movement = Vector3()
var input_angle := turn_input.angle()
var _target_angle:float
var angle_diff := wrapf(_target_angle - rotation.y, -PI, PI)
rotation.y += clamp(delta * _angular_speed, 0, abs(angle_diff)) * sign(angle_diff)
if Input.is_action_pressed("move_forward") and Input.is_action_pressed("move_left"):
movement[2] = 1
movement[0] = 1
elif Input.is_action_pressed("move_forward") and Input.is_action_pressed("move_right"):
movement[2] = 1
movement[0] = -1
elif Input.is_action_pressed("move_backward") and Input.is_action_pressed("move_left"):
movement[2] = -1
movement[0] = 1
elif Input.is_action_pressed("move_backward") and Input.is_action_pressed("move_right"):
movement[2] = -1
movement[0] = -1
else:
if Input.is_action_pressed("move_forward"):
movement[2] = 1
if Input.is_action_pressed("move_backward"):
movement[2] = -1
if Input.is_action_pressed("move_left"):
movement[0] = 1
if Input.is_action_pressed("move_right"):
movement[0] = -1
movement = movement.normalized()
global_transform[3] += movement/7
vel.y -= gravity * delta
if Input.is_action_pressed("jump") and is_on_floor():
vel.y = jumpForce
vel = move_and_slide(vel, Vector3.UP)
Edit: This question has now been answered.

You are doing some odd mix of things here.
Unused input_angle
First, of all, just copying the over to Godot. I get a warning that input_angle is not used. And after a quick look, _target_angle right next is never assigned:
var input_angle := turn_input.angle()
var _target_angle:float
That is an easy fix. Just keep _target_angle:
var _target_angle := turn_input.angle()
Clean up
Second, not really a problem, but movement is this:
var movement := Vector3(turn_input.x, 0.0, turn_input.y).normalized()
With that, you see all this code:
if Input.is_action_pressed("move_forward") and Input.is_action_pressed("move_left"):
movement[2] = 1
movement[0] = 1
elif Input.is_action_pressed("move_forward") and Input.is_action_pressed("move_right"):
movement[2] = 1
movement[0] = -1
elif Input.is_action_pressed("move_backward") and Input.is_action_pressed("move_left"):
movement[2] = -1
movement[0] = 1
elif Input.is_action_pressed("move_backward") and Input.is_action_pressed("move_right"):
movement[2] = -1
movement[0] = -1
else:
if Input.is_action_pressed("move_forward"):
movement[2] = 1
if Input.is_action_pressed("move_backward"):
movement[2] = -1
if Input.is_action_pressed("move_left"):
movement[0] = 1
if Input.is_action_pressed("move_right"):
movement[0] = -1
movement = movement.normalized()
Delete it. Gone. Just keep the one liner above. It should do the same thing. It should do the same thing, with the weird behavior and all, but it is easier to see the code now.
The code looks like this now:
extends KinematicBody
var moveSpeed : float = 5.0
var jumpForce : float = 10.0
var gravity : float = 20
var vel : Vector3 = Vector3()
const _angular_speed:float = TAU
func _physics_process(delta):
vel.x = 0
vel.z = 0
var turn_input := Vector2(
Input.get_action_strength("move_left") - Input.get_action_strength("move_right"),
Input.get_action_strength("move_forward") - Input.get_action_strength("move_backward")
)
var _target_angle := turn_input.angle()
var angle_diff := wrapf(_target_angle - rotation.y, -PI, PI)
rotation.y += clamp(delta * _angular_speed, 0, abs(angle_diff)) * sign(angle_diff)
var movement := Vector3(turn_input.x, 0.0, turn_input.y).normalized()
global_transform[3] += movement/7
vel.y -= gravity * delta
if Input.is_action_pressed("jump") and is_on_floor():
vel.y = jumpForce
vel = move_and_slide(vel, Vector3.UP)
What the movement?
Look at this line:
global_transform[3] += movement/7
What the Hell, Michigan?
That line is equivalent to this:
global_transform.origin += movement * 1/7
Notice this is motion, and it is not using delta. I will come back to that.
Rotation resetting
We need to promote _target_angle to a field, and only set it when there is some input. I also did clean the field further. The code now looks like this:
extends KinematicBody
const _angular_speed:float = TAU
var moveSpeed := 5.0
var jumpForce := 10.0
var gravity := 20
var vel := Vector3()
var _target_angle:float
func _physics_process(delta):
vel.x = 0
vel.z = 0
var turn_input := Vector2(
Input.get_action_strength("move_left") - Input.get_action_strength("move_right"),
Input.get_action_strength("move_forward") - Input.get_action_strength("move_backward")
)
if turn_input.length_squared() > 0:
_target_angle = turn_input.angle()
var angle_diff := wrapf(_target_angle - rotation.y, -PI, PI)
rotation.y += clamp(delta * _angular_speed, 0, abs(angle_diff)) * sign(angle_diff)
var movement := Vector3(turn_input.x, 0.0, turn_input.y).normalized()
global_transform[3] += movement/7
vel.y -= gravity * delta
if Input.is_action_pressed("jump") and is_on_floor():
vel.y = jumpForce
vel = move_and_slide(vel, Vector3.UP)
As you can see I declare target_angle at the start, so it is not a local variable. That way, it keeps its value. Also I do this:
if turn_input.length_squared() > 0:
_target_angle = turn_input.angle()
That way, only when turn_input is not empty, it sets _target_angle.
Wrong direction
It seems to be moving in the opposite direction it should. I'm not sure if this is intentional or not, given that I kept the order you had.
Anyway, fixing it is a matter of flipping the input:
var turn_input := Vector2(
Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
Input.get_action_strength("move_backward") - Input.get_action_strength("move_forward")
)
This makes sense given that x grows to the right, and - actually - forward in Godot is negative z (here stored in the y).
Wrong orientation
The rotation of the character seems to be off by a quarter turn. This solves it:
_target_angle = 0.75 * TAU - turn_input.angle()
Actually it makes sense given that turn_input.angle() would be measured from the x axis, but 0 rotation is looking down the z axis. I did overlook that.
Motion again
Instead of changing the origin of the transform (by snaky means, no less), use move_and_slide, which you are already using. Thus, we are not going to have movement, instead we are going to write to vel. To ease doing that, I decided to normalize turn_input so we can use it directly to compute vel. And while we are at it, let us use the moveSpeed field you have. Which is very small by the way.
This is the final code:
extends KinematicBody
const _angular_speed:float = TAU
var moveSpeed := 500.0
var jumpForce := 10.0
var gravity := 20
var vel := Vector3()
var _target_angle:float
func _physics_process(delta:float) -> void:
# Input
var turn_input := Vector2(
Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
Input.get_action_strength("move_backward") - Input.get_action_strength("move_forward")
).normalized()
# Rotation
if turn_input.length_squared() > 0:
_target_angle = 0.75 * TAU - turn_input.angle()
var angle_diff := wrapf(_target_angle - rotation.y, -PI, PI)
rotation.y += clamp(delta * _angular_speed, 0, abs(angle_diff)) * sign(angle_diff)
# Velocity
vel.x = turn_input.x * moveSpeed * delta
vel.z = turn_input.y * moveSpeed * delta
vel.y -= gravity * delta
if Input.is_action_pressed("jump") and is_on_floor():
vel.y = jumpForce
# Motion
vel = move_and_slide(vel, Vector3.UP)

Related

Invalid set index z with value of type float in gdscript

im making my first 3d game for a jam and i was writing some code about the player state machine, it was all working, but when i put this code in the state_run(delta) func, it crashes:
if playerIsMoving == false:
initialize_idle()
it gives me the error invalid set intex z (base int) with value type of float.
Code:
extends KinematicBody
var sensitivity = 0.06
var speed = 10
var h_aceleration = 6
var gravity = 20
var direction = Vector3()
var h_velocity = Vector3()
var movement = Vector3()
var grav_vec = Vector3()
onready var head = $Head
enum STATES { IDLE, RUN, ATTACK, DEAD}
var state_cur : int
var state_nxt : int
var test = Vector3.ZERO
var playerIsMoving = false
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
state_nxt = STATES.IDLE
func _input(event):
if event is InputEventMouseMotion:
rotate_y(deg2rad(-event.relative.x * sensitivity))
head.rotate_x(deg2rad(-event.relative.y * sensitivity))
head.rotation.x = clamp(head.rotation.x, deg2rad(-89), deg2rad(89))
func _physics_process(delta):
if state_nxt != state_cur:
state_cur = state_nxt
match state_cur:
STATES.IDLE:
state_idle(delta)
STATES.RUN:
state_run(delta)
STATES.ATTACK:
pass
STATES.DEAD:
pass
print(state_cur)
if Input.is_action_pressed("forward") or Input.is_action_pressed("backwards") or Input.is_action_pressed("left") or Input.is_action_pressed("right"):
playerIsMoving = true
else:
playerIsMoving = false
if not is_on_floor():
grav_vec += Vector3.DOWN * gravity * delta
else:
grav_vec = -get_floor_normal() * gravity
func initialize_idle():
state_nxt = STATES.IDLE
movement = 0
func state_idle(delta):
if Input.is_action_pressed("left") or Input.is_action_pressed("right") or Input.is_action_pressed("forward") or Input.is_action_pressed("backwards"):
initialize_run()
func initialize_run():
state_nxt = STATES.RUN
pass
func state_run(delta):
direction = Vector3()
if Input.is_action_pressed("forward"):
direction -= transform.basis.z
elif Input.is_action_pressed("backwards"):
direction += transform.basis.z
elif Input.is_action_pressed("left"):
direction -= transform.basis.x
elif Input.is_action_pressed("right"):
direction += transform.basis.x
else:
playerIsMoving = false
direction = direction.normalized()
h_velocity = h_velocity.linear_interpolate(direction * speed, h_aceleration * delta)
movement.z = h_velocity.z + grav_vec.z
movement.x = h_velocity.x + grav_vec.x
movement.y = grav_vec.y
move_and_slide(movement, Vector3.UP)
if playerIsMoving == false:
initialize_idle()
I alredy tried to round the value or use the int() but it isnt working, the code is giving error on the "movement.z = h_velocity.z + grav_vec.z"
Types.
Look, movement is a Variant, initialized to a Vector3:
var movement = Vector3()
And here you use it as a Vector3:
movement.z = h_velocity.z + grav_vec.z
movement.x = h_velocity.x + grav_vec.x
movement.y = grav_vec.y
move_and_slide(movement, Vector3.UP)
But here 0 is an int not a Vector3:
movement = 0
So after that movement... Continues to be a Variant, but now it has an int value. So when you use it as a Vector3 it fails. Because an int does not have x, y, z.
You can declare movement to be a Vector3 explicitly:
var movement:Vector3 = Vector3()
Or implicitly (inferred from the value you assigned):
var movement:= Vector3()
And then Godot will tell you that this line:
movement = 0
Is an error, because you are trying to set an int to a Vector3.
My guess is that you want to set movement to the zero vector, which is like this:
movement = Vector3(0.0, 0.0, 0.0)
Or like this:
movement = Vector3.ZERO
Or - similarly to how you initialized it - like this:
movement = Vector3()

Why i am not able to make a projectile weapon using GDScript in Godot

I want to make a projectile weapon with GDScript but I am getting the error:
the function " _physics _process " already exists in this class (at line 35)
I cannot delete the line of code which has the error as if I do so I will not be able to make my FPS controller character move
here is the the code:
extends KinematicBody
var speed = 9
const ACCEL_DEFAULT = 7
const ACCEL_AIR = 1
onready var accel = ACCEL_DEFAULT
var gravity = 9.8
var jump = 4
var damage = 100
var cam_accel = 40
var mouse_sense = 0.1
var snap
var direction = Vector3()
var velocity = Vector3()
var gravity_vec = Vector3()
var movement = Vector3()
onready var head = $Head
onready var camera = $Head/Camera
onready var bullet = preload("res://player/world/bullet/bullet.tscn")
onready var muzzle = $Head/Gun/Muzzle
func _ready():
#hides the cursor
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _input(event):
if event is InputEventMouseMotion:
rotate_y(deg2rad(-event.relative.x * mouse_sensitivity))
head.rotate_x(deg2rad(-event.relative.y * mouse_sensitivity))
head.rotation.x = clamp(head.rotation.x, deg2rad(-90), deg2rad(90))
func _physics_process(delta):
direction = Vector3()
if Input.is_action_just_pressed("fire"):
if aimcast.is_colliding():
var b = bullet.instance()
muzzle.add_child(b)
b.look_at(aimcast.get_collision_point(), Vector3.UP)
b.shoot = true
func _process(delta):
#camera physics interpolation to reduce physics jitter on high refresh-rate monitors
if Engine.get_frames_per_second() > Engine.iterations_per_second:
camera.set_as_toplevel(true)
camera.global_transform.origin = camera.global_transform.origin.linear_interpolate(head.global_transform.origin, cam_accel * delta)
camera.rotation.y = rotation.y
camera.rotation.x = head.rotation.x
else:
camera.set_as_toplevel(false)
camera.global_transform = head.global_transform
# this is the line of code which is causing the error
(
func _physics_process(delta):
#get keyboard input
direction = Vector3.ZERO
var h_rot = global_transform.basis.get_euler().y
var f_input = Input.get_action_strength("move_backwards") - Input.get_action_strength("move_forward")
var h_input = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
direction = Vector3(h_input, 0, f_input).rotated(Vector3.UP, h_rot).normalized()
#jumping and gravity
if is_on_floor():
snap = -get_floor_normal()
accel = ACCEL_DEFAULT
gravity_vec = Vector3.ZERO
else:
snap = Vector3.DOWN
accel = ACCEL_AIR
gravity_vec += Vector3.DOWN * gravity * delta
if Input.is_action_just_pressed("jump") and is_on_floor():
snap = Vector3.ZERO
gravity_vec = Vector3.UP * jump
#make it move
velocity = velocity.linear_interpolate(direction * speed, accel * delta)
movement = velocity + gravity_vec
move_and_slide_with_snap(movement, snap, Vector3.UP) )
The error:
"_physics_process" already exists in this class
Is telling you that you have _physics_process twice in your script. You can only have one.
This is the first one:
func _physics_process(delta):
direction = Vector3()
if Input.is_action_just_pressed("fire"):
if aimcast.is_colliding():
var b = bullet.instance()
muzzle.add_child(b)
b.look_at(aimcast.get_collision_point(), Vector3.UP)
b.shoot = true
This is the second one:
func _physics_process(delta):
#get keyboard input
direction = Vector3.ZERO
var h_rot = global_transform.basis.get_euler().y
var f_input = Input.get_action_strength("move_backwards") - Input.get_action_strength("move_forward")
var h_input = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
direction = Vector3(h_input, 0, f_input).rotated(Vector3.UP, h_rot).normalized()
#jumping and gravity
if is_on_floor():
snap = -get_floor_normal()
accel = ACCEL_DEFAULT
gravity_vec = Vector3.ZERO
else:
snap = Vector3.DOWN
accel = ACCEL_AIR
gravity_vec += Vector3.DOWN * gravity * delta
if Input.is_action_just_pressed("jump") and is_on_floor():
snap = Vector3.ZERO
gravity_vec = Vector3.UP * jump
#make it move
velocity = velocity.linear_interpolate(direction * speed, accel * delta)
movement = velocity + gravity_vec
move_and_slide_with_snap(movement, snap, Vector3.UP)
I'm guessing you want both. So merge them into a single one with the code from both:
func _physics_process(delta):
direction = Vector3()
if Input.is_action_just_pressed("fire"):
if aimcast.is_colliding():
var b = bullet.instance()
muzzle.add_child(b)
b.look_at(aimcast.get_collision_point(), Vector3.UP)
b.shoot = true
#get keyboard input
direction = Vector3.ZERO
var h_rot = global_transform.basis.get_euler().y
var f_input = Input.get_action_strength("move_backwards") - Input.get_action_strength("move_forward")
var h_input = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
direction = Vector3(h_input, 0, f_input).rotated(Vector3.UP, h_rot).normalized()
#jumping and gravity
if is_on_floor():
snap = -get_floor_normal()
accel = ACCEL_DEFAULT
gravity_vec = Vector3.ZERO
else:
snap = Vector3.DOWN
accel = ACCEL_AIR
gravity_vec += Vector3.DOWN * gravity * delta
if Input.is_action_just_pressed("jump") and is_on_floor():
snap = Vector3.ZERO
gravity_vec = Vector3.UP * jump
#make it move
velocity = velocity.linear_interpolate(direction * speed, accel * delta)
movement = velocity + gravity_vec
move_and_slide_with_snap(movement, snap, Vector3.UP)
That should solve the error at hand. I haven't look deeper into the code for any other possible problems.

Godot player not walking in the direction

So I am new to godot and I was having a problem. The players body doesnt follow the camera when the camera moves When I look around with the camera the players body stays the same e.g. if i use wasd if i turn to the right it would be aswd. the player movement is hard but i got help. if you could help that will be super cool, i am just trying to learn coding. this is hard for me.
p.s sorry for the bad grammar
extends KinematicBody
signal hit
# How fast the player moves in meters per second.
export var speed = 14
# The downward acceleration when in the air, in meters per second squared.
export var fall_acceleration = 50
# Vertical impulse applied to the character upon jumping in meters per second.
export var jump_impulse = 30
# Vertical impulse applied to the character upon bouncing over a mob in meters per second.
export var bounce_impulse = 16
# stats
var curHP : int = 10
var maxHP : int = 10
var ammo : int = 15
var score : int = 0
# cam look
var minLookAngle : float = -90.0
var maxLookAngle : float = 90.0
var lookSensitivity : float = 10.0
# vectors
var vel : Vector3 = Vector3()
var mouseDelta : Vector2 = Vector2()
# components
onready var camera : Camera = get_node("Camera")
onready var muzzle : Spatial = get_node("Camera/Muzzle")
# Emitted when a mob hit the player.
var velocity = Vector3.ZERO
func _physics_process(delta):
var direction = Vector3.ZERO
if Input.is_action_pressed("move_right"):
direction.x += 1
if Input.is_action_pressed("move_left"):
direction.x -= 1
if Input.is_action_pressed("move_back"):
direction.z += 1
if Input.is_action_pressed("move_forward"):
direction.z -= 1
#sprinting
if Input.is_action_pressed("move_sprint"):
speed = 50
if Input.is_action_just_released("move_sprint"):
speed = 14
velocity.x = direction.x * speed
velocity.z = direction.z * speed
# Jumping.
if is_on_floor() and Input.is_action_just_pressed("move_jump"):
velocity.y += jump_impulse
velocity.y -= fall_acceleration * delta
velocity = move_and_slide(velocity, Vector3.UP)
func _ready():
# hide and lock the mouse cursor
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _process(delta):
# rotate the camera along the x axis
camera.rotation_degrees.x -= mouseDelta.y * lookSensitivity * delta
# clamp camera x rotation axis
camera.rotation_degrees.x = clamp(camera.rotation_degrees.x, minLookAngle, maxLookAngle)
# rotate the player along their y-axis
rotation_degrees.y -= mouseDelta.x * lookSensitivity * delta
# reset the mouseDelta vector
mouseDelta = Vector2()
func _input(event):
if event is InputEventMouseMotion:
mouseDelta = event.relative
If you want the movement to be based on the orientation of camera...
Then base the movement:
var direction = Vector3.ZERO
if Input.is_action_pressed("move_right"):
direction.x += 1
if Input.is_action_pressed("move_left"):
direction.x -= 1
if Input.is_action_pressed("move_back"):
direction.z += 1
if Input.is_action_pressed("move_forward"):
direction.z -= 1
On the orientation of the camera.
We will use camera.global_transform.basis. The basis of a transform gives us a set of vectors that are aligned to the axis of the transformed space.
Using camera.transform instead of camera.global_transform will NOT work, because the Camera is a child of the KinematicBody.
Then your code ends up like this:
var direction = Vector3.ZERO
var camera_x = camera.global_transform.basis.x
var camera_z = camera.global_transform.basis.z
if Input.is_action_pressed("move_right"):
direction += camera_x
if Input.is_action_pressed("move_left"):
direction -= camera_x
if Input.is_action_pressed("move_back"):
direction += camera_z
if Input.is_action_pressed("move_forward"):
direction -= camera_z
Complete script on OP request:
extends KinematicBody
#signal hit
# How fast the player moves in meters per second.
export var speed = 14
# The downward acceleration when in the air, in meters per second squared.
export var fall_acceleration = 50
# Vertical impulse applied to the character upon jumping in meters per second.
export var jump_impulse = 30
# Vertical impulse applied to the character upon bouncing over a mob in meters per second.
# export var bounce_impulse = 16
# stats
# var curHP : int = 10
# var maxHP : int = 10
# var ammo : int = 15
# var score : int = 0
# cam look
var minLookAngle : float = -90.0
var maxLookAngle : float = 90.0
var lookSensitivity : float = 10.0
# vectors
# var vel : Vector3 = Vector3()
var mouseDelta : Vector2 = Vector2()
# components
onready var camera : Camera = get_node("Camera")
# onready var muzzle : Spatial = get_node("Camera/Muzzle")
# Emitted when a mob hit the player.
var velocity = Vector3.ZERO
func _physics_process(delta):
var direction = Vector3.ZERO
var camera_x = camera.global_transform.basis.x
var camera_z = camera.global_transform.basis.z
if Input.is_action_pressed("move_right"):
direction += camera_x
if Input.is_action_pressed("move_left"):
direction -= camera_x
if Input.is_action_pressed("move_back"):
direction += camera_z
if Input.is_action_pressed("move_forward"):
direction -= camera_z
#sprinting
if Input.is_action_pressed("move_sprint"):
speed = 50
if Input.is_action_just_released("move_sprint"):
speed = 14
velocity.x = direction.x * speed
velocity.z = direction.z * speed
# Jumping.
if is_on_floor() and Input.is_action_just_pressed("move_jump"):
velocity.y += jump_impulse
velocity.y -= fall_acceleration * delta
velocity = move_and_slide(velocity, Vector3.UP)
func _ready():
# hide and lock the mouse cursor
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _process(delta):
# rotate the camera along the x axis
camera.rotation_degrees.x -= mouseDelta.y * lookSensitivity * delta
# clamp camera x rotation axis
camera.rotation_degrees.x = clamp(camera.rotation_degrees.x, minLookAngle, maxLookAngle)
# rotate the player along their y-axis
rotation_degrees.y -= mouseDelta.x * lookSensitivity * delta
# reset the mouseDelta vector
mouseDelta = Vector2()
func _input(event):
if event is InputEventMouseMotion:
mouseDelta = event.relative

Animation plays only the first frame Godot

Im making a simple platformer. I have 3 movements that the player can do, run, jump and walk. The walking and jumping functions run fine but I have a problem with the run function, it seems to work but the animation only plays the first frame, which does not happen for any other animation.
extends KinematicBody2D
var speed : int = 200
var jumpforce: int = 500
var gravity: int = 1000
var vel: Vector2 = Vector2()
onready var sprite: Sprite = get_node("Sprite")
onready var anim = get_node("AnimationPlayer").get_animation("walk")
onready var anim2 = get_node("AnimationPlayer").get_animation("run")
func _physics_process(delta):
vel.x = 0
#movement
if Input.is_action_pressed("move_left"):
vel.x -= speed
anim.set_loop(true)
get_node("AnimationPlayer").play("walk")
if Input.is_action_pressed("move_right"):
vel.x += speed
anim.set_loop(true)
get_node("AnimationPlayer").play("walk")
#return to idle
if Input.is_action_just_released("move_right") or Input.is_action_just_released("move_left"):
$AnimationPlayer.play("idle")
#run
if Input.is_action_pressed("move_left") and Input.is_action_pressed("shift"):
vel.x -= speed
anim2.set_loop(true)
get_node("AnimationPlayer").play("run")
if Input.is_action_pressed("move_right") and Input.is_action_pressed("shift"):
vel.x += speed
anim2.set_loop(true)
get_node("AnimationPlayer").play("run")
#physic and jump
vel.y += gravity * delta
if Input.is_action_pressed("jump") and is_on_floor():
vel.y -= jumpforce
vel = move_and_slide(vel, Vector2.UP)
if vel.x < 0:
sprite.flip_h = true
elif vel.x > 0:
sprite.flip_h = false
Hi Man i am not sure if you still need Help but here is my solution:
extends KinematicBody2D
var speed : int = 200
var jumpforce: int = 500
var gravity: int = 1000
var vel: Vector2 = Vector2()
onready var sprite: Sprite = get_node("Sprite")
func _physics_process(delta):
vel.x = 0
#movement
#run
if Input.is_action_pressed("move_left") and Input.is_action_pressed("shift"):
vel.x -= speed
$AnimationPlayer.play("run")
elif Input.is_action_pressed("move_right") and Input.is_action_pressed("shift"):
vel.x += speed
$AnimationPlayer.play("run")
elif Input.is_action_pressed("move_left"):
vel.x -= speed
$AnimationPlayer.play("walk")
elif Input.is_action_pressed("move_right"):
vel.x += speed
$AnimationPlayer.play("walk")
#return to idle
else:
$AnimationPlayer.play("idle")
#physic and jump
vel.y += gravity * delta
if Input.is_action_pressed("jump") and is_on_floor():
vel.y -= jumpforce
vel = move_and_slide(vel, Vector2.UP)
if vel.x < 0:
sprite.flip_h = true
elif vel.x > 0:
sprite.flip_h = false
The problem was that you had a bunch of if statements and every tick both the run and walk if statements were true. So for example you press left and shift. The walk left if statement is true and the animation gets set to walk. Then the run if statement is also true and your animation gets set to run. The next frame the walk animation if statement is true again which means it gets set to the walk animation again. Then the run animation is true which sets the animation to the run animation but because we are switching the animation it sets the frame to 0 and starts the animation again.

Spawned bullets in Godot are oriented wrongly

I'm trying to make the player shoot bullets out
The thing is, they're not pointing in the same direction as the player
They also do not follow the player as they move around
code for the bullet
I store the object that shot the bullet so that the bullet can signal back if it has hit something
extends KinematicBody
var time = 0
var speed = 1800
var velocity = Vector3()
var collision = NAN
# stores the object that shot it
var shooter = NAN
func start(own):
shooter = own
# TODO Finish
global_transform.basis = own.global_transform.basis
velocity = own.global_transform.basis.z * speed + own.velocity
func _process(delta):
collision = move_and_collide(velocity * delta)
if collision:
# get parent of the StaticBody or RigidBody
print(collision.collider.get_parent())
queue_free()
time += delta
if time > 3:
queue_free()
Code for the Player
extends KinematicBody
var velocity = Vector3()
var acceleration = 1
var retrograde = false
var mouse_sensitivity = 0.008
var rot_x_target = 0
var rot_y_target = 0
var rot_x_speed = 0
var rot_y_speed = 0
var rot_acceleration = 7
var max_rot_x_speed = 0
var max_rot_y_speed = 0
var move_camera = false # if true, the 3rd person camera will move arnd freely
var bullet = preload("res://18 3 red round.tscn")
var reload_time = 0.2
var reload_timer = 0
var fire_gun = false
func shoot():
var bullet_node = bullet.instance()
bullet_node.start(self)
get_parent().add_child(bullet_node)
# to keep track of what buttons are pressed
var pressed = {}
func is_action_just_pressed(action):
if Input.is_action_pressed(action):
if not pressed.has(action) or not pressed[action]:
pressed[action] = true
return true
else:
pressed[action] = false
return false
func _physics_process(delta):
# check if the deccelerate command is active
# if so, wait for the current rotation to finish
if retrograde and abs(rot_x_speed) < rot_acceleration * delta and abs(rot_y_speed) < rot_acceleration * delta:
# orders the ship to flip
rot_x_target = PI
retrograde = false
# IMPULSOR below
# constantly calculates the maximum rotational speed to reach the target orientation
if rot_x_target != 0:
max_rot_x_speed = sqrt(2 * abs(rot_x_target) * rot_acceleration) * abs(rot_x_target) / rot_x_target
if rot_y_target != 0:
max_rot_y_speed = sqrt(2 * abs(rot_y_target) * rot_acceleration) * abs(rot_y_target) / rot_y_target
# controls the speed in each axes to be equal to the max rotational speed
# if the difference is greater than the acceleration, a correction is made
if abs(max_rot_x_speed - rot_x_speed) > rot_acceleration * delta:
if rot_x_speed < max_rot_x_speed:
rot_x_speed += rot_acceleration * delta
elif rot_x_speed > max_rot_x_speed:
rot_x_speed -= rot_acceleration * delta
if abs(max_rot_y_speed - rot_y_speed) > rot_acceleration * delta:
if rot_y_speed < max_rot_y_speed:
rot_y_speed += rot_acceleration * delta
elif rot_y_speed > max_rot_y_speed:
rot_y_speed -= rot_acceleration * delta
rotate_object_local(Vector3(1, 0, 0), - rot_x_speed * delta)
rotate_object_local(Vector3(0, 1, 0), rot_y_speed * delta)
rot_x_target -= rot_x_speed * delta
rot_y_target -= rot_y_speed * delta
reload_timer += delta # for incrementing the reload timer
if reload_timer >= reload_time and fire_gun:
shoot()
reload_timer = 0
move_and_slide(velocity)
func _input(event):
if event.is_action("midmouse"):
move_camera = not move_camera
if event.is_action_pressed("retrograde"):
retrograde = true
if event.is_action("shoot"):
fire_gun = not fire_gun
if event is InputEventMouseMotion and not move_camera and not retrograde:
rot_x_target -= event.relative.y * mouse_sensitivity
rot_y_target -= event.relative.x * mouse_sensitivity
elif event.is_action("move_forward"):
velocity += get_global_transform().basis.z * acceleration
https://youtu.be/29ynaoqyM1k
is a vid of the game not working
Okay I found out that the scene was rotated 90 degrees on the x-axis for some reason
And that you can copy the global_transform directly

Resources