/// <summary>
    /// Used to calculate required data for joining of pieces together
    /// </summary>
    void CalculateDataForCollisionPlacement(SPieceInfo PieceData, out float LeftJointWorldScale, out float RightJointWorldScale,
                                            out float TopJointWorldScale, out float BottomJointWorldScale)
    {
        bool LeftJointPresent  = false;
        bool RightJointPresent = false;
        bool TopJointPresent   = false;
        bool BotJointPresent   = false;

        SJointInfo TempLeftJointInfo  = PieceData.GetJoint(EJointPosition.Left, out LeftJointPresent);
        SJointInfo TempRightJointInfo = PieceData.GetJoint(EJointPosition.Right, out RightJointPresent);
        SJointInfo TempTopJointInfo   = PieceData.GetJoint(EJointPosition.Top, out TopJointPresent);
        SJointInfo TempBotJointInfo   = PieceData.GetJoint(EJointPosition.Bottom, out BotJointPresent);

        float PMPieceWidthWOJoint = (float)JpPuzzleControllerInstance.PuzzleMakerPieceWidthWithoutJoint;

        LeftJointWorldScale = LeftJointPresent && TempLeftJointInfo.JointType == EJointType.Male ?
                              (float)TempLeftJointInfo.JointWidth / PMPieceWidthWOJoint : 0;
        RightJointWorldScale = RightJointPresent && TempRightJointInfo.JointType == EJointType.Male ?
                               (float)TempRightJointInfo.JointWidth / PMPieceWidthWOJoint : 0;
        TopJointWorldScale = TopJointPresent && TempTopJointInfo.JointType == EJointType.Male ?
                             (float)TempTopJointInfo.JointHeight / PMPieceWidthWOJoint : 0;
        BottomJointWorldScale = BotJointPresent && TempBotJointInfo.JointType == EJointType.Male ?
                                (float)TempBotJointInfo.JointHeight / PMPieceWidthWOJoint : 0;
    }
    /// <summary>
    /// This method is called throw SendMessage from piece when it collides with appropriate collider for its placement.
    /// </summary>
    /// <param name="ObjNum">Number of collider this piece found its place with</param>
    private void PiecePlaceFound(int ObjNum)
    {
        if (_CurrentHoldingPiece != null)
        {
            int PieceRow = 0;
            int PieceCol = 0;

            if (ArrayPosToRC(ObjNum, PiecesInCol, PiecesInRow, out PieceRow, out PieceCol))
            {
                //Get this piece joints information for placement position calculation
                SPieceInfo TempPieceInfo = _PuzzleMaker._CreatedImagePiecesData[PieceRow, PieceCol].PieceMetaData;

                SJointInfo[] TempJointsInfo = TempPieceInfo.GetJoints();

                Vector3 PieceColliderPosition = _ChildColliders[ObjNum].transform.position;

                Vector3 CalculatedPosition = new Vector3();


                #region "Calculate Adjusted X Position For Piece Placement"

                // Calculate X Position
                // Default scaleX of piece is 1 in world
                bool LeftJointPresent  = false;
                bool RightJointPresent = false;

                SJointInfo TempLeftJointInfo  = TempPieceInfo.GetJoint(EJointPosition.Left, out LeftJointPresent);
                SJointInfo TempRightJointInfo = TempPieceInfo.GetJoint(EJointPosition.Right, out RightJointPresent);

                EJointType TempLeftJointType  = TempLeftJointInfo.JointType;
                EJointType TempRightJointType = TempRightJointInfo.JointType;

                float LeftJointWorldScale  = (float)TempLeftJointInfo.JointWidth / (float)_PuzzleMaker.PieceWidthWithoutJoint;
                float RightJointWorldScale = (float)TempRightJointInfo.JointWidth / (float)_PuzzleMaker.PieceWidthWithoutJoint;

                if (LeftJointPresent && RightJointPresent && TempLeftJointType == EJointType.Male && TempRightJointType == EJointType.Male)
                {
                    CalculatedPosition.x = _ChildColliders[ObjNum].transform.position.x + (RightJointWorldScale / 2) - (LeftJointWorldScale / 2);
                }
                else if (LeftJointPresent && TempLeftJointType == EJointType.Male)
                {
                    CalculatedPosition.x = _ChildColliders[ObjNum].transform.position.x - (LeftJointWorldScale / 2f);
                }
                else if (RightJointPresent && TempRightJointType == EJointType.Male)
                {
                    CalculatedPosition.x = _ChildColliders[ObjNum].transform.position.x + (RightJointWorldScale / 2f);
                }
                else
                {
                    CalculatedPosition.x = _ChildColliders[ObjNum].transform.position.x;
                }

                #endregion

                #region "Calculate Adjusted Y Position For Piece Placement"

                // Calculate Y Position
                // Default scaleY of piece is calculated with aspect ratio of image and ScaleX = 1

                bool TopJointPresent    = false;
                bool BottomJointPresent = false;

                SJointInfo TempTopJointInfo    = TempPieceInfo.GetJoint(EJointPosition.Top, out TopJointPresent);
                SJointInfo TempBottomJointInfo = TempPieceInfo.GetJoint(EJointPosition.Bottom, out BottomJointPresent);

                EJointType TempTopJointType    = TempTopJointInfo.JointType;
                EJointType TempBottomJointType = TempBottomJointInfo.JointType;

                float TopJointWorldScale    = (float)TempTopJointInfo.JointHeight / (float)_PuzzleMaker.PieceWidthWithoutJoint;
                float BottomJointWorldScale = (float)TempBottomJointInfo.JointHeight / (float)_PuzzleMaker.PieceWidthWithoutJoint;


                if (TopJointPresent && BottomJointPresent && TempTopJointType == EJointType.Male && TempBottomJointType == EJointType.Male)
                {
                    CalculatedPosition.y = _ChildColliders[ObjNum].transform.position.y + (TopJointWorldScale / 2) - (BottomJointWorldScale / 2);
                }
                else if (TopJointPresent && TempTopJointType == EJointType.Male)
                {
                    CalculatedPosition.y = _ChildColliders[ObjNum].transform.position.y + (TopJointWorldScale / 2);
                }
                else if (BottomJointPresent && TempBottomJointType == EJointType.Male)
                {
                    CalculatedPosition.y = _ChildColliders[ObjNum].transform.position.y - (BottomJointWorldScale / 2);
                }
                else
                {
                    CalculatedPosition.y = _ChildColliders[ObjNum].transform.position.y;
                }

                #endregion


                // Z position
                CalculatedPosition.z = _ChildColliders[ObjNum].transform.position.z;


                // _CurrentHoldingPiece.transform.position = _ChildColliders[ObjNum].transform.position;
                _CurrentHoldingPiece.transform.position = CalculatedPosition;

                //Disable this piece
                _CurrentHoldingPiece.GetComponent <CharacterController>().enabled = false;

                //Call event function
                OnPiecePlaced(_CurrentHoldingPiece, ObjNum);

                _CurrentHoldingPiece = null;

                //Update trackers
                _NoOfPiecesPlaced++;

                //Check for Puzzle complete
                if (_NoOfPiecesPlaced >= _PuzzlePieces.Length)
                {
                    OnPuzzleComplete();
                }
            }
        }
    }