godotengine / godotengine/godot

RayCast2D detects object at previous position, if that object has just moved

Open
#95,359 8 comments 0 reactions 0 assignees View on GitHub
discussion documentation topic:2d topic:physics
Dominant language
C++
Stars
117k
Forks
26.8k
PR merge metrics
PR metrics pending

Description

### Tested versions

- Reproducible in v4.2.2.stable.official [15073afe3] and v4.3.rc3.official [03afb92ef]

### System information

Godot v4.3.rc3 - Windows 10.0.19045 - Vulkan (Forward+) - integrated Intel(R) HD Graphics 520 (Intel Corporation; 24.20.100.6293) - Intel(R) Core(TM) i5-6300U CPU @ 2.40GHz (4 Threads)

### Issue description

I'm making a turn-based game and I ran into this strange behavior with RayCast2D. If I move the player object (a CharacterBody2D) and then use RayCast2D to try to detect the player, it will detect the player at their previous position.

As an example, if you do something like this:

```gdscript
player.position.x += 100
var raycast = $RayCast2D
raycast.position = player.position
raycast.target_position = Vector2.ZERO
raycast.force_raycast_update()
if raycast.get_collider() == player:
print("RayCast2D hit player")
```

Then the print statement will never run. If instead the RayCast2D is aimed at the player's previous position (i.e. `raycast.position = player.position - Vector2(100, 0)`) then the print statement will always run.

I thought calling `force_raycast_update` would cause RayCast2D to see the player at their current position, but it seems like it doesn't. (By the way, if you remove the call to `force_raycast_update` then it misses the player the first time it runs, but then always hits the player on subsequent runs. That also seems strange to me.)

Am I doing something wrong here? Is there a better way to accomplish this that doesn't run into this problem? Thank you!

### Steps to reproduce

1. In the MRP, use the arrow keys to move the player or the spacebar to wait.
2. The MRP code will move a RayCast2D to the player's position, call `force_raycast_update` and then `get_collider`.
3. If you move the player, it will print "RayCast2D missed player". I would expect it to always print "RayCast2D hit player". Waiting will correctly print "RayCast2D hit player".

### Minimal reproduction project (MRP)

[raycast2d-minimal-repro.zip](https://github.com/user-attachments/files/16569787/raycast2d-minimal-repro.zip)

Contributor guide

Open the contributing guide

Research direction

Start with the attached minimal reproduction project and trace the RayCast2D calls in the reproduction: moving the player, setting the ray position and target_position, then calling force_raycast_update() and get_collider(). Compare results after movement versus waiting, and determine whether the ray sees the current or previous physics position. Done means reproducing the mismatch and identifying a confirmed engine-side fix or documented expected behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
godot
Domain
game-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.