public static void ForEachConnection(System.Action <IStrokeConnection, Vector3> Event, StrokeCategory Category, float Distance, Vector3 CenterPosition, LayerMask Layers)
        {
            // check front,back,left,right
            IStrokeConnection TopPiece    = CheckForConnection(CenterPosition, Distance, Category, Vector3.forward, ConnectionDirection.Front, Layers, true);
            IStrokeConnection BottomPiece = CheckForConnection(CenterPosition, Distance, Category, -Vector3.forward, ConnectionDirection.Back, Layers, true);
            IStrokeConnection RightPiece  = CheckForConnection(CenterPosition, Distance, Category, Vector3.right, ConnectionDirection.Right, Layers, true);
            IStrokeConnection LeftPiece   = CheckForConnection(CenterPosition, Distance, Category, -Vector3.right, ConnectionDirection.Left, Layers, true);

            if (TopPiece != null)
            {
                Event.Invoke(TopPiece, Vector3.forward);
            }
            if (BottomPiece != null)
            {
                Event.Invoke(BottomPiece, -Vector3.forward);
            }
            if (RightPiece != null)
            {
                Event.Invoke(RightPiece, Vector3.right);
            }
            if (LeftPiece != null)
            {
                Event.Invoke(LeftPiece, -Vector3.right);
            }
        }
 public static IStrokeConnection CheckForConnection(Vector3 CenterPosition, float Distance, StrokeCategory Category, Vector3 WorldDirection, ConnectionDirection WorldConnectionDirection, LayerMask Mask, bool ShouldDebug = false, float DebugTime = 1f)
 {
     if (ShouldDebug)
     {
         Debug.DrawRay(CenterPosition, WorldDirection * Distance, Color.red, DebugTime);
     }                                       // check if should debug
     RaycastHit[] CastResults = Physics.RaycastAll(CenterPosition, WorldDirection, Distance, Mask);
     if (CastResults.Length > 0)             // check for object
     {
         for (int i = 0; i < CastResults.Length; i++)
         {
             IStrokeConnection Piece = CastResults[i].collider.transform.GetComponent <IStrokeConnection>(); // get stroke piece component of object
             if (Piece != null && Piece.StrokeCategory == Category)                                          // if is a stroke piece and of the same category
             // Check if has connection
             {
                 ConnectionDirection   InverseWorldDirection = VectorToDirection(-WorldDirection); // calculate inverse direction
                 ConnectionDirection[] WorldPieceConnections = Piece.WorldConnectionDirections;    // get world connection directions of piece
                 for (int x = 0; x < WorldPieceConnections.Length; x++)                            // check for connection match
                 {
                     if (WorldPieceConnections [x] == InverseWorldDirection)                       // found a matching connection
                     {
                         return(Piece);                                                            // return piece
                     }
                 }
             }
         }
     }
     return(null);
 }
        public static Vector3[] StrokeConnectedDirections(Vector3 CenterPosition, float Distance, StrokeCategory Category, LayerMask Layers)
        {
            List <Vector3> TempDirections = new List <Vector3> ();

            ForEachConnection((IStrokeConnection Piece, Vector3 Direction) => {
                TempDirections.Add(Direction);
            }, Category, Distance, CenterPosition, Layers);
            return(TempDirections.ToArray());
        }
        public static IStrokeConnection[] StrokeConnections(Vector3 CenterPosition, float Distance, StrokeCategory Category, LayerMask Layers)
        {
            List <IStrokeConnection> TempConnections = new List <IStrokeConnection> ();

            ForEachConnection((IStrokeConnection Piece, Vector3 Direction) => {
                TempConnections.Add(Piece);
            }, Category, Distance, CenterPosition, Layers);
            // return result as array
            return(TempConnections.ToArray());
        }
 // public calculations
 public static void UpdateStrokeState(Vector3 CenterPosition, float Distance, StrokeCategory Category, ModularStrokeSetData StrokeSet, System.Action <bool, StrokeType, int> Result, LayerMask Layers)
 {
     Vector3[]             Directions  = StrokeConnectedDirections(CenterPosition, Distance, Category, Layers); // connection directions
     ConnectionDirection[] Connections = DirectionsToConnectionDirections(Directions);                          // convert to connection directions
     GetStrokeStateInformation(CenterPosition, Distance, Connections, Directions, StrokeSet, Result);
 }