C# XNA/Monogame中的光线视线

C# XNA/Monogame中的光线视线,c#,xna,monogame,xna-4.0,C#,Xna,Monogame,Xna 4.0,我正在尝试为敌人类创建一个视线方法。然而,无论玩家离敌人有多近,或者射线是否通过任何块到达玩家,它总是返回false public virtual bool PlayerInLOS() { Vector3 middleOfPlayer = new Vector3(Level.Player.Position.X, Level.Player.Position.Y - Level.Player.BoundingRectangle.Height / 2, 0);

我正在尝试为敌人类创建一个视线方法。然而,无论玩家离敌人有多近,或者射线是否通过任何块到达玩家,它总是返回false

public virtual bool PlayerInLOS()
    {
        Vector3 middleOfPlayer = new Vector3(Level.Player.Position.X, Level.Player.Position.Y - Level.Player.BoundingRectangle.Height / 2, 0);
        Vector3 middleOfEnemy = new Vector3(Position.X, Position.Y - localBounds.Height / 2, 0);

        Vector3 direction = middleOfPlayer - middleOfEnemy;
        float distanceToPlayer = Vector3.Distance(middleOfEnemy, middleOfPlayer);

        if (direction != Vector3.Zero)
            direction.Normalize();

        Ray lineOfSight = new Ray(middleOfEnemy, direction);

        float? lineToPlayer = lineOfSight.Intersects(Level.Player.BoundingBox);

        foreach (BoundingBox box in Level.boundingBoxes)
        {
            float? distanceToIntersect = lineOfSight.Intersects(box);

            if (distanceToIntersect == null)
                continue;
            else if (distanceToIntersect < visionLength && distanceToIntersect < distanceToPlayer && distanceToIntersect != null)
                return false; 
        }

        // Never gets to this part because it always returns before it exits the for loop
        if (lineToPlayer < visionLength)
            return true;
        else return false;
    }
公共虚拟bool playerlos()
{
Vector3 middleOfPlayer=新的Vector3(Level.Player.Position.X,Level.Player.Position.Y-Level.Player.BoundingRectangle.Height/2,0);
Vector3 middleOfEnemy=新的Vector3(Position.X,Position.Y-localBounds.Height/2,0);
矢量3方向=中间层-中间层敌人;
浮动距离TopLayer=矢量3.距离(MiddleOfEnmy,MiddleOfLayer);
如果(方向!=矢量3.0)
方向。规范化();
光线视线=新光线(米德洛夫敌人,方向);
float?lineToPlayer=视线相交(Level.Player.BoundingBox);
foreach(标高中的边界框。边界框)
{
float?distanceToIntersect=视线相交(方框);
if(distanceToIntersect==null)
继续;
else if(distanceToIntersect

有什么想法吗?谢谢。

我最终解决了这个问题,实现了一个完全不同的解决方案:检查敌人和玩家之间距离上的每个矢量2。工作完美

    public bool CanSeePlayer()
    {
        Vector2 middleOfPlayer = new Vector2(Level.Player.Position.X, Level.Player.Position.Y - Level.Player.BoundingRectangle.Height / 2);
        Vector2 middleOfEnemy = new Vector2(Position.X, Position.Y - localBounds.Height / 2);

        Vector2 direction = middleOfPlayer - middleOfEnemy;
        float distanceToPlayer = Vector2.Distance(middleOfEnemy, middleOfPlayer);

        if (visionLength > distanceToPlayer) // If the enemy can see farther than the player's distance,
        {
            if (direction != Vector2.Zero)
            direction.Normalize();

            for (int y = 0; y < Level.tiles.GetLength(1); ++y) // loop through every tile, 
            {
                for (int x = 0; x < Level.tiles.GetLength(0); ++x)
                {
                    if (Level.GetCollision(x, y) != TileCollision.Passable) // and if the block is solid,
                    {
                        Vector2 currentPos = middleOfEnemy;
                        float lengthOfLine = 0.0f;

                        Rectangle tileRect = new Rectangle(x * Tile.Width, y * Tile.Height, Tile.Width, Tile.Height);

                        while (lengthOfLine < distanceToPlayer + 1.0f) // check every point along the line
                        {
                            currentPos += direction;

                            if (tileRect.Contains(currentPos)) // to see if the tile contains it.
                            {
                                return false;
                            }

                            lengthOfLine = Vector2.Distance(middleOfEnemy, currentPos);
                        }
                    }
                }
            }
            // If every tile does not contain a single point along the line from the enemy to the player,
            return true;
        }
        return false;            
    }
public bool CanSeePlayer()
{
Vector2 middleOfPlayer=新的Vector2(Level.Player.Position.X,Level.Player.Position.Y-Level.Player.BoundingRectangle.Height/2);
Vector2 middleOfEnemy=新的Vector2(Position.X,Position.Y-localBounds.Height/2);
矢量2方向=中间层-中间层敌人;
浮动距离TopLayer=矢量2.距离(MiddleOfEnmy,MiddleOfLayer);
if(visionLength>distanceToPlayer)//如果敌人能看到比玩家更远的距离,
{
如果(方向!=矢量2.0)
方向。规范化();
对于(int y=0;y
如果您需要检查敌人是否在视线范围内,并且在一定距离内,您可以尝试此代码

public static bool InLOS(float AngleDistance, float PositionDistance, Vector2 PositionA, Vector2 PositionB, float AngleB)
{
    float AngleBetween = (float)Math.Atan2((PositionA.Y - PositionB.Y), (PositionA.X - PositionB.X));
    if ((AngleBetween <= (AngleB + (AngleDistance / 2f / 100f))) && (AngleBetween >= (AngleB - (AngleDistance / 2f / 100f))) && (Vector2.Distance(PositionA, PositionB) <= PositionDistance)) return true;
    else return false;
}
public static bool InLOS(浮动角度距离、浮动位置距离、矢量2位置A、矢量2位置B、浮动角度B)
{
浮动角度介于=(浮动)数学Atan2((位置A.Y-位置B.Y),(位置A.X-位置B.X));

如果((AngleBetween=(AngleB-(AngleDistance/2f/100f))&(Vector2.距离(位置A,位置B)你做了什么调试,可能会用注释显示你调试过的地方以及发生了什么我做了相对较少的调试,因为我已经在脑海中一步一步地进行了多次,我看不出哪里会出错。我尝试在foreach循环中的if语句中进行检查,但没有改变任何东西.