Floor issue with the player script

Godot Version

4.2

Question

I’m working on the player script

extends Skeleton3D
class_name MovementController


@export var gravity_multiplier := 3.0
@export var speed := 10
@export var acceleration := 8
@export var deceleration := 10
var air_control := 0.3
@export var jump_height := 10
var direction := Vector3()
var input_axis := Vector2()
var velocity := Vector3()
var snap := Vector3()
var up_direction := Vector3.UP
var stop_on_slope := true

var fall = Vector3() 

var current_weapon = 1

var talk_mode

var grappling = false
var hookpoint = Vector3()
var hookpoint_get = false

@onready var floor_max_angle: float = deg_to_rad(45.0)
# Get the gravity from the project settings to be synced with RigidDynamicBody nodes.
@onready var gravity = (ProjectSettings.get_setting("physics/3d/default_gravity") 
		* gravity_multiplier)
@onready var head = $Head
@onready var taser = $Head/Hand/Gun1
@onready var gun2 = $Head/Hand/Gun2
@onready var aimcast = $Head/Camera/AimCast
@onready var muzzle = $Head/Gun/Muzzle
@onready var dart = preload("res://Dart.tscn")
@onready var grapplecast = $Head/Camera/GrappleCast
@onready var bonker = $HeadBonker
@onready var sprint_timer = $SprintTimer


		

# Called every physics tick. 'delta' is constant
func _physics_process(delta) -> void:
	input_axis = Input.get_vector("move_back", "move_forward",
			"move_left", "move_right")
	
	direction_input()
	
	if is_on_floor():
		snap = -get_floor_normal() - get_floor_velocity() * delta
		
		# Workaround for sliding down after jump on slope
		if velocity.y < 0:
			velocity.y = 0
		
		if Input.is_action_just_pressed("jump"):
			snap = Vector3.ZERO
			velocity.y = jump_height
	else:
		# Workaround for 'vertical bump' when going off platform
		if snap != Vector3.ZERO && velocity.y != 0:
			velocity.y = 0
		
		snap = Vector3.ZERO
		
		velocity.y -= gravity * delta
	
	accelerate(delta)
	
	if talk_mode == false:
		var input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_backward")
		var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()

	velocity.x = move_toward(velocity.x, direction.x * _speed, Speed)
	velocity.z = move_toward(velocity.z, direction.z * _speed, Speed)

	move_and_slide()
	
	if Input.is_action_just_pressed("ability"):
		if grapplecast.is_colliding():
			if not grappling:
				grappling = true
				
	if grappling:
		fall.y = 0
		if not hookpoint_get:
			hookpoint = grapplecast.get_collision_point() + Vector3(0, 2.25, 0)
			hookpoint_get = true
		if hookpoint.distance_to(transform.origin) > 1:
			if hookpoint_get:
				transform.origin = lerp(transform.origin, hookpoint, 0.05)
		else:
			grappling = false
			hookpoint_get = false
	if bonker.is_colliding():
		grappling = false
		hookpoint = null
		hookpoint_get = false
		global_translate(Vector3(0, -1, 0))
	
	velocity = move_and_slide_with_snap(velocity, snap, up_direction, 
			stop_on_slope, 4, floor_max_angle)

func weapon_select():
	
	if Input.is_action_just_pressed("taser"):
		current_weapon = 1
	elif Input.is_action_just_pressed("unarmed"):
		current_weapon = 2
		
	if current_weapon == 1:
		taser.visible = true
		taser.shoot()
	else:
		taser.visible = false

	if current_weapon == 2:
		gun2.visible = true
		gun2.shoot()
	else:
		gun2.visible = false
		
	

func direction_input() -> void:
	direction = Vector3()
	var aim: Basis = get_global_transform().basis
	if input_axis.x >= 0.5:
		direction -= aim.z
	if input_axis.x <= -0.5:
		direction += aim.z
	if input_axis.y <= -0.5:
		direction -= aim.x
	if input_axis.y >= 0.5:
		direction += aim.x
	direction.y = 0
	direction = direction.normalized()


func accelerate(delta: float) -> void:
	# Using only the horizontal velocity, interpolate towards the input.
	var temp_vel := velocity
	temp_vel.y = 0
	
	var temp_accel: float
	var target: Vector3 = direction * speed
	
	if direction.dot(temp_vel) > 0:
		temp_accel = acceleration
	else:
		temp_accel = deceleration
	
	if not is_on_floor():
		temp_accel *= air_control
	
	temp_vel = temp_vel.linear_interpolate(target, temp_accel * delta)
	
	velocity.x = temp_vel.x
	velocity.z = temp_vel.z

but i keep having this issue

Parse Error: Function “is_on_floor()” not found in base self.
Parse Error: Function “get_floor_normal()” not found in base self

I think you need: CharacterBody3D — Godot Engine (stable) documentation in English

but your script: extends Skeleton3DSkeleton3D — Godot Engine (stable) documentation in English


What does your scene look like? You could also link it via @onready, for example.

1 Like

Your example is probably from Godot 3, the get_floor_velocity function no longer exists, it is now get_platform_velocity in Godot 4 (CharacterBody3D or 2D). Scripts from Godot 3 usually have to be ported manually. Automatic conversion doesn’t always work.