+1 vote

Hello,

I have a quite simple task to do, if an enemy see the character of the player, the enemy move toward the character, and I want to do it with RayCast2D node inside the enemy scene, so I can detect obstacles between character and enemy

I wrote these lines of code for the enemy so that at every physic process frame the ray is cast toward the player´s character:

var idle=true
var player_detected=false
var target=global_position
func _physics_process(delta):
$RayCast2D.set_cast_to(character.global_position)
if ($RayCast2D.is_colliding()==true and $RayCast2D.get_collider().get_parent()==character):
        print("I see you")
        idle=false
        player_detected=true
        target=character.global_position
    elif player_detected==true:
        print("I cant see you but i remember where you were")
        pass
    else:
        print("idle")
        idle=true  
move_toward(target,delta)    #a simple function to move the enemy

This is not working, the player is detected only if the character stands in front of the enemy. I suppose the .setcastto() command is not working as intended, and that detection happens only if the character move inside the original ray I created into the enemy scene.
What am I doing wrong here?

SOLVED:
it turned out the input for the command "cast to" is always refereed in local coordinates, which means that if you instance the scene with the RayCast2d in a world scene, if the scenese rotates or move, it is very difficult to calculate the correct casting Vector2.
It is much easier to create a very long RayCast, and then set it´s rotation so that is always pointing toward the player.
if I substitute $RayCast2D.set_cast_to(character.global_position) with $RayCast2D.rotation=get_angle_to(character.global_position)it works fine.

PS: (may I say that to use local coordinates to cast a ray is quite silly? It´s very likely a ray is used to get collision between objects of different scenes with different local coordinates. Is there a way to take that into consideration without let me doing hard trigonometry problems?)

asked Feb 24, 2018 in Engine by Andrea (520 points)
edited Mar 2, 2018 by Andrea

thank for this random thread from 2 years ago solved my problem

1 Answer

0 votes

Ok, so first of all the raycast2D works like a laser pointer, and will return the FIRST object it collides with.
second of all, if you set castto to Vector2(0,1) and then rotates it by 90 degrees its like you made the castto to Vector2(-1,0) .
third of all, the get_collider() returns the physics object not the collider itself( if you dont trust me just print the collider's name or seomthing ).
FOURTH: if you have a Boolean in an if statement you dont need to ask if its true, its like saying if true == true or if false == true(i think you get the point here)
fifth: setting the castto doesnt mean it will cast towards that point from where it stands but if will cast to that vector from where it stands, if the raycast will stand in (0,10) and its castto is (10,0) the end of it will be relative to its position so globally it will the point (10,10), you want to set it to the relative position, so it will be $Player.global_position - $Raycast.global_position.

no sixth sorry but here is the word potato: potato

answered Feb 24, 2018 by rustyStriker (1,079 points)

Already tried that, didnt work.
That´s because if you do difference=player.global_position - $raycast.global_position, it will take into account the difference in translation, but not in rotation: if the scene with the ray rotates, casting the ray toward said difference will point toward a totally wrong direction. In order to take in account difference in translation AND rotation you have to rotate the vector of the difference so that it nullify the rotation of the scene in which the Raycast2d is living (and this is where my question about hard trigonometry came from. not really that hard, but i cannot imagine there is not a simpler way)

the difference is a 2d Vector right? so try getting the length using Vector2D.length() and place that length in the Y axis of the cast_to vector( i think it should be in the y )...

and for what you think about raycasts, you are kinda wrong, you can use them to do some lasers, use them for a "scanner", to shoot a bullet without shooting the bullet(like in cs go, no bullet physics)... and for geometry, its the easiest of geometry possible, and if you want some help with it take an eraseable marker and some invisible slides to draw on(like in the new minutephysics video) and draw lines and rotate and move them around, you will get it in no time if you will visualize it for yourself... dont be afraid to use probs to understand better(its actually fun when you learn and understand it properly)

Mmmmh... not sure I understood: you want me to try with$RayCast2D.cast_to(0,difference.length()) ? won´t this ray simply point down relatively to the enemy (regardless of the position of the player)?

it will point down the distance from the player, and since you rotate it to the player then it will rotate to the player(so if the distance is,in geometrical vectors,(20 units, 30 degrees)you will have a raycast pointing 20 units down,which if i recall correctly is the 0 degrees position, you will have a 20 units raycast at 30 degrees, resulting in pointing towards the player)

Maybe I express myself badly: the enemy do not always face the player, it face it only when it sees him. However, in order for it to sees him, a raycast must ALWAYS be cast from the enemy to the player, independently from enemy-player relative position and rotation

well, you can rotate only the Sprite instead of the whole scene if the enemy is round

Lol, but then the problem is reversed to find the correct angle for the sprite, knowing the scene is always rotated toward the player XD
But that´s ok, i´m quite satisfied with my solution already! Thank you for your help anyway! :)

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.