X Tutup

physics_raycast

This function casts a ray against (part of) the physics world and returns an array of structs with information on where the ray hit and what the normal is at the hitpoint.

You define the ray by providing its start and end points. Collisions are either checked between the start and end point, or from the start till a fraction of the ray (depending on the parameters passed).

The part of the physics world to check against can be a single object, a single instance or an Array containing objects and/or instances.

By default, the function only returns the closest hit, but it can return all hits if you set the all_hits parameter to true. When the parameter is set to false, the function still returns an array on a collision being found, which only contains one element.

In the returned array, each struct will represent one hitpoint, holding the following information for any given hitpoint:

Raycast Hitpoint Struct
Variable Type Description
instance Object Instance The instance that was hit.
hitpointX Real The x coordinate of the hitpoint.
hitpointY Real The y coordinate of the hitpoint.
normalX Real The x component of the normal at the hitpoint.
normalY Real The y component of the normal at the hitpoint.
fraction Real The fraction of the line segment where the hit occurred, a value from 0 to 1. 0 is at the start point, 1 is at the end point, 0.5 is in the middle, etc.

 

Syntax:

physics_raycast(x_start, y_start, x_end, y_end, ids, [all_hits], [max_fraction])

Argument Type Description
x_start Real The x coordinate of the ray's start point.
y_start Real The y coordinate of the ray's start point.
x_end Real The x coordinate of the ray's end point.
y_end Real The y coordinate of the ray's end point.
ids Object Asset or Object Instance or Array A single object asset, instance or an array containing a combination of them to check the ray against. All of them must have physics fixtures. Child objects that have physics enabled are also checked.
all_hits Boolean OPTIONAL Whether to return all the hits or only the closest. The default is false.
max_fraction Real OPTIONAL The maximum proportion of the ray to check. A value from 0 to 1. 0 is at the start point, 1 is at the end point. If this is set to, for example, 0.5 then the check is only performed from the ray's start point to its midpoint. The default is 1, meaning the ray is checked fully.

 

Returns:

Array of Raycast Hitpoint Struct if there are collisions (or undefined if the room doesn't have a physics world, when there are no physics instances or when no collisions are detected)

 

Example 1: Basic Use

Create Event

physics_world_create(0.1);
fixtures = [];

var _fix = physics_fixture_create();
physics_fixture_set_density(_fix, 0);
repeat(100)
{
    var _angle = random(360);
    var _x = random(room_width), _y = random(room_height);
    physics_fixture_set_edge_shape(_fix, _x, _y, _x + lengthdir_x(40, _angle), _y + lengthdir_y(40, _angle));
    var _fix_bound = physics_fixture_bind(_fix, id);
    array_push(fixtures, _fix_bound);
}
physics_fixture_delete(_fix);

x1 = room_width / 2; y1 = room_height / 2;
x2 = mouse_x; y2 = mouse_y;

hits = undefined;

Step Event

x2 = mouse_x; y2 = mouse_y;
hits = physics_raycast(x1, y1, x2, y2, id, true);

Draw Event

physics_world_draw_debug(phy_debug_render_shapes);
draw_line_colour(x1, y1, x2, y2, c_red, c_blue);

if (is_undefined(hits)) { exit; }

for(var i = 0;i < array_length(hits);i++)
{
    var _hit = hits[i];
    draw_line(_hit.hitpointX, _hit.hitpointY, _hit.hitpointX + _hit.normalX * 40, _hit.hitpointY + _hit.normalY * 40);
}

Clean Up Event

for(var i = 0;i < array_length(fixtures);i++) { physics_remove_fixture(id, fixtures[i]); }

The example above shows how to use the physics_raycast function.

First, in an object's Create event, a physics world is set up using physics_world_create and 100 edge-shaped fixtures are bound to it using physics_fixture_bind. After that, the fixture is deleted since it's no longer needed once the fixtures have been bound to the instance. The start and end point are initialised to the room center and the mouse position respectively, the coordinates are stored in variables x1, y1, x2 and y2. The variable hits that will hold the result of the function call is set to undefined.

In the Step event, the ray's end point is first updated and then the physics_raycast function is called. A ray is cast in the physics world from (x1, y1) to (x2, y2), checking for hits with the current instance of the object, i.e. its id. The all_hits parameter is set to true so that all hits are returned.

In the Draw event, the physics world's shapes are drawn with a call to physics_world_draw_debug and the ray itself is drawn with a call to draw_line_colour. If physics_raycast returned undefined, the Draw event is exited. If it returned results, a line is drawn for every hitpoint returned: a line 40 pixels long is drawn from the hitpoint in the direction of the normal at the hitpoint.

In the Clean Up event all bound fixtures are removed.

 

Example 2: Using the Fraction Value

Step Event

x2 = mouse_x; y2 = mouse_y;
hits = physics_raycast(x1, y1, x2, y2, id, false);

Draw Event

physics_world_draw_debug(phy_debug_render_shapes);
draw_line_colour(x1, y1, x2, y2, c_red, c_blue);

if (is_undefined(hits)) { exit; }

var _fract = hits[0].fraction;
draw_line_colour(x1, y1, x1 + _fract * (x2 - x1), y1 + _fract * (y2 - y1), c_yellow, c_yellow);

The above code shows how to use the fraction value to draw a line from the ray's start point to the hitpoint. (the object's Create and Clean Up events are the same as in Example 1)

In the Step event, the end point's coordinates are set to the mouse position. The function physics_raycast is called and casts a ray against the object, the all_hits parameter is set to false so that only the closest hit is returned.

In the Draw event, the physics world's shapes are drawn with a call to physics_world_draw_debug and the ray itself is drawn. If the function returned undefined, the Draw event is exited. If the function returned a result, it will only be one result since the all_hits parameter was set to false. So the fraction can be found in hits[0].fraction. A second, yellow line is then drawn over the ray from the start point to the point that's the fraction of the distance between the two points away from the start point. This point is at the same coordinates as the hitpoint itself, i.e. hits[0].hitpointX and hits[0].hitpointY.

 

Example 3: Checking against Multiple Objects & Instances

Step Event

hits = physics_raycast(x1, y1, x2, y2, [obj_physics_parent, obj_physics_circle, ins_physics_unique], true);

The above code shows how to call physics_raycast with an array of objects and instances. The ray is checked against all instances of child objects of obj_physics_parent, against all instances of obj_physics_circle and against the one unique instance ins_physics_unique.

 

 

X Tutup