RayCast2D and TileMap Kinematic works only in one direction

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By websterek
:warning: Old Version Published before Godot 3 was released.

Hello

I have problem with “2DTileMap Collision Shapes”. For some reason “RayCast2D” detects collision only in one place and in other just no.

For a test I have created StaticBody2D and is_colliding() returns “true” correctly.

How can I detect this collisions correctly?

Here is my script and screens:

extends Sprite

onready var Ray = get_node("RayCast2D")
onready var Twe = get_node("Tween")

func _ready():
	set_process_input(true)


func _input(key):
	if key.is_action_pressed("ui_right"):
		Ray.set_cast_to(Vector2(0, 64))
		if Ray.is_colliding() == false:
			Twe.interpolate_property(self, "transform/pos", get_pos(), Vector2(get_pos().x + 64, get_pos().y), 0.25,  Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
			Twe.start()
	if key.is_action_pressed("ui_left"):
		Ray.set_cast_to(Vector2(0, -64))
		if Ray.is_colliding() == false:
			Twe.interpolate_property(self, "transform/pos", get_pos(), Vector2(get_pos().x - 64, get_pos().y), 0.25,  Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
			Twe.start()


Best!

:bust_in_silhouette: Reply From: eons

Inside Input, Raycast may report things before actually colliding, more if your tween positions on Idle, and keep tweening.


To keep something like you are doing, by default I would restrict movement unless the raycast is not colliding (sometimes is better to restrict until all conditions are met than the inverse).

Could be (pseudo gdscript):

func _fixed_process(delta):
  if !is_moving: #is tweening, can't move
   can_move = !Ray.is_colliding()

func _input(event):
  if !is_moving:
    check input
      if can_move: #just turn around if cant move
         tween #tweens can get messy, also set it on fixed
  can_move = false #default after use 

func on_tween_start(): #signals
  is_moving = true #lock the inputs and checks you don't need

func on_tween_complete(): #signals
  is_moving = false #release input and can_move check

You can see the states of your character here, it can_move only if not is_moving (idle) and not facing a wall, while moving it just can wait.


A more simple way could be to check world to tilemap coordinates on the tween destination and see if there is a valid tile there (!= -1 or one without collider) on the tilemap, you may need to lock the tweening while moving, no need for raycasts or anything.