0 votes

Currently, I am trying to set up a kinemeticbody2d (I'll call it teleporter) with a collision2d as a child of the kinematicbody2d player. The plan is, this teleporter is supposed to always be in front of the player so that when they teleport, they can move to the teleporter. When this teleporter collides with a wall, it would stop so that the player can't teleport into/through walls, then when you move away from the wall, the teleporter would move back. This is my current code for it:

extends KinematicBody2D

const speed = 5000

var velocity = Vector2.ZERO
var location = position

func _physics_process(delta):
    if location != position:
        velocity = position.direction_to(location.position) * speed
    velocity = move_and_slide(velocity)

Currently, all that happens is a "Invalid get index 'position' (on base: 'Vector2')." If anyone has any advice on how to get this working, or if there's a better way of setting up this sort of detection, I would greatly appreciate the advice.

Godot version Godot Engine v3.3.stable.official
in Engine by (30 points)

1 Answer

+1 vote
Best answer

Create a RayCast2D as a child of your Player KinematicBody2D and set it to cast to a teleport's length in front of your player. This takes the place of the Teleporter KinematicBody2D that you were attempting to create.

onready var teleporting_ray_check : RayCast2D = get_node("ray_cast")

func _ready():
    teleporting_ray_check.enabled = true

func _physics_process(_delta: float) -> void:
    var teleporting = Input.is_action_just_pressed("ui_accept")
    if not teleporting:
        pass
    elif teleporting_ray_check.is_colliding():
        self.global_position =  teleporting_ray_check.get_collision_point()
    else:
        self.position += teleporting_ray_check.get_cast_to()

Add a cooldown timer as you see fit.

by (3,513 points)
selected by

"however it causes the raycast to go up or down"
That has to deal with the values of your teleportRight and teleportLeft - which should be treated as constants. You should never be adjusting the position of the RayCast2D it will follow the center of your KinematicBody2D since the RayCast2D is a child of it.

Works almost perfectly! The issue with the raycast pointing up and down was because I had already rotated it to face to the right, and the code made it rotate again, I've fixed that. The only thing that currently doesn't work is collision, as it still teleports into walls.

If you're standing next to a wall do you teleport the entire length of the RayCast2D?

if teleport.is_colliding():
    print("colliding")
    self.global_position =  teleport.get_collision_point()  + (sign(teleport.get_cast_to().x) * BUFFER)
else:
    print("not colliding")
    self.position += teleport.get_cast_to()

add those print statements. If you're hitting the "colliding" and still going into the wall it has to deal with what you're setting your teleportLeft and teleportRight to , they should be set to Vector2.LEFT * some length and Vector2.RIGHT * some length respectively. Or your buffer is too small.

You shouldn't be hitting the not colliding branch. If you are that's very strange.

Ahh I finally found where it went wrong. I was setting the buffer to half the height, not half the width. Works perfectly now, thank you ever so much!

Hahaha I was very confused! No problem man!

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.