Пример #1
0
    public static bool IsLayerIn(LayerTypeSelection SpecifyLayers, LayerType Layer)
    {
        LayerTypeSelection LayerCon = LayerType2LayerTypeSelection(Layer);

        //Bits are set in SpecifyLayers, doing a logical AND with the layer will return either 0 if it doesn't contain it or the layer bit itself.
        return((SpecifyLayers & LayerCon) > 0);
    }
Пример #2
0
    /// <summary>
    /// Returns all colliders found in the cone of sight
    /// Provide the direction to look and
    /// include the layers you want to test for in the hitMask
    /// </summary>
    public List <MatrixManager.CollisionHit> GetObjectsInSight(LayerMask hitMask, LayerTypeSelection hitLayers, Vector2 direction, float lengthOfSight,
                                                               int rayCount = 5)
    {
        var angleOfDir = Vector3.Angle(direction, transform.up);
        var cw         = Vector3.Cross(transform.up, direction).z < 0f;

        if (!cw)
        {
            angleOfDir = -angleOfDir;
        }

        var offsetDegrees = fieldOfView / 2f;
        List <MatrixManager.CollisionHit> hitColls = new List <MatrixManager.CollisionHit>();

        for (int i = 0; i < rayCount; i++)
        {
            var step    = (float)i / ((float)rayCount - 1);
            var offset  = Mathf.Lerp(-offsetDegrees, offsetDegrees, step);
            var castDir = (Quaternion.AngleAxis(-angleOfDir, Vector3.forward) * Quaternion.Euler(0, 0, -offset)) * Vector3.up;

            var hit = MatrixManager.RayCast(transform.position + castDir, castDir, lengthOfSight, hitLayers, hitMask);
            // Debug.DrawRay(transform.position, castDir, Color.blue, 10f);
            if (hit.ItHit)
            {
                hitColls.Add(hit.CollisionHit);
            }
        }

        return(hitColls);
    }
Пример #3
0
    /// <summary>
    /// Returns the furthest unhindered position possible in the cone of sight.
    /// A world position is returned. It is advisable to use this
    /// with matrix manager so all matricies are considered
    /// </summary>
    public Vector2 GetFurthestPositionInSight(Vector2 originWorldPos, LayerTypeSelection layerMask, LayerMask hitMask,
                                              Vector2 direction, float lengthOfSight,
                                              int rayCount = 5)
    {
        var angleOfDir = Vector3.Angle(direction, transform.up);
        var cw         = Vector3.Cross(transform.up, direction).z < 0f;

        if (!cw)
        {
            angleOfDir = -angleOfDir;
        }

        var offsetDegrees = fieldOfView / 2f;
        var furthestDist  = 0f;
        var furthestPoint = Vector2.zero;

        //First see how far the initial direction is
        var dirHit = MatrixManager.RayCast(originWorldPos, direction, lengthOfSight, layerMask, hitMask);

        //	Debug.DrawRay(originWorldPos, direction, Color.red, 10f);
        if (dirHit.ItHit == false)
        {
            furthestDist  = lengthOfSight;
            furthestPoint = originWorldPos + ((direction * lengthOfSight) - direction);
        }
        else
        {
            furthestDist  = dirHit.Distance;
            furthestPoint = originWorldPos + ((direction * dirHit.Distance) - direction);
        }

        //now test all rays in the cone of sight:
        for (int i = 0; i < rayCount; i++)
        {
            var step   = (float)i / ((float)rayCount - 1);
            var offset = Mathf.Lerp(-offsetDegrees, offsetDegrees, step);

            var castDir = (Quaternion.AngleAxis(-angleOfDir, Vector3.forward) * Quaternion.Euler(0, 0, -offset)) *
                          Vector3.up;

            var hit = MatrixManager.RayCast(originWorldPos, castDir, lengthOfSight, layerMask, hitMask);
            //	Debug.DrawRay(originWorldPos, castDir, Color.blue, 10f);
            if (hit.ItHit)
            {
                if (hit.Distance > furthestDist)
                {
                    //this ray is longer, calculate the general position:
                    furthestDist  = hit.Distance;
                    furthestPoint = originWorldPos + (Vector2)((castDir * hit.Distance) - (castDir * 1.5f));
                }
            }
        }

        return(furthestPoint);
    }
Пример #4
0
    /// <summary>
    /// Gets the topmost tile at the specified cell position , Whilst ignoring the specified tiles in the ExcludedLayers
    /// </summary>
    /// <param name="cellPosition">cell position within the tilemap to get the tile of. NOT the same
    /// as world position.</param>
    /// <returns></returns>
    public LayerTile GetTile(Vector3Int cellPosition, LayerTypeSelection ExcludedLayers)
    {
        for (var i = 0; i < LayersValues.Length; i++)
        {
            LayerTile tile = LayersValues[i].GetTile(cellPosition);
            if (tile != null)
            {
                if (LTSUtil.IsLayerIn(ExcludedLayers, tile.LayerType))
                {
                    continue;
                }

                return(tile);
            }
        }

        return(null);
    }
Пример #5
0
    /// <summary>
    /// Returns all colliders found in the cone of sight
    /// Provide the direction to look and
    /// include the layers you want to test for in the hitMask
    /// </summary>
    public List <GameObject> GetObjectsInSight(LayerMask hitMask, LayerTypeSelection hitLayers, Vector2 direction,
                                               float lengthOfSight)
    {
        var angleOfDir = Vector3.Angle(direction, transform.up);
        var cw         = Vector3.Cross(transform.up, direction).z < 0f;

        if (!cw)
        {
            angleOfDir = -angleOfDir;
        }

        var offsetDegrees          = fieldOfView / 2f;
        List <GameObject> hitColls = new List <GameObject>();

        var Hits = Physics2D.OverlapCircleAll(transform.position, lengthOfSight, hitMask);

        var v1 = transform.position +
                 (Quaternion.AngleAxis(-angleOfDir, Vector3.forward) * Quaternion.Euler(0, 0, -offsetDegrees)) *
                 Vector3.up * lengthOfSight;
        var v2 = transform.position +
                 (Quaternion.AngleAxis(-angleOfDir, Vector3.forward) * Quaternion.Euler(0, 0, offsetDegrees)) *
                 Vector3.up * lengthOfSight;


        foreach (var hit in Hits)
        {
            if (IsInsideSector(hit.transform.position.To2(), transform.position.To2(),
                               transform.position.To2() - v2.To2(), transform.position.To2() - v1.To2()))
            {
                var RayHit = MatrixManager.RayCast(transform.position, Vector2.zero, lengthOfSight, hitLayers,
                                                   WorldTo: hit.gameObject.transform.position);

                if (RayHit.ItHit == false)                 //No obstructions
                {
                    hitColls.Add(hit.gameObject);
                }
            }
        }



        return(hitColls);
    }
Пример #6
0
        /// <summary>
        /// Gets the topmost tile at the specified cell position , Whilst ignoring the specified tiles in the ExcludedLayers
        /// </summary>
        /// <param name="cellPosition">cell position within the tilemap to get the tile of. NOT the same
        /// as world position.</param>
        /// <returns></returns>
        public LayerTile GetTile(Vector3Int cellPosition, LayerTypeSelection ExcludedLayers)
        {
            TileLocation TileLcation = null;

            foreach (var layer in LayersValues)
            {
                if (layer.LayerType == LayerType.Objects)
                {
                    continue;
                }

                if (LTSUtil.IsLayerIn(ExcludedLayers, layer.LayerType))
                {
                    continue;
                }

                lock (PresentTiles)
                {
                    PresentTiles[layer].TryGetValue(cellPosition, out TileLcation);
                }

                if (TileLcation != null)
                {
                    break;
                }
            }

            return(TileLcation?.Tile);

            // for (var i = 0; i < LayersValues.Length; i++)
            // {
            // LayerTile tile = LayersValues[i].GetTile(cellPosition);
            // if (tile != null)
            // {
            // if (LTSUtil.IsLayerIn(ExcludedLayers, tile.LayerType)) continue;

            // return tile;
            // }
            // }

            // return null;
        }
Пример #7
0
    public static CustomPhysicsHit RayCast(Vector3 Worldorigin,
                                           Vector2 direction,
                                           float distance,
                                           LayerTypeSelection layerMask, LayerMask?Layermask2D = null, Vector3?WorldTo = null)
    {
        Worldorigin.z = 0;


        //TODO RRT
        //get to  from vector
        CustomPhysicsHit?ClosestHit = null;
        CustomPhysicsHit?Checkhit   = null;

        // Vector3 Localdorigin = Vector3.zero;
        // Vector3 LocalTo = Vector3.zero;

        if (WorldTo == null)
        {
            WorldTo = Worldorigin + (Vector3)(direction.normalized * distance);
        }

        if (direction.x == 0 && direction.y == 0)
        {
            direction = (WorldTo.Value - Worldorigin).normalized;
        }

        if (layerMask != LayerTypeSelection.None)
        {
            for (var i = Instance.ActiveMatrices.Count - 1; i >= 0; i--)
            {
                MatrixInfo mat = Instance.ActiveMatrices[i];
                //if (mat.Matrix == Instance.spaceMatrix) continue;
                if (LineIntersectsRect(Worldorigin, (Vector2)WorldTo, mat.WorldBounds))
                {
                    Checkhit = mat.MetaTileMap.Raycast(Worldorigin.ToLocal(mat.Matrix), Vector2.zero, distance,
                                                       layerMask,
                                                       WorldTo.Value.ToLocal(mat.Matrix));


                    if (Checkhit != null)
                    {
                        if (ClosestHit != null)
                        {
                            if (ClosestHit.Value.Distance < Checkhit.Value.Distance)
                            {
                                ClosestHit = Checkhit;
                            }
                        }
                        else
                        {
                            ClosestHit = Checkhit;
                        }
                    }
                }
            }
        }

        if (Layermask2D != null)
        {
            var Hit2D = Physics2D.Raycast(Worldorigin, direction.normalized, distance, Layermask2D.Value);
            if (ClosestHit != null)
            {
                if (Hit2D.distance != 0 && ClosestHit.Value.Distance > Hit2D.distance)
                {
                    ClosestHit = new CustomPhysicsHit(Hit2D);
                }
            }
            else
            {
                ClosestHit = new CustomPhysicsHit(Hit2D);
            }
        }

        if (ClosestHit == null)
        {
            ClosestHit = new CustomPhysicsHit();
        }

        return(ClosestHit.Value);
    }
Пример #8
0
 public static CustomPhysicsHit Linecast(Vector3 Worldorigin, LayerTypeSelection layerMask, LayerMask?Layermask2D,
                                         Vector3 WorldTo)
 {
     return(RayCast(Worldorigin, Vector2.zero, 0, layerMask, Layermask2D, WorldTo));
 }
Пример #9
0
    /// <summary>
    /// Gets the LayerTile of the tile at the indicated position, null if no tile there (open space).
    /// </summary>
    /// <param name="worldPos"></param>
    /// <returns></returns>
    public LayerTile LayerTileAt(Vector2 worldPos, LayerTypeSelection ExcludedLayers)
    {
        Vector3Int pos = objectLayer.transform.InverseTransformPoint(worldPos).RoundToInt();

        return(metaTileMap.GetTile(pos, ExcludedLayers));
    }
Пример #10
0
        //Gets the first hit
        public MatrixManager.CustomPhysicsHit? Raycast(
            Vector2 origin,
            Vector2 direction,
            float distance,
            LayerTypeSelection layerMask, Vector2? To = null)
        {
            if (To == null)
            {
                To = direction.normalized * distance;
            }

            if (direction.x == 0 && direction.y == 0)
            {
                direction = (To.Value - origin).normalized;
                distance  = (To.Value - origin).magnitude;
            }

            // var Beginning = (new Vector3((float) origin.x, (float) origin.y, 0).ToWorld(PresentMatrix));
            // Debug.DrawLine(Beginning + (Vector3.right * 0.09f), Beginning + (Vector3.left * 0.09f), Color.yellow, 30);
            // Debug.DrawLine(Beginning + (Vector3.up * 0.09f), Beginning + (Vector3.down * 0.09f), Color.yellow, 30);

            // var end = (new Vector3((float) To.Value.x, (float) To.Value.y, 0).ToWorld(PresentMatrix));
            // Debug.DrawLine(end + (Vector3.right * 0.09f), end + (Vector3.left * 0.09f), Color.red, 30);
            // Debug.DrawLine(end + (Vector3.up * 0.09f), end + (Vector3.down * 0.09f), Color.red, 30);

            // Debug.DrawLine(Beginning, end, Color.magenta, 30);


            Vector2 Relativetarget = To.Value - origin;
            //custom code on tile to ask if it aptly got hit, if you want custom geometry
//
//What needs to be returned
//What it hit, game object/tile
//Normal of hit
//Can be done quite easily since we know if me moving left or right

//Static manager
//Calculate if Within bounds of matrix?
//End and start World pos
//
//Calculate offset to then put onto positions, Maybe each position gets its own Calculation

            double RelativeX = 0;
            double RelativeY = 0;


            double gridOffsetx = 0;
            double gridOffsety = 0;

            int xSteps = 0;
            int ySteps = 0;

            int stepX = 0;
            int stepY = 0;

            double Offsetuntouchx = (origin.x - Math.Round(origin.x));
            double Offsetuntouchy = (origin.y - Math.Round(origin.y));

            if (direction.x < 0)
            {
                gridOffsetx = -(-0.5d + Offsetuntouchx); //0.5f  //this is So when you multiply it gives you 0.5 that some tile borders
                stepX       = -1;                        //For detecting which Tile it hits
            }
            else
            {
                gridOffsetx = -0.5d - Offsetuntouchx;                 //-0.5f
                stepX       = 1;
                //sideDistX = (mapX + 1.0 - posX) * deltaDistX;
            }

            if (direction.y < 0)
            {
                gridOffsety = -(-0.5d + Offsetuntouchy);                 // 0.5f
                stepY       = -1;
                //sideDistY = (posY - mapY) * deltaDistY;
            }
            else
            {
                gridOffsety = -0.5d - Offsetuntouchy;                 //-0.5f
                stepY       = 1;
                //sideDistY = (mapY + 1.0 - posY) * deltaDistY;
            }


            var          vec         = Vector3Int.zero; //Tile it hit Local  Coordinates
            var          vecHit      = Vector3.zero;    //Coordinates of Edge tile hit
            TileLocation TileLcation = null;

            var vexinvX = (1d / (direction.x));             //Editions need to be done here for Working offset
            var vexinvY = (1d / (direction.y));             //Needs to be conditional

            double calculationFloat = 0;

            bool LeftFaceHit = true;



            while (Math.Abs((xSteps + gridOffsetx + stepX) * vexinvX) < distance ||
                   Math.Abs((ySteps + gridOffsety + stepY) * vexinvY) < distance)
            //for (int Ai = 0; Ai < 6; Ai++)
            {
                //if (xBuildUp > yBuildUp)
                if ((xSteps + gridOffsetx + stepX) * vexinvX < (ySteps + gridOffsety + stepY) * vexinvY
                    )             // which one has a lesser multiplication factor since that will give a less Magnitude
                {
                    xSteps += stepX;

                    calculationFloat = ((xSteps + gridOffsetx) * vexinvX);

                    RelativeX = direction.x * calculationFloat;                     //Remove offset here maybe?
                    RelativeY = direction.y * calculationFloat;

                    LeftFaceHit = true;
                }
                //else if (xBuildUp < yBuildUp)
                else                 //if (xBuildUp < yBuildUp)
                {
                    ySteps          += stepY;
                    calculationFloat = ((ySteps + gridOffsety) * vexinvY);

                    RelativeX = direction.x * calculationFloat;
                    RelativeY = direction.y * calculationFloat;

                    LeftFaceHit = false;
                }


                vec.x = (int)Mathf.Round(origin.x) + xSteps;
                vec.y = (int)Mathf.Round(origin.y) + ySteps;

                vecHit.x = origin.x + (float)RelativeX;                  //+ offsetX;
                vecHit.y = origin.y + (float)RelativeY;                  // + offsetY;
                //Check point here

                if (LeftFaceHit)
                {
                    // float TestX = ((vecHit.x - 0.5f) - Mathf.Floor(vecHit.x));

                    // if (0.05f < Math.Abs(TestX))
                    // {
                    // Logger.Log("Offsetuntouchx = " + Offsetuntouchx + "\n" + "directionx = " + direction.x + "\n" +
                    // "Step = " + xSteps + "\n" + "vexinv = " + vexinvX + "\n" + "offset = " + offsetX +
                    // "\n" + "\n" + "Test =" + TestX + "\n" + "Relative =" + (RelativeX)
                    // + "\n" + "\n"
                    // + " direction.x = " +  direction.x + " calculationFloat " + calculationFloat
                    // + "\n" + " xSteps " + xSteps + " gridOffsetx " + gridOffsetx  +"  vexinvX " + vexinvX);


                    // }
                }
                else
                {
                    // float Testy = ((vecHit.y - 0.5f) - Mathf.Floor(vecHit.y));
                    // if (0.05f < Math.Abs(Testy))
                    // {
                    // Logger.Log("Offsetuntouchx = " + Offsetuntouchy + "\n" + "directionx = " + direction.y + "\n" +
                    // "Step = " + ySteps + "\n" + "vexinv = " + vexinvY + "\n" + "offset = " + offsetY +
                    // "\n" + "\n" + "Test =" + Testy + "\n" + "Relative =" + (RelativeY)
                    // + "\n" + "\n"
                    // + " direction.y = " +  direction.y + " calculationFloat " + calculationFloat
                    // + "\n" + " ySteps " + ySteps + " gridOffsety " + gridOffsety  +"  vexinvY " + vexinvY);
                    // }
                }

                for (var i = 0; i < LayersValues.Length; i++)
                {
                    if (LayersValues[i].LayerType == LayerType.Objects)
                    {
                        continue;
                    }
                    if (LTSUtil.IsLayerIn(layerMask, LayersValues[i].LayerType))
                    {
                        lock (PresentTiles)
                        {
                            PresentTiles[LayersValues[i]].TryGetValue(vec, out TileLcation);
                        }

                        // var wold = (vecHit.ToWorld(PresentMatrix));
                        // Debug.DrawLine(wold + (Vector3.right * 0.09f), wold + (Vector3.left * 0.09f), Color.green, 30);
                        // Debug.DrawLine(wold + (Vector3.up * 0.09f), wold + (Vector3.down * 0.09f), Color.green, 30);


                        // if (LeftFaceHit)
                        // {
                        // Debug.DrawLine(wold + (Vector3.up * 4f), wold + (Vector3.down * 4), Color.blue, 30);
                        // }
                        // else
                        // {
                        // Debug.DrawLine(wold + (Vector3.right * 4), wold + (Vector3.left * 4), Color.blue, 30);
                        // }

                        // ColorUtility.TryParseHtmlString("#ea9335", out var Orange);
                        // var map = ((Vector3) vec).ToWorld(PresentMatrix);
                        // Debug.DrawLine(map + (Vector3.right * 0.09f), map + (Vector3.left * 0.09f), Orange, 30);
                        // Debug.DrawLine(map + (Vector3.up * 0.09f), map + (Vector3.down * 0.09f), Orange, 30);

                        if (TileLcation != null)
                        {
                            Vector2 normal;

                            if (LeftFaceHit)
                            {
                                normal = Vector2.left * stepX;
                            }
                            else
                            {
                                normal = Vector2.down * stepY;
                            }


                            Vector3 AdjustedNormal = ((Vector3)normal).ToWorld(PresentMatrix);
                            AdjustedNormal = AdjustedNormal - (Vector3.zero.ToWorld(PresentMatrix));


                            // Debug.DrawLine(wold, wold + AdjustedNormal, Color.cyan, 30);

                            return(new MatrixManager.CustomPhysicsHit(((Vector3)vec).ToWorld(PresentMatrix),
                                                                      (vecHit).ToWorld(PresentMatrix), AdjustedNormal,
                                                                      new Vector2((float)RelativeX, (float)RelativeY).magnitude, TileLcation));
                        }
                    }
                }
            }
            return(null);
        }
Пример #11
0
    public static bool IsLayerIn(LayerTypeSelection SpecifyLayers, LayerType Layer)
    {
        LayerTypeSelection LayerCon = LayerType2LayerTypeSelection(Layer);

        return(SpecifyLayers.HasFlag(LayerCon));
    }