0 votes

I'm trying to do something like that:

if ground_ray1.is_colliding() or ground_ray2.is_colliding():
    ground_ray1.add_exception(player)
    ground_ray2.add_exception(player)
    set_fixed_process(false)

but i don't know how to do it since the KinematicBody2D node representing the player isn't on the same scene. Before this, I've tried to do that:

onready var scn_player = preload("res://scenes/player.tscn")

func _ready():
    var player = scn_player.instance()

but didn't worked, i think it's because that would be a generic copy of this scene and not the one running on the game and whose i'm trying to make an exception.

I would either like to know some other useful functions that are related with RayCast2D's collisions, they are really useful.

in Engine by (15 points)

1 Answer

+1 vote
Best answer

Use raycast's method get_collider().

From the documentation (2d or 3d is all the same):

Object get_collider() const

Returns the closest object the ray is pointing to. Note that this does not consider the length of the ray, so you must also use is_colliding() to check if the object returned is actually colliding with the ray.

Example:

if RayCast2D.iscolliding(): var collider = RayCast2D.getcollider()

by (73 points)
selected by

There is some difference, specially with the "new()". Here is the entire code anyway. I'll do some modifications based on what you said and see what happens.

# Blocks spawner

extends Node2D

const scn_block_32 = preload("res://scenes/block_32.tscn")
const scn_player = preload("res://scenes/player.tscn")
onready var container = get_node("container")

func _ready():
    var player = scn_player.instance()
    container.add_child(player)
    set_fixed_process(true)

func _fixed_process(delta):
    #Moving spawner up
    set_pos(Vector2(get_pos().x, get_pos().y - 200 * delta))

# Spawn block 32x32
func spawn_block_32():
    randomize()
    var new_block_32 = scn_block_32.instance()
    new_block_32.set_pos(Vector2(rand_range(16, 240), get_pos().y))
    container.add_child(new_block_32)

# Timer
func _on_timer_0_timeout():
    spawn_block_32()

Now for some reason my player is going left forever if it is on container. This doesn't make any sense.

I will start all again.

You've set player as a child of container and in your code container is constantly moving 200 px/s left. A child always follows it's parent.

Starting over is ok if you are just at the beginning of a project, but otherwise it'd be better for you to start using a vcs (like git) if you haven't already, it will save you a loooot of pain. If you don't know what they are you can find a ton of tutorials online (like this ones for git).

I wish you the best of lucks.

Didn't thought about that, makes sense now. It's my very first project and i was just 2 days working on it, no problem starting over. I'll take a look on that vcs.

I made it all again and discovered a bunch of things:

  • For some reason, the get_node("player") were adding the player scene to the current node (that would be the container from block_spawner), but i never told it to add a child. That is what causes the player to go left forever. Then i decided to erase my instance and left that one there, but the exception wasn't working either. Then i've put get_node("/root/arcade/player, which solved the problem with the double players.

  • The add_exception(player) is being ignored. I printed the collider and the player to see what they were if the collision is detected, and for my surprise, they were the same! So, i was doing it right, but the condition is being ignored for some reason. Also, i get this error when colliding the block while it is in the air:

    ERROR: KinematicBody2D::get-collider: Condition ' !colliding ' is true. returned: 0 At: scene\2D\physics-body_2d.cpp:1326

  • I also tried to make a variable can_stop, that would continue false if the collider was equal to the player. But it didn't worked either.

What the hell is happening here? The add_exception function works well on the player's raycast by avoiding any accidental collision with the player collision shape by checking jump disponibility. Don't know why this doesn't work here.

I'm doing it on the block scene itself. Code:

extends KinematicBody2D

onready var bottom_ray = get_node("bottom_ray")
onready var player = get_node("/root/arcade/player")
. . .
func _ready():
. . .
    set_fixed_process(true)

func _fixed_process(delta):
. . .
    # Collision
    if bottom_ray.is_colliding():
        bottom_ray.add_exception(player)
        set_fixed_process(false)

I also tried:

if bottom_ray.is_colliding():
    bottom_ray.add_exception(player)
    if bottom_ray.is_colliding():
        set_fixed_process(false)

But the issue continued.

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.