Game Development Community

Ray Casting in 2D

by Nick Gravelyn · in Torque X 2D · 10/22/2007 (7:19 pm) · 3 replies

Is there any way to do a 2D raycast in TorqueX? I have an origin, a direction, and a length and simply want to find the closest object that this ray hits. I didn't see any ray classes so I wasn't sure.

Thanks.

#1
10/23/2007 (10:03 pm)
Pickline =)
#2
10/23/2007 (10:25 pm)
The PickLine() method was great in TGB. Is there a Torque X equivalent?

John K.
#3
10/23/2007 (10:55 pm)
Unfortunately, I wasn't able to find a PickLine() method for Torque X. Someone please let me know if I'm wrong. So, I quickly coded my own version of the PickLine() method.

public List<ISceneContainerObject> PickLine(Vector2 firstPoint, Vector2 secondPoint)
{
    List<ISceneContainerObject> contacts = new List<ISceneContainerObject>();
 
    //find all of the objects within range
    T2DSceneGraph.Instance.FindObjects(firstPoint, Vector2.Distance(firstPoint, secondPoint), 
        TorqueObjectType.AllObjects, (uint)0xFFFFFFFF, contacts);
 
    //determine the angle of the raycast
    float rayAngle = T2DVectorUtil.AngleFromTarget(firstPoint, secondPoint);
 
    //now find all of the objects hit by the ray cast
    foreach (T2DSceneObject obj in contacts)
    {
        //if the object angles are different, then remove from the contacts list
        if (T2DVectorUtil.AngleFromTarget(firstPoint, obj.Position) != rayAngle)
            contacts.Remove(obj);
    }
 
    return contacts;
}

To use it, code something like this to a component. It essentially casts a ray between the component's owner and some designated target point (position 10.0x10.0 in the example). It casts the ray to find which victims will be destroyed, and then cycles through the results to mop up the bodies (MarkForDelete).

//a player component looking for other scene objects
T2DSceneObject player = Owner as T2DSceneObject;
 
//really get the crosshairs from somewhere else
Vector2 crosshairsPosition = new Vector2( 10,10);
 
//perform the ray cast between the player and crosshairs
List<ISceneContainerObject> deadEnemies = PickLine(player.Position, crosshairsPosition);
 
//everyone here is now dead
foreach( T2DSceneObject objDead in deadEnemies )
{
    //get them outta here
    objDead.MarkForDelete = true;
}

It may not be the most efficient solution in the world, but it should work. If you know how to work with layer masks, then you can add a method parameter that feeds it into FindObjects() method to speed up the initial search. I kept the code generic to search all layers to help out as many thread readers as possible.

John K.