GetCollisionPoint() always returns the same Vector2
Asked Answered
S

6

0

Godot 4.2.2rc1, Scripts written in C#

my "UpdateLos" functions basically loops through a list of Vector2 items, sets the the TargetPosition of a RayCast2D node to the value of the current Vector2, forecupdates the RayCast2D and then checks if there is a collision (with one of the collision layers of the tiles on a TileMap).
If a collision is detected, I want the position where the collision has happened.

My problem now is, that I always get the same result for the collision point, no matter what I set as the "recast.TargetPosition". For example, if I aim at the top left of my tilemap, I get bottom right as collision point. If I aim at bottom left I get bottom right as well as answer.

The UpdateLos function is being called from a script, that is attached to the tilemap.

Any help is appreciated...
Jens

public static List<Vector2> UpdateLos(
        Vector2 mapPlayerPosition,
        RayCast2D losRayCast,
        TileMap visTileMap
    )
    {
        _npcs = Data.ActiveMapNpcs;
        List<Vector2> markedTiles = new List<Vector2>();

        var targetPointList = CreateTargetPoints(Data.Visibility);
         
        foreach (var mapTargetPoint in targetPointList)
        {
            var los = AddLine(visTileMap, false);
            var pointOrigin = visTileMap.MapToLocal((Vector2I)Data.CurrentPlayerPos);
            var pointTarget = visTileMap.MapToLocal((Vector2I)Data.CurrentPlayerPos + (Vector2I)mapTargetPoint);
            losRayCast.TargetPosition = pointTarget;
            losRayCast.ForceRaycastUpdate();
            los.Points = new[] { pointOrigin, pointTarget};
            GD.Print("aiming at: " + pointTarget);
            
            if (losRayCast.IsColliding())
            {
                los.DefaultColor = new Color(1, 0, 0);
                
                //
                losRayCast.ForceRaycastUpdate();
                var localCollisionPoint = losRayCast.GetCollisionPoint();
                var mapCollisionPoint = visTileMap.LocalToMap(localCollisionPoint);
                GD.Print("collision detect at: " + localCollisionPoint);
                //
                
                var newPath = CreateAStarPath(mapPlayerPosition, mapCollisionPoint, visTileMap);
                ClearPath(newPath.ToList(), visTileMap, markedTiles); ;
            }
            else
            {
               var mapRayCastEndpoint = mapPlayerPosition + mapTargetPoint;
               var newPath = CreateAStarPath(mapPlayerPosition, mapRayCastEndpoint, visTileMap);
                ClearPath(newPath.ToList(), visTileMap, markedTiles);
            }
        }
Soundless answered 18/3 at 17:24 Comment(0)
B
0

There's quite a lot going on here that are unknowns to the Internet reader. For example, what is CreateTargetPoints and are they correct? What does GD.Print("aiming at: " + pointTarget); display? What's the position on losRayCast? Are you using MapToLocal correctly?

Debugging here should help but maybe you should consider uploading a small example project?

Banuelos answered 19/3 at 14:57 Comment(0)
S
0

Banuelos

The CreateTargetPoint Methode returns a List of Vector2. These Vector2 basically describe the tiles surrounding the player in a certain distance. For a Distance of 3 the coordinates would range from (-3,-3), (-2,-3), (-1,-3), (0,-3), (1,-3), (2,-3), (3,-3), (-3,3), (-2,3), (-1,3), (0,3), (1,3), (2,3), (3,3), (-3,-2), (-3,-1), (-3,0), (-3,1), (-3,2), (3,-2), (3,-1), (3,0), (3,1), (3,2)

Then I target each of these points with the RayCast and check if a collision is detected. The console output would look like this:

mapTargetPoint: (-3, -3)
mapTargetPoint: (-2, -3)
mapTargetPoint: (-1, -3)
mapTargetPoint: (0, -3)
collision detect at: local: (324, 489,81818) / map: (20, 30)
mapTargetPoint: (1, -3)
collision detect at: local: (324, 485,14285) / map: (20, 30)
mapTargetPoint: (2, -3)
collision detect at: local: (326,4889, 484) / map: (20, 30)
mapTargetPoint: (3, -3)
collision detect at: local: (329,86667, 484) / map: (20, 30)
mapTargetPoint: (-3, 3)
mapTargetPoint: (-2, 3)
mapTargetPoint: (-1, 3)
mapTargetPoint: (0, 3)
mapTargetPoint: (1, 3)
mapTargetPoint: (2, 3)
mapTargetPoint: (3, 3)
mapTargetPoint: (-3, -2)
mapTargetPoint: (-3, -1)
mapTargetPoint: (-3, 0)
mapTargetPoint: (-3, 1)
mapTargetPoint: (-3, 2)
mapTargetPoint: (-3, 3)
mapTargetPoint: (3, -2)
collision detect at: local: (327,06384, 484) / map: (20, 30)
mapTargetPoint: (3, -1)
collision detect at: local: (324,4898, 484) / map: (20, 30)
mapTargetPoint: (3, 0)
collision detect at: local: (324, 486,46155) / map: (20, 30)
mapTargetPoint: (3, 1)
collision detect at: local: (324, 489,53845) / map: (20, 30)
mapTargetPoint: (3, 2)
mapTargetPoint: (3, 3)

As can be seen, when I aim at mapTargetPoint: (1, -3)the collision is detected at (20,30). If I aim at (3,-1) the collision is detected at (20,30) as well.

Soundless answered 19/3 at 17:40 Comment(0)
C
0

Well, if your tile size is 16x16 all your points with coordinates ~ 320/~ 480 are on your map(20,30). So this is correct.
Your map target point changes the raycasts position only by a few pixels and never makes it out of the current tile.

Not sure without seeing more code/setup, but maybe you need to multiplay your map target points by your tilesize so your raycast moves in tile size steps.

Cavefish answered 19/3 at 18:42 Comment(0)
S
0

Cavefish

I uploaded a version of my code to GitHub. The function and file in question can be found at res://global/FuncLos.cs

link to GitHub project

I run this project with Godot_mono v4.2.2.rc1.mono.official [c7fb0645a]

Soundless answered 19/3 at 22:5 Comment(0)
C
0

I get a lot of errors from other things. Anyway, those green dots should represent the raycast positions I assume?

Cavefish answered 19/3 at 23:49 Comment(0)
S
0

Cavefish

The green dots are simply a "grass texture" from the tileset.


Maybe my illustration might shed a little light on my problem?

Soundless answered 20/3 at 20:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.