I'm working on a 2D platformer game and currently scripting the enemy.

The problem is that I can't change the velocity after hitting the wall.

I used GDQuest's code, but the problem is on the move_and_slide function.

Basically, I only need to use velocity.y, not both. Like this [velocity.y = move_and_slide(velocity, FLOOR_UP).y]

One way is to remove the move_and_slide function and add it separately to other scripts, but I have to rewrite the Player's State Machine script.

If possible, I want the move_and_slide function remains of actor.gd, but if there's no other way, I have to rewrite the player script.

Actor.gd

extends KinematicBody2D
class_name Actor

const FLOOR_UP := Vector2.UP

export var max_health: int
export var max_speed: float
export var jump_force: float
export var gravity:= 2000.0

var health: int
var velocity := Vector2.ZERO

func _physics_process(delta: float) -> void:
	control()
	velocity.y += gravity * delta
	velocity = move_and_slide(velocity, FLOOR_UP)

func control() -> void:
	pass

Enemy.gd

extends "res://src/actors/Actor.gd"
class_name EnemyCrawler

onready var raycasts := $RayCasts

export var score: int

func _ready() -> void:
	set_physics_process(false)
	velocity.x = -max_speed

func control() -> void:
	velocity.x *= -1 if is_on_wall() else 1
	$Sprite.flip_h = true if velocity.x > 0 else false

Player.gd

extends "res://src/actors/Actor.gd"
class_name Player

enum STATES {IDLE, MOVE, CROUCH, AERIAL, HIT}

export var accel: float
export var friction: float
export var air_resistance: float

var state = STATES.IDLE
var direction: float
var can_jump_cancel := true
var can_shoot := true
var is_facing_right := true

func control() -> void:
	match state:
		STATES.IDLE:
			idle_state()
		STATES.MOVE:
			move_state()
		STATES.CROUCH:
			crouch_state()
		STATES.AERIAL:
			aerial_state()

func idle_state() -> void:
	$AnimationPlayer.play("idle")
	
	velocity.x = lerp(velocity.x, 0, friction)
	
	direction = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
	
	if Input.is_action_just_pressed("shoot") and can_shoot:
		shoot()
	
	if Input.is_action_just_pressed("jump"):
		velocity.y = -jump_force
	
	if direction != 0:
		state = STATES.MOVE
	
	if Input.is_action_pressed("ui_down"):
		state = STATES.CROUCH
	
	if !is_on_floor():
		state = STATES.AERIAL

func move_state() -> void:
	direction = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
	
	if direction != 0:
		velocity.x = lerp(velocity.x, direction * max_speed, accel)
		$AnimationPlayer.play("walk")
		if direction > 0:
			is_facing_right = true
			$Sprite.flip_h = false
			$ProjectileEmitter.position.x = abs($ProjectileEmitter.position.x)
		else:
			is_facing_right = false
			$Sprite.flip_h = true
			$ProjectileEmitter.position.x = -abs($ProjectileEmitter.position.x)
	
	if Input.is_action_just_pressed("shoot") and can_shoot:
		shoot()
	
	if Input.is_action_just_pressed("jump"):
		velocity.y = -jump_force

	if direction == 0:
		state = STATES.IDLE

	if Input.is_action_pressed("ui_down"):
		state = STATES.CROUCH
	
	if !is_on_floor():
		state = STATES.AERIAL

func crouch_state() -> void:
	$AnimationPlayer.play("crouch")
	velocity.x = lerp(velocity.x, 0, friction)
	
	direction = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
	
	if direction != 0:
		if direction > 0:
			is_facing_right = true
			$Sprite.flip_h = false
			$ProjectileEmitter.position.x = abs($ProjectileEmitter.position.x)
		else:
			is_facing_right = false
			$Sprite.flip_h = true
			$ProjectileEmitter.position.x = -abs($ProjectileEmitter.position.x)
	
	if Input.is_action_just_pressed("shoot") and can_shoot:
		shoot()
	
	if Input.is_action_just_pressed("jump"):
		position.y += 3

	if Input.is_action_just_released("ui_down"):
		state = STATES.IDLE
	
	if !is_on_floor():
		state = STATES.AERIAL

func aerial_state() -> void:
	$AnimationPlayer.play("aerial")
	
	direction = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
	
	if direction != 0:
		velocity.x = lerp(velocity.x, direction * max_speed, accel)
		if direction > 0:
			is_facing_right = true
			$Sprite.flip_h = false
			$ProjectileEmitter.position.x = abs($ProjectileEmitter.position.x)
		else:
			is_facing_right = false
			$Sprite.flip_h = true
			$ProjectileEmitter.position.x = -abs($ProjectileEmitter.position.x)
	
	if Input.is_action_just_pressed("shoot") and can_shoot:
		shoot()
	
	if Input.is_action_just_released("jump") and can_jump_cancel:
		can_jump_cancel = false
		velocity.y *= 0.25
	
	if is_on_floor():
		can_jump_cancel = true
		state = STATES.IDLE

What I would recommend doing is having a function in actor.gd that is a virtual/stub (so if other things don't use it, there's no performance loss) and then check for wall collisions there by overriding the function for the player. Something like this:

### Actor.gd
extends KinematicBody2D
class_name Actor
const FLOOR_UP := Vector2.UP
export var max_health: int
export var max_speed: float
export var jump_force: float
export var gravity:= 2000.0
var health: int
var velocity := Vector2.ZERO

func _physics_process(delta: float) -> void:
	control()
	velocity.y += gravity * delta
	velocity = move_and_slide(velocity, FLOOR_UP)
	_post_physics(delta)

func control() -> void:
	pass

func _post_physics(delta:float) -> void:
	pass

###

### Player.gd
# store the previous velocity from the last _post_physics
# so we can flip the velocity without losing horizontal velocity
# due to the wall collision
var previous_velocity = Vector2.ZERO

func _post_physics(delta):
	if is_on_wall:
		velocity = previous_velocity
		# flip the X velocity
		velocity.x *= -1
		# optionally: move the player
		# velocity = move_and_slide(velocity)
	else:
		previous_velocity = velocity
###
a year later