Invalid set index z with value of type float in gdscript - godot

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()

Related

Player Stops Moving After a few seconds(3D)

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.

The function 'connect()' returns a value, but this value is never used. What does this mean?

I am new to Godot, and I am creating my first project. There's something that annoys the heck out of me. It's this: "The function 'connect()' returns a value, but this value is never used." I don't know what to add to the line of code, but I will first show the code:
extends KinematicBody2D
var gravity = 1000
var velocity = Vector2.ZERO
var maxHorizontalSpeed = 120
var horizontalAcceleration = 100
var jumpSpeed = 320
var jumpTerminationMultiplier = 4
var hasDoubleJump = false
func _ready():
warning-ignore:return_value_discarded
$HazardArea.connect("area_entered", self, "on_hazard_area_entered")
func _process(delta):
var moveVector = Vector2.ZERO
moveVector.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
moveVector.y = -1 if Input.is_action_just_pressed("jump") else 0
velocity.x += moveVector.x * horizontalAcceleration * delta
if (moveVector.x == 0):
velocity.x = lerp(0, velocity.x, pow(2, -50))
velocity.x = clamp(velocity.x, -maxHorizontalSpeed, maxHorizontalSpeed)
if (moveVector.y < 0 && (is_on_floor() || $CoyoteTimer.is_stopped() || hasDoubleJump)):
velocity.y = moveVector.y * jumpSpeed
if(!is_on_floor() && $CoyoteTimer.is_stopped()):
hasDoubleJump = false
$CoyoteTimer.stop()
if(moveVector.y < 0 && !Input.is_action_just_pressed("jump")):
velocity.x = gravity * jumpTerminationMultiplier * delta
else:
velocity.y += gravity * delta
var wasOnFloor = is_on_floor()
velocity = move_and_slide(velocity, Vector2.UP)
if(wasOnFloor && !is_on_floor()):
$CoyoteTimer.start()
if(is_on_floor()):
hasDoubleJump = true
update_animation()
func get_movement_vector():
var moveVector = Vector2.ZERO
moveVector.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
moveVector.y = -1 if Input.is_action_just_pressed("jump") else 0
return moveVector
func update_animation():
var moveVec = get_movement_vector()
if(!is_on_floor()):
$AnimatedSprite.play("Jump")
elif(moveVec.x != 0):
$AnimatedSprite.play("Run")
else:
$AnimatedSprite.play("Idle")
$AnimatedSprite.flip_h = true if moveVec.x > 0 else false
func on_hazard_area_entered(_area2d):
print("die")
The problem is on line 13, and I would really appreciate some help!
there is not a solution for this problem. The only thinks you can do are these:
Or use the returning value (if you want)
Or press ignore in warning tab
This link can help you more https://godotengine.org/qa/78337/the-function-connect-returns-value-but-this-value-never-used

Godot 3: How to walk on walls using Gravity and Gravity Direction?

I want to make a 3D game on Godot with the player who can walk on walls and ceiling but I've tried to make this but it didn't work :(
This is the code of my Player First Person Controller:
extends KinematicBody
export var GravityDirection = Vector3(-9.8, 0, 0)
var held_object: Object
var velocity = Vector3.ZERO
var speed = 10
var MAX_SPEED = 30
var GravityStrength = 9.8
var throw_force: float = 200
var wall_one = Vector3(-9.8, 0, 0)
var wall_two = Vector3(0, 0, -9.8)
var wall_three = Vector3(9.8, 0, 0)
var wall_four = Vector3(0, 0, 9.8)
var ground = Vector3(0, -9.8, 0)
onready var ray = $"Camera/Hand/RayCast"
onready var hold_position = $"Camera/Hand/HoldPosition"
# Camera
onready var player_camera = $"Camera"
var spin = 0.1
export var mouse_sensitivity = 5
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _physics_process(delta):
var Gravity = GravityStrength * GravityDirection
var Velocity = Gravity * delta
move_and_collide(Velocity)
var run_once = 0
while 1:
if run_once == 0:
if GravityDirection == wall_one:
rotate_x(90)
run_once = 1
player_camera.rotation_degrees.y = 180
player_camera.rotation_degrees.z = 0
if Input.is_action_just_pressed("player_fire"):
fire()
if not is_on_floor():
Velocity.y += -GravityStrength
movement(delta)
velocity = move_and_slide(velocity, Vector3.ZERO)
if Input.is_action_just_pressed("player_pick"):
if held_object:
held_object.mode = RigidBody.MODE_RIGID
held_object.collision_mask = 1
held_object = null
else:
if ray.get_collider():
held_object = ray.get_collider()
held_object.mode = RigidBody.MODE_KINEMATIC
held_object.collision_mask = 0
if held_object:
held_object.global_transform.origin = hold_position.global_transform.origin
#_process_input()
#_process_gravity()
# Mouvement
func movement(_delta):
var dir = Vector3.ZERO
var vel_y = velocity.y
velocity = Vector3.ZERO
# Movement forward and backward
if Input.is_action_pressed("player_forward"):
dir += transform.basis.z
elif Input.is_action_pressed("player_backward"):
dir -= transform.basis.z
# Movement Left and Right
if Input.is_action_pressed("player_left"):
dir += transform.basis.x
elif Input.is_action_pressed("player_right"):
dir -= transform.basis.x
velocity = dir.normalized() * speed
velocity.y = vel_y
func _input(event):
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
rotate_y(lerp(0, -spin, event.relative.x * (mouse_sensitivity * 0.01) ))
player_camera.rotate_x(lerp(0,spin, event.relative.y * (mouse_sensitivity * 0.01)) )
#Clamp vertical rotation
var curr_rot = player_camera.rotation_degrees
curr_rot.x = clamp(curr_rot.x, -60, 60)
player_camera.rotation_degrees = curr_rot
func fire():
print("fire")
if ray.get_collider() != null and ray.get_collider().is_in_group("enemy"):
print(ray.get_collider())
ray.get_collider().hp -= 10
Nodes Configuration
In the code, you can find fonctions for the camera and gravity system. Also, there is a fonction to pick up rigid bodies. I want to make a system where when the Gravity has a specific direction, the mesh rotate to 90°. I've made a "GlobalRay" with 6 RayCast to detect collisions (walls) and register face blablabla... you've understood but I don't know how to make a system like this!!!
I think there is a way to optimize the script, so, I need help :D
If you can perform my code it's nice! Have a nice code!
It looks like you're subtracting GravityStrength from the player's y velocity if they are not on the floor, while you should be adding the Velocity to the player's velocity. Otherwise, this question here is very general and could be implemented in a lot of ways. wall_one, wall_two, wall_three etc. I think would be better off with a magnitude of one so they could undergo the same GravityStrength modifier as everything else in later implementations, but that's just me.

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.

How do I write a code that controls jumps, and creates a double jump action'?

# 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).

Resources