0 votes

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()

False
True

Best!

in Engine by (227 points)

1 Answer

0 votes
Best answer

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.

http://docs.godotengine.org/en/stable/classes/class_tilemap.html#class-tilemap-world-to-map

by (7,908 points)
selected by
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 Frequently asked questions and 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 [email protected] with your username.