how to call move_and_slide from another script, node or inherited method ?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By lofi

Hi, instead of having a single script handling all actions from a character, i want to spread actions across diferents scripts or nodes for readability, so far i’ve tried this methods without luck.

Character (kinematicbody)
Sprite (sprite)
Motion(kinematicbody)

first one is based on inheritance

This is the Character node code

extends KinematicBody2D

#this is character node

var	joypad = { D = null, L = null, R = null, U = null }
var	motion = Vector2()
var	veloct = 7.5

func _ready():
      pass

This is the Motion node code

extends "Character.gd"

func _ready():
      pass

func _physics_process(delta):
      get_Action()
      set_Action()
      pass

func	get_Action():
      joypad.U = Input.is_action_pressed("ui_up")
      joypad.D = Input.is_action_pressed("ui_down")
      joypad.L = Input.is_action_pressed("ui_left")
      joypad.R = Input.is_action_pressed("ui_right")
      pass

func	set_Action():
      motion.x = int(joypad.R) - int(joypad.L)
      motion.y = int(joypad.U) - int(joypad.D)

      motion = motion.normalized() * veloct
      motion = move_and_slide(motion)
      pass

It didn’t work, if you add a print(motion) inside set_Action() you get some values but Character node isn’t moving, in fact what’s moving it’s the Motion node itself.

Second one is this

This is the Character node code

extends KinematicBody2D

#this is character node

var	joypad = { D = null, L = null, R = null, U = null }
var	motion = Vector2()
var	veloct = 7.5

func _ready():
      pass

This is the Motion node code

extends KinematicBody2D

var	parent = null

func _ready():
	  parent = get_parent()
      pass

func _physics_process(delta):
      get_Action()
      set_Action()
      pass

func	get_Action():
      parent.joypad.U = Input.is_action_pressed("ui_up")
      parent.joypad.D = Input.is_action_pressed("ui_down")
      parent.joypad.L = Input.is_action_pressed("ui_left")
      parent.joypad.R = Input.is_action_pressed("ui_right")
      pass

func	set_Action():
      parent.motion.x = int(parent.joypad.R) - int(parent.joypad.L)
      parent.motion.y = int(parent.joypad.U) - int(parent.joypad.D)

      parent.motion = parent.motion.normalized() * parent.veloct
      parent.motion = parent.move_and_slide(parent.motion)
      pass

It didnt work same as above

third one, more spaghetti oriented and more uglier cuz im poluting Character with methods, thing i wanted to avoid.

This is the Character node code

extends KinematicBody2D

#this is character node

var	joypad = { D = null, L = null, R = null, U = null }
var	motion = Vector2()
var	veloct = 7.5
var	child = null


func _ready():
	  child = $Motion
      pass

func _physics_process(delta):
      child.get_Action()
      child.set_Action()
      pass

This is the Motion node code

extends KinematicBody2D

var	parent = null

func _ready():
	  parent = get_parent()
      pass

func	get_Action():
      parent.joypad.U = Input.is_action_pressed("ui_up")
      parent.joypad.D = Input.is_action_pressed("ui_down")
      parent.joypad.L = Input.is_action_pressed("ui_left")
      parent.joypad.R = Input.is_action_pressed("ui_right")
      pass

func	set_Action():
      parent.motion.x = int(parent.joypad.R) - int(parent.joypad.L)
      parent.motion.y = int(parent.joypad.U) - int(parent.joypad.D)

      parent.motion = parent.motion.normalized() * parent.veloct
      parent.motion = parent.move_and_slide(parent.motion)
      pass

More of the same, im moving Motion node instead of Character node, is there any option out there without having to declare functions inside the Character node

:bust_in_silhouette: Reply From: Lopy

You code seems like it should work, are you sure that the character is not moving? Are your Sprites direct children of it? Try printing parent.translation.

Why is motion inheriting KinematicBody2D? It would be better as a basic Node, or even a Reference. That way, you are sure that it can not move.

PS: pass is a keyword that does nothing, and is used to avoid erroring out on empty functions. You can remove them.

thanks dude, to work the way i want both nodes have to be kinematicbodies otherwise an error appears saying something like move_and_slide isn’t declared or node can’t inherit from kinematicbody. i’ve already solved it but what do you mean use motion as a reference?.

lofi | 2021-01-31 09:59

:bust_in_silhouette: Reply From: lofi

to anyone in the future out there struggling the same way, the solution was to add collisionshapes to both kinematicbodies, you can disable if you want the inherited kinematicbody collision shape and then add the next code:

func _ready():
#watch closely this line
	player = get_parent()
	pass

func _physics_process(delta):
	get_Action()
	set_Action()
	pass



func	get_Action():
	joypad.U = Input.is_action_pressed("ui_up")
	joypad.D = Input.is_action_pressed("ui_down")
	joypad.L = Input.is_action_pressed("ui_left")
	joypad.R = Input.is_action_pressed("ui_right")
	pass

func	set_Action():
	motion.x = int(joypad.R) - int(joypad.L)
	motion.y = int(joypad.U) - int(joypad.D)
	motion.z = 0

	motion = motion.normalized() * veloct
#cause it makes it's magic here
	motion = player.move_and_slide(motion)
	pass

this even works with 3d kinematicbody