im trying to make a 3d fighting game, when i start it the player can move around like normal, but after a few seconds the player just freezes, the animations work fine, but the player will just freeze in place.
i looked through the code a bunch of times but i cant find what's causing it, plz help
Code:
extends KinematicBody
onready var anim = $PlayerANIM/AnimationPlayer
export var speed = 10
const ACCEL = 15.0
const AIR_ACCEL = 9.0
const JUMP_SPEED = 15
var velocity = Vector3.ZERO
var velocity_info = Vector3.ZERO
var current_vel = Vector3.ZERO
var snap = Vector3.ZERO
var gravity = -40
var can_run = true
var dir = Vector3.ZERO
func play_anim(dir):
if anim.is_playing() == false:
anim.play("IDLE")
if Input.is_action_just_pressed("a") or Input.is_action_just_pressed("d") and can_run:
anim.stop()
anim.play("RUN")
if Input.is_action_just_released("a") or Input.is_action_just_released("d") and can_run:
anim.stop()
func _physics_process(delta):
#MOVEMENT
dir = Vector3.ZERO
if Input.is_action_pressed("d") and can_run:
rotation_degrees = Vector3(0,0,0)
if anim.is_playing() == false:
anim.play("RUN")
dir += global_transform.basis.x
if Input.is_action_pressed("a") and can_run:
rotation_degrees = Vector3(0,180,0)
if anim.is_playing() == false:
anim.play("RUN")
dir += global_transform.basis.x
if Input.is_action_just_pressed("Punch") and $PunchTimer.is_stopped():
anim.stop()
anim.play("PUNCH")
$PunchTimer.start()
can_run = false
if Input.is_action_just_pressed("Kick") and $KickTimer.is_stopped():
anim.stop()
anim.play("KICK")
$KickTimer.start()
can_run = false
if Input.is_action_just_released("a") or Input.is_action_just_released("d"):
anim.stop()
if Input.is_action_just_pressed("space") and is_on_floor():
#velocity.y = 15
anim.play("ROLL")
$RollTimer.start()
var target_vel = dir * speed
var accel = ACCEL if is_on_floor() else AIR_ACCEL
current_vel = current_vel.linear_interpolate(target_vel, accel * delta)
velocity.x = current_vel.x
velocity.z = current_vel.z
velocity.y += gravity *delta
move_and_slide_with_snap(velocity, snap, Vector3.UP, true, 4, deg2rad(45))
play_anim(dir)
func _on_PunchTimer_timeout():
can_run = true
func _on_KickTimer_timeout():
can_run = true
func _on_RollTimer_timeout():
pass
I guess you need to change Input.is_action_just_pressed("action_name") to Input_is_actions_pressed("action_name").
The difference is that first functions returns 'true' only once while you pressing the button (which is good, for example, when you make pistol shooting), and second one returns 'true' all the time you pressing the button.
Related
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()
So, the code I have for a dash function is not working correctly even though im positive the logic is correct. I suspected the problem was with the variable isdashing so I printed out the value for it and comes back false no matter what I do. Can anyone tell me what im doing wrong?
extends KinematicBody2D
export(int) var Jump_Height = -100
export(int) var Jump_Realese = -60
export(int) var gravity = 4
var velocity = Vector2.ZERO
var move_speed = 50
#Jump Stuff
var max_jump = 2
var jump_count = 0
# Dash Stuff
var dash_direction = Vector2(1,0)
var dashable = false
var isdashing = false
# Movement
func _physics_process(delta):
dash()
gravity_control()
if Input.is_action_pressed("ui_right"):
velocity.x = move_speed
elif Input.is_action_pressed("ui_left"):
velocity.x = -move_speed
else:
velocity.x = 0
if is_on_floor() and jump_count != 0:
jump_count = 0
if jump_count<max_jump:
if Input.is_action_just_pressed("ui_up"):
velocity.y = Jump_Height
jump_count += 1
else:
if Input.is_action_just_released("ui_up") and velocity.y < Jump_Realese:
velocity.y = Jump_Realese
velocity = move_and_slide(velocity, Vector2.UP)
func dash():
if is_on_floor():
dashable = true
if Input.is_action_pressed("ui_left"):
dash_direction = Vector2(-1,0)
if Input.is_action_pressed("ui_right"):
dash_direction = Vector2(1,0)
if Input.is_action_just_pressed("ui_Dash") and dashable:
velocity = dash_direction.normalized() * 7000
dashable = false
isdashing = true
yield(get_tree().create_timer(0.2), "timeout")
isdashing = false
It's likely that Input.is_action_just_pressed("ui_Dash") is false because dash() is being called in the physics_process function which doesn't run every frame (it runs 60 times a second).
What currently happens is -
During a game frame, the user presses the dash button. At this point Input.is_action_just_pressed("ui_Dash") is true but nothing has checked it.
A frame or two (or more) later, the dash function is called in the physics_process. This polls if the dash button was just pressed - but now it's false because it was "just pressed" a few frames ago, not on this frame.
The only way your current logic works is if the dash button was pressed in the EXACT frame that the physics_process runs.
You can get around this by using Input.is_action_pressed("ui_Dash") to capture the button press, setting a flag to prevent it being captured on the next physics frame and then enabling it again sometime later. E.g.
var can_dash: boolean = true
func dash():
if is_on_floor():
dashable = true
if Input.is_action_pressed("ui_left"):
dash_direction = Vector2(-1,0)
if Input.is_action_pressed("ui_right"):
dash_direction = Vector2(1,0)
if can_dash and Input.is_action_pressed("ui_Dash") and dashable:
can_dash = false;
velocity = dash_direction.normalized() * 7000
dashable = false
isdashing = true
yield(get_tree().create_timer(0.2), "timeout")
isdashing = false
can_dash = true
You are resetting your variables (especially velocity) before calling move_and_slide().
Solution: Call dash() immediately before calling move_and_slide().
This is the reset I'm referring to:
if Input.is_action_pressed("ui_right"):
velocity.x = move_speed
elif Input.is_action_pressed("ui_left"):
velocity.x = -move_speed
else:
velocity.x = 0
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.
I am working on a game and for some reason when I try to call the hit_check() function it won't animate the sprite. all of the other animations have worked perfectly which is why I'm confused.
Heres my script:
extends KinematicBody2D
var motion = Vector2(0,0)
const SPEED = 130
const GRAVITY = 15
const UP = Vector2(0,-1)
const JUMP_SPEED = 350
func _physics_process(delta):
apply_gravity()
hit_check()
jump_check()
move_check()
move_and_slide(motion, UP)
func apply_gravity():
if not is_on_floor():
motion.y += GRAVITY
else:
motion.y = 0
func jump_check():
if Input.is_action_pressed("jump") and is_on_floor():
motion.y -= JUMP_SPEED
func move_check():
if Input.is_action_pressed('left'):
$PlayerAnimation.flip_h = true
$PlayerAnimation.play("walk")
motion.x = -SPEED
elif Input.is_action_pressed('right'):
$PlayerAnimation.flip_h = false
$PlayerAnimation.play("walk")
motion.x = SPEED
else:
motion.x = 0
$PlayerAnimation.play("idle")
func hit_check():
if Input.is_action_pressed("hit"):
$PlayerAnimation.play("hit")
jump_check and move_check functions are called after hit_check function, and move_check function always overrides the current animation of the node because there is an animation specified in both if and else blocks.
# changed switch statement setup by creating a new variable and using "." operator
# removed extra delta in move_and_slide function
# left off attempting to add gravity to the game
# 2/26/2019
# removed FSM and will replace it with tutorial video code, for sake of completion
extends Node2D
const FLOOR = Vector2(0,-1)
const GRAVITY = 5
const DESCEND = 0.6
var speed = 100
var jump_height = -250
var motion = Vector2()
var jump_count = 0
var currentState = PlayerStates.STATE_RUNNING
var grounded = false
enum PlayerStates {STATE_RUNNING, STATE_JUMPING, STATE_DOUBLE_JUMPING, STATE_GLIDING}
func _ready():
var currentState = PlayerStates.STATE_RUNNING
pass
func jump():
motion.y = jump_height
func glide():
if motion.y < 500:
motion.y += DESCEND
func _process(delta):
var jump_pressed = Input.is_action_pressed('jump')
var glide_pressed = Input.is_action_pressed('glide')
* the code below is where I attempted to count the jumps in order to keep them from surpassing two jumps. My goal is to create a double
jump and so I used the less than operator to control that number*
if jump_pressed:
if jump_count < 2:
jump_count += 1
jump()
grounded = false <-- I had to copy paste this code again, below, so I don't get an error in my question.
if jump_pressed:
if jump_count < 2:
jump_count += 1
jump()
grounded = false
if grounded == false:
if glide_pressed:
glide()
motion.x = speed
motion.y += GRAVITY
motion = move_and_slide(motion, FLOOR)
if is_on_floor():
grounded = true
jump_count = 0
else:
grounded = false
First of all, I think you need to use a KinematicBody2D and perform your logic in _physics_process if you would like to use move_and_slide, other than that, your code was almost working:
extends KinematicBody2D
const FLOOR = Vector2(0,-1)
const GRAVITY = 3000
const DESCEND = 0.6
var speed = 100
var jump_height = 250
var motion = Vector2()
var jump_count = 0
func jump():
motion.y = -jump_height
func glide():
if motion.y < 500:
motion.y += DESCEND
func _physics_process(delta):
var jump_pressed = Input.is_action_pressed('jump')
var glide_pressed = Input.is_action_pressed('glide')
motion.y += delta * GRAVITY
var target_speed = Vector2(speed, motion.y)
if is_on_floor():
jump_count = 0
if glide_pressed:
glide()
if jump_pressed and jump_count < 2:
jump_count += 1
jump()
motion = lerp(motion, target_speed, 0.1)
motion = move_and_slide(motion, FLOOR)
You also need to change the node type to KinematicBody2D in the Godot editor (right click on the node and then on change type).