Reputation: 153
I am probably overthinking this or going about it the completely wrong way. Basically I want to use move_and_slide on the instanced player (aPlayer) where I've commented, #MOVE. This script is attatched to my Tilemap on an instanced Scene Level_Test.
Code in screenshot pared down for this post because it is not relevant and nonfunctional at this time.
extends TileMap
onready var aPlayer = preload("res://Scenes/Player.tscn").instance()
var cSpawn1 = Vector2.ZERO
func _ready() -> void:
aPlayer.position = cSpawn1
add_child(aPlayer)
func _physics_process(delta) -> void:
if Input.is_action_just_released("iPlayerInteract"):
_Interact()
else:
var vInputDirection = Vector2(Input.get_action_strength("iPlayerRight") - Input.get_action_strength("iPlayerLeft"), Input.get_action_strength("iPlayerDown") - Input.get_action_strength("iPlayerUp"))
if vInputDirection != Vector2.ZERO:
_Move(aPlayer, vInputDirection)
func _Interact():
pass
func _Move(vSelf, vDirection):
#MOVE
pass
Upvotes: 1
Views: 983
Reputation: 40285
The player.tscn scene as depicted in the screenshot is structured as follows:
Player (Node2d)
└ Body (KinematicBody2D)
├ Camera (Camera2D)
├ Collision (CollisionShape2D)
└ Sprite (Sprite)
This is what gets instanced here:
onready var aPlayer = preload("res://Scenes/Player.tscn").instance()
That sets aPlayer
to the root node of the instanced scene, which is a Node2D
.
And thus what you pass into _Move
(_Move(aPlayer, vInputDirection)
) is a Node2D
, which do not have move_and_slide
, and thus calling move_and_slide
on it results in error.
Instead move_and_slide
exists in KinematicBody
(3D) and KinematicBody2D
.
The simple and elegant solution is make the KinematicBoyd2D
(Body
) the root of the scene. There is a "Make Scene Root" in the contextual menu you get on secondary click on the Scene panel, which will do that.
Alternatively you could also reach into the scene with get_node
, for example:
vSelf.get_node("Body").move_and_slide(...)
Or for example:
onready var aPlayer = preload("res://Scenes/Player.tscn").instance().get_node("Body")
Addendum: There is another way if you think about it. You can add a script to the root node (Player
) and declare whatever functions you want there, including but not limited to a move_and_slide
that delegates to the KinematicBody2D
(Body
).
I should also point out that move_and_slide
will move the KinematicBody2D
, but not its parent. So the position
property on the Player
node will no longer be the position of the KinematicBody2D
. And, well, you avoid all the trouble if you make the KinematicBody2D
the root.
Upvotes: 1