Currently I am using a Ray class that I built myself. The following is for brevity.

public class Ray : GameObject
{
    public GameObject Shooter;
    public List<GameObject> Objects;
    public float Speed = 250f;
    public bool Collided = false;

    public void Update(){
        if (Collided) return;
        Position.X += Speed * gameTime;
        Position.Y += Speed * gameTime;

        foreach(var obj in Objects){
            if (this.Intersects(obj) {
                 obj.OnCollide(this);
                 Collided = true;
            }
        }
    }

This works, but only if I control the amount of rays, cause if I create too many rays, the game becomes laggy OR the ray/bullet get past through walls (idk why). I am trying to find out which objects that player can see and only draw the visible things, so I need to let out alot of rays. Is there a more efficient way to achieve this objective.

  • 2
    This looks more like a projectile than a ray. A projectile is an object with a position in the world that travels incrementally each frame until it hits something. By contrast, when game developers say "ray", they usually mean a line segment or infinite half-line that instantaneously checks for intersections anywhere along its length, all in one go (also sometimes termed a "hitscan" in the context of weapon mechanics). Are you trying to implement a ray for instantly scanning for collisions, or a projectile that travels gradually? – DMGregory Aug 27 at 3:41

The reason your rays seem to be passing through game objects is that with each iteration for a single ray you're jumping 250 units. Some objects may be smaller than this or have intersecting lines that are smaller than this. An easy solution is to make your ray speed smaller. Unfortunately, this will only make your game lag even more.

Another reason your rays could be passing through objects is that you're not iterating over game objects from nearest to farthest. If a collision is found that's close, then another that's far, your algorithm will end up accidentally preferring the latter. A relatively easy solution to this is to gather your objects in a second container, then sort them from closest to farthest from the start of the ray. Iterate over that and break at the first collision. Again, this will probably increase lag, especially with lots of rays at different positions.

This method is rather slow for large scenes and/or scenes with tons of game objects. A single ray can end up taking more than 1/60th of a second to process, which is when you'll notice lag. Consider your this.Intersects(obj) function. By itself, this may be very fast, but if you repeat this call thousands of times per frame, it'll become a problem.

There are many ways to make it faster, though. Here are two:

1) For each ray, don't move in steps. Use math to check if each game object collides with the whole ray at once. Eliminates having to iterate over every game object many times. Check out How to find out if a ray intersects a rectangle?.

2) Use spacial partitioning to avoid having to check every game object for any given collision detection (not just rays). This could be harder to retrofit into your game engine, but if you intend on having very large levels with many objects and don't want the game run slow, it's definitely worth the investment.

You can combine these two methods to make a much faster raycasting system. However, still be careful casting tons of rays.

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.