/// <summary> /// Called when piece is colliding from its top side /// </summary> /// <param name="CollidingPieceId">Id of piece colliding with</param> /// <param name="ColP">Instance of piece colliding with</param> /// <param name="ColPPieceData">Metadata of piece colliding with</param> /// <param name="ColObjController">JPPieceController instance of piece colliding with</param> void OnTopCollision(int CollidingPieceId, GameObject ColP, SPieceInfo ColPPieceData, JPPieceController ColObjController) { //Check if this is child of current holding piece then apply collision logic bool IsChildOfHoldingPiece = false; JPPieceController[] ChildrenControllers = transform.GetComponentsInChildren <JPPieceController>(); foreach (JPPieceController item in ChildrenControllers) { if (ThisPieceData.ID == item.ThisPieceData.ID) { IsChildOfHoldingPiece = true; break; } } if (ThisPieceData.ID == JpPuzzleControllerInstance.HoldingPieceID() || IsChildOfHoldingPiece) { //Debug.Log(CollidingPieceId + "," + ThisPieceData.ID + " Top Collision"); //Get colliding piece position in grid int CPElementRow = -1; int CPElementCol = -1; PPPuzzleController.ArrayPosToRC(CollidingPieceId, JpPuzzleControllerInstance.PiecesInCol, JpPuzzleControllerInstance.PiecesInRow, out CPElementRow, out CPElementCol); //Get this piece position in grid int PElementRow = -1; int PElementCol = -1; PPPuzzleController.ArrayPosToRC(ThisPieceData.ID, JpPuzzleControllerInstance.PiecesInCol, JpPuzzleControllerInstance.PiecesInRow, out PElementRow, out PElementCol); if (ThisPieceData.ID < CollidingPieceId && PElementCol == CPElementCol && PElementRow == CPElementRow - 1) { //If is child of holding piece make it parent //Make this piece parent of all Transform Temp = transform.root; transform.parent = null; Temp.parent = transform; JpPuzzleControllerInstance.UnholdPiece(); transform.position = new Vector3(ColP.transform.position.x, ColP.transform.position.y - JpPuzzleControllerInstance.PieceHeightInWorld, ColP.transform.position.z); ColP.transform.root.parent = transform; OnPieceJoined(); CheckForPuzzleComplete(transform); } } }
/// <summary> /// Called when piece is colliding from its right side /// </summary> /// <param name="CollidingPieceId">Id of piece colliding with</param> /// <param name="ColP">Instance of piece colliding with</param> /// <param name="ColPPieceData">Metadata of piece colliding with</param> /// <param name="ColObjController">JPPieceController instance of piece colliding with</param> void OnRightCollision(int CollidingPieceId, GameObject ColP, SPieceInfo ColPPieceData, JPPieceController ColObjController) { //Check if this is child of current holding piece then apply collision logic bool IsChildOfHoldingPiece = false; JPPieceController[] ChildrenControllers = transform.GetComponentsInChildren <JPPieceController>(); foreach (JPPieceController item in ChildrenControllers) { if (ThisPieceData.ID == item.ThisPieceData.ID) { IsChildOfHoldingPiece = true; break; } } if (ThisPieceData.ID == JpPuzzleControllerInstance.HoldingPieceID() || IsChildOfHoldingPiece) { if (ThisPieceData.ID == CollidingPieceId - 1) { //If is child of holding piece make it parent //Make this piece parent of all Transform Temp = transform.root; transform.parent = null; Temp.parent = transform; JpPuzzleControllerInstance.UnholdPiece(); transform.position = new Vector3(ColP.transform.position.x - JpPuzzleControllerInstance.PieceWidthInWorld, ColP.transform.position.y, ColP.transform.position.z); ColP.transform.root.parent = transform; OnPieceJoined(); CheckForPuzzleComplete(transform); } } else { //Wrong Piece } }
/// <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(); } } } }
/// <summary> /// Generates jigsaw puzzle and initialize pieces with data according to user selected options /// </summary> /// <returns>Coroutine</returns> public virtual IEnumerator Start() { if (!UseFilePath) { _puzzlePieceMaker = new PuzzlePieceMaker(PuzzleImage, JointMaskImage, PiecesInRow, PiecesInCol); //Enable below code and provide a file path to save data created by _puzzlemaker class using provided image //_PuzzleMaker.SaveData("File Path here e.g c:\\Images\\Temp.pm"); } else { if (PuzzlePieceMaker.IsPMFileSupportedPlatform()) { try { _puzzlePieceMaker = new PuzzlePieceMaker(PMFilePath); PiecesInCol = _puzzlePieceMaker.NoOfPiecesInCol; PiecesInRow = _puzzlePieceMaker.NoOfPiecesInRow; _isFileLoadingComplete = true; } catch (System.Exception e) { Debug.LogError("Please check if you have provided correct file path : " + e.Message); Destroy(gameObject); yield break; } } else if (Application.platform == RuntimePlatform.WebGLPlayer || Application.platform == RuntimePlatform.WindowsWebPlayer) { WebPmFileLoader Temp = GetComponent <WebPmFileLoader>(); if (Temp != null) { yield return(StartCoroutine(Temp.LoadFileToStream(PMFilePath))); if (Temp.PMFileStream != null) { _puzzlePieceMaker = new PuzzlePieceMaker(Temp.PMFileStream); PiecesInCol = _puzzlePieceMaker.NoOfPiecesInCol; PiecesInRow = _puzzlePieceMaker.NoOfPiecesInRow; _isFileLoadingComplete = true; } else { Debug.LogError("File loading failed"); yield break; } } else { Debug.LogError("Prefab not set correctly"); } } } yield return(new WaitForEndOfFrame()); //Get main instance of puzzle piece _puzzlePieceInst = gameObject.transform.FindChild("Piece").gameObject; //Set puzzle image to Puzzle piece instance _puzzlePieceInst.GetComponent <Renderer>().material.mainTexture = _puzzlePieceMaker.PuzzleImage; //Seperate from cam for cam resizing to adjust whole puzzle in cam view parentCamTransform = gameObject.transform.parent; parentCam = parentCamTransform.GetComponent <Camera>(); gameObject.transform.parent = null; //Set background if (DisplayCompletedImage) { GetComponent <Renderer>().enabled = true; GetComponent <Renderer>().material.mainTexture = _puzzlePieceMaker.CreatedBackgroundImage; } //Resize gameobject to match size for pieces transform.localScale = new Vector3((float)PiecesInRow, (PiecesInCol * ((float)PuzzleImage.height / (float)PuzzleImage.width)), 1f); //Translate to zero transform.position = Vector3.zero; transform.rotation = Quaternion.Euler(Vector3.zero); //Initialize all pieces and joints resize them and place them on screen randomly _puzzlePieces = new GameObject[PiecesInRow * PiecesInCol]; //Scale piece according to puzzle float PieceScaleX = 1; float PieceScaleY = 1 * ((float)_puzzlePieceMaker.PuzzleImageHeight / (float)_puzzlePieceMaker.PuzzleImageWidth); _puzzlePieceInst.transform.localScale = new Vector3(PieceScaleX, PieceScaleY, 1); //Create joints instances for each side from _puzzle piece GameObject _leftJointInst = Object.Instantiate(_puzzlePieceInst) as GameObject; Component[] AllCompoenents = _leftJointInst.GetComponents <Component>(); foreach (Component item in AllCompoenents) { if (!(item is Renderer || item is Transform || item is MeshFilter)) { Destroy(item); } } yield return(new WaitForEndOfFrame()); GameObject _rightJointInst = Object.Instantiate(_leftJointInst) as GameObject; GameObject _topJointInst = Object.Instantiate(_leftJointInst) as GameObject; GameObject _bottomJointInst = Object.Instantiate(_leftJointInst) as GameObject; //Initialize joints instances _leftJointInst.GetComponent <Renderer>().material.mainTexture = _puzzlePieceMaker.LeftJointsMaskImage; _rightJointInst.GetComponent <Renderer>().material.mainTexture = _puzzlePieceMaker.RightJointsMaskImage; _topJointInst.GetComponent <Renderer>().material.mainTexture = _puzzlePieceMaker.TopJointsMaskImage; _bottomJointInst.GetComponent <Renderer>().material.mainTexture = _puzzlePieceMaker.BotJointsMaskImage; //Name joints _leftJointInst.name = "LeftJoint"; _rightJointInst.name = "RightJoint"; _topJointInst.name = "TopJoint"; _bottomJointInst.name = "BottomJoint"; //Position joints float JointWidth = _leftJointInst.transform.localScale.x; float JointHeight = _leftJointInst.transform.localScale.y; //Make joints child of piece _leftJointInst.transform.parent = _puzzlePieceInst.transform; _leftJointInst.transform.localScale = Vector3.one; _leftJointInst.SetActive(true); _rightJointInst.transform.parent = _puzzlePieceInst.transform; _rightJointInst.transform.localScale = Vector3.one; _rightJointInst.SetActive(true); _topJointInst.transform.parent = _puzzlePieceInst.transform; _topJointInst.transform.localScale = Vector3.one; _topJointInst.SetActive(true); _bottomJointInst.transform.parent = _puzzlePieceInst.transform; _bottomJointInst.transform.localScale = Vector3.one; _bottomJointInst.SetActive(true); //Position joints _leftJointInst.transform.localPosition = new Vector3(-1, 0, 0); _rightJointInst.transform.localPosition = new Vector3(1, 0, 0); _topJointInst.transform.localPosition = new Vector3(0, 1, 0); _bottomJointInst.transform.localPosition = new Vector3(0, -1, 0); //Initialize pieces for (int RowTrav = 0; RowTrav < PiecesInCol; RowTrav++) { for (int ColTrav = 0; ColTrav < PiecesInRow; ColTrav++) { GameObject Temp = Object.Instantiate(_puzzlePieceInst) as GameObject; //Name for this piece Temp.name = "Piece" + ((RowTrav * PiecesInRow) + ColTrav).ToString(); SetPuzzlePieceUV(Temp, ColTrav, RowTrav, PiecesInCol, PiecesInRow); //Enable piece Temp.SetActive(true); SPieceInfo ThisPieceData = _puzzlePieceMaker._CreatedPiecesData[RowTrav, ColTrav]; bool TempOut = false; bool HaveTopJoint = ThisPieceData.HaveJoint(EJointPosition.Top); if (HaveTopJoint) { HaveTopJoint = ThisPieceData.GetJoint(EJointPosition.Top, out TempOut).JointType != EJointType.Female; } bool HaveBotJoint = ThisPieceData.HaveJoint(EJointPosition.Bottom); if (HaveBotJoint) { HaveBotJoint = ThisPieceData.GetJoint(EJointPosition.Bottom, out TempOut).JointType != EJointType.Female; } bool HaveLeftJoint = ThisPieceData.HaveJoint(EJointPosition.Left); if (HaveLeftJoint) { HaveLeftJoint = ThisPieceData.GetJoint(EJointPosition.Left, out TempOut).JointType != EJointType.Female; } bool HaveRightJoint = ThisPieceData.HaveJoint(EJointPosition.Right); if (HaveRightJoint) { HaveRightJoint = ThisPieceData.GetJoint(EJointPosition.Right, out TempOut).JointType != EJointType.Female; } //Set joints uvs Transform LeftJoint = Temp.transform.FindChild("LeftJoint"); if (HaveLeftJoint && ColTrav > 0) { SetPuzzlePieceUV(LeftJoint.gameObject, ColTrav - 1, RowTrav, PiecesInCol, PiecesInRow); } else { LeftJoint.gameObject.SetActive(false); } Transform RightJoint = Temp.transform.FindChild("RightJoint"); if (HaveRightJoint && ColTrav < PiecesInCol - 1) { SetPuzzlePieceUV(RightJoint.gameObject, ColTrav + 1, RowTrav, PiecesInCol, PiecesInRow); } else { RightJoint.gameObject.SetActive(false); } Transform TopJoint = Temp.transform.FindChild("TopJoint"); if (HaveTopJoint && RowTrav < PiecesInRow - 1) { SetPuzzlePieceUV(TopJoint.gameObject, ColTrav, RowTrav + 1, PiecesInCol, PiecesInRow); } else { TopJoint.gameObject.SetActive(false); } Transform BotJoint = Temp.transform.FindChild("BottomJoint"); if (HaveBotJoint && RowTrav > 0) { SetPuzzlePieceUV(BotJoint.gameObject, ColTrav, RowTrav - 1, PiecesInCol, PiecesInRow); } else { BotJoint.gameObject.SetActive(false); } _puzzlePieces[(RowTrav * PiecesInRow) + ColTrav] = Temp; } } }
void Start() { if (!UseFilePath) { //random image selection PuzzleImage = new Texture2D(1, 1); PuzzleImage.LoadImage(File.ReadAllBytes(getPath() + "/dewa/" + Random.Range(0, 6) + ".jpg")); //Debug.Log(getPath()+ "/Puzzle Maker/PM Free Images/dewa/" + "1" + ".jpg"); //Random.Range(0, 3) //KIDS PUZZLE IMAGES //Random.Range(3,6) //ADULTS PUZZLE IMAGES _PuzzleMaker = new PuzzlePieceMaker(PuzzleImage, JointMaskImage, PiecesInRow, PiecesInCol); //Enable below code and provide a file path to save data created by _puzzlemaker class using provided image //_PuzzleMaker.SaveData("File Path here e.g c:\\Images\\Temp.pm"); } else { try { _PuzzleMaker = new PuzzlePieceMaker(PMFilePath); PiecesInCol = _PuzzleMaker.NoOfPiecesInCol; PiecesInRow = _PuzzleMaker.NoOfPiecesInRow; } catch (System.Exception e) { Debug.LogError("Please check if you have provided correct file path : " + e.Message); Destroy(gameObject); return; } } //Get main instance of puzzle piece _jpPuzzlePieceInst = gameObject.transform.FindChild("JPPiece").gameObject; //Seperate from cam for cam resizing to adjust whole puzzle in cam view Transform parentCamTransform = gameObject.transform.parent; Camera parentCam = parentCamTransform.GetComponent <Camera>(); gameObject.transform.parent = null; //Store current transform and translate to origin for everythings placement Vector3 OrigionalScale = transform.localScale; Vector3 OrigionalPosition = transform.position; Vector3 OrigionalRotation = transform.localRotation.eulerAngles; //Set background if (DisplayCompletedImage) { GetComponent <Renderer>().enabled = true; GetComponent <Renderer>().material.mainTexture = _PuzzleMaker.CreatedBackgroundImage; } //Resize gameobject to match size for pieces transform.localScale = new Vector3((float)PiecesInRow, (PiecesInCol * ((float)PuzzleImage.height / (float)PuzzleImage.width)), 1f); //Translate to zero transform.position = new Vector3(0, 0, 0); transform.rotation = Quaternion.Euler(Vector3.zero); #region "Pieces Initialization And Placement" //Initialize all pieces resize them and place them on screen randomly _PuzzlePieces = new GameObject[PiecesInRow * PiecesInCol]; Random.seed = System.DateTime.Now.Millisecond; for (int RowTrav = 0; RowTrav < PiecesInCol; RowTrav++) { for (int ColTrav = 0; ColTrav < PiecesInRow; ColTrav++) { GameObject Temp = Object.Instantiate(_jpPuzzlePieceInst) as GameObject; //AudioSettings name for this piece Temp.name = "Piece" + ((RowTrav * PiecesInRow) + ColTrav).ToString(); Texture2D Img = _PuzzleMaker._CreatedImagePiecesData[RowTrav, ColTrav].PieceImage; float PieceScaleX = (float)Img.width / (float)_PuzzleMaker.PieceWidthWithoutJoint; float PieceScaleY = this.PieceHeightInWorld * ((float)Img.height / (float)_PuzzleMaker.PieceHeightWithoutJoint); JPPieceController TempPieceControllerInst = Temp.GetComponent <JPPieceController>(); TempPieceControllerInst.JpPuzzleControllerInstance = this; //Get this piece information SPieceInfo ThisPieceData = _PuzzleMaker._CreatedImagePiecesData[RowTrav, ColTrav].PieceMetaData.MakeCopy(); TempPieceControllerInst.ThisPieceData = ThisPieceData; //Assign image to piece Temp.GetComponent <Renderer>().material.mainTexture = Img; //Resize piece in world Temp.transform.localScale = new Vector3(PieceScaleX, PieceScaleY, 1); //Position pieces randomly on screen Vector3 CalcPosition = Camera.main.ScreenToWorldPoint( new Vector3(Random.Range(_PuzzleMaker.PieceWidthWithoutJoint, Screen.width - _PuzzleMaker.PieceWidthWithoutJoint), Random.Range(_PuzzleMaker.PieceHeightWithoutJoint, Screen.height - _PuzzleMaker.PieceHeightWithoutJoint), 0)); CalcPosition.z = transform.position.z - 0.4f; Temp.transform.position = CalcPosition; //Enable collider for this piece Temp.GetComponent <BoxCollider>().enabled = true; TempPieceControllerInst.enabled = true; //Enable piece Temp.SetActive(true); _PuzzlePieces[(RowTrav * PiecesInRow) + ColTrav] = Temp; } } #endregion #region "Camera Resizing And Placement" //Resize camera to display whole puzzle in camera view float widthToBeSeen = PiecesInRow * PieceWidthInWorld; float heightToBeSeen = PiecesInCol * PieceHeightInWorld; parentCam.orthographicSize = widthToBeSeen > heightToBeSeen ? widthToBeSeen * 0.4f : heightToBeSeen * 0.4f; //Position camera in centre of puzzle //float CalcCameraX = ; //float CalcCameraY = ; //parentCamTransform.position = new Vector3(CalcCameraX, CalcCameraY, _pieceInstances[1][0].transform.position.z - 3); parentCamTransform.position = new Vector3(0, 0, transform.position.z - 10); #endregion }
/// <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) { //Enable next piece if display mode one piece at a time if (PiecesDisplayMode == EPieceDisplayMode.ShowOnePieceAtATime) { foreach (GameObject item in _puzzlePieces) { if (!item.activeSelf) { //Randomly activate a piece int RndIndex = 0; while (_puzzlePieces[RndIndex].activeSelf) { RndIndex = Random.Range(0, _puzzlePieces.Length); } _puzzlePieces[RndIndex].SetActive(true); break; } } } else if (PiecesDisplayMode == EPieceDisplayMode.LeftSliderWithPieces) { _gameObjectsVerticleSliderInst.Remove(_CurrentHoldingPiece); } 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 = _puzzlePieceMaker._CreatedPiecesData[PieceRow, PieceCol]; // _CurrentHoldingPiece.transform.position = _ChildColliders[ObjNum].transform.position; _CurrentHoldingPiece.transform.position = _ChildColliders[ObjNum].transform.position; //Disable this piece _CurrentHoldingPiece.GetComponent <CharacterController>().enabled = false; //Call event function E_OnPiecePlaced(_CurrentHoldingPiece, ObjNum); OnPiecePlaced.Invoke(); _CurrentHoldingPiece = null; //Update trackers _NoOfPiecesPlaced++; if (_NoOfPiecesPlaced >= _puzzlePieces.Length) { _audioManager.PlaySFXSound(PuzzleCompletionSound); OnPuzzleComplete.Invoke(); if (ActualImageOnPuzzleComplete) { HideAllPieces(); _actualImageGameObject.SetActive(true); } } else { _audioManager.PlaySFXSound(PiecePlacedSound); } } } }
void OnRightCollision(int CollidingPieceId, GameObject ColP, SPieceInfo ColPPieceData, JPPieceController ColObjController) { //Check if this is child of current holding piece then apply collision logic bool IsChildOfHoldingPiece = false; JPPieceController[] ChildrenControllers = transform.GetComponentsInChildren <JPPieceController>(); foreach (JPPieceController item in ChildrenControllers) { if (ThisPieceData.ID == item.ThisPieceData.ID) { IsChildOfHoldingPiece = true; break; } } if (ThisPieceData.ID == JpPuzzleControllerInstance.HoldingPieceID() || IsChildOfHoldingPiece) { if (ThisPieceData.ID == CollidingPieceId - 1) { //If is child of holding piece make it parent //Make this piece parent of all Transform Temp = transform.root; transform.parent = null; Temp.parent = transform; JpPuzzleControllerInstance.UnholdPiece(); Vector3 CalculatedPos = new Vector3(); float LeftJointWorldScale = 0; float RightJointWorldScale = 0; float TopJointWorldScale = 0; float BotJointWorldScale = 0; float ColPLeftJointWorldScale = 0; float ColPRightJointWorldScale = 0; float ColPTopJointWorldScale = 0; float ColPBotJointWorldScale = 0; //Calculate required data CalculateDataForCollisionPlacement(ColPPieceData, out ColPLeftJointWorldScale, out ColPRightJointWorldScale, out ColPTopJointWorldScale, out ColPBotJointWorldScale); CalculateDataForCollisionPlacement(ThisPieceData, out LeftJointWorldScale, out RightJointWorldScale, out TopJointWorldScale, out BotJointWorldScale); //Calculate X //Calculated X without joints float CalcXWJ = ColP.transform.position.x - JpPuzzleControllerInstance.PieceWidthInWorld; CalculatedPos.x = CalcXWJ - (ColPRightJointWorldScale / 2) + (ColPLeftJointWorldScale / 2) + (RightJointWorldScale / 2) - (LeftJointWorldScale / 2); //Calculate Y CalculatedPos.y = ColP.transform.position.y + (TopJointWorldScale / 2) - (BotJointWorldScale / 2) - (ColPTopJointWorldScale / 2) + (ColPBotJointWorldScale / 2); CalculatedPos.z = transform.position.z; transform.position = CalculatedPos; ColP.transform.root.parent = transform; CheckForPuzzleComplete(transform); } } }
void OnBottomCollision(int CollidingPieceId, GameObject ColP, SPieceInfo ColPPieceData, JPPieceController ColObjController) { //Check if this is child of current holding piece then apply collision logic bool IsChildOfHoldingPiece = false; JPPieceController[] ChildrenControllers = transform.GetComponentsInChildren <JPPieceController>(); foreach (JPPieceController item in ChildrenControllers) { if (ThisPieceData.ID == item.ThisPieceData.ID) { IsChildOfHoldingPiece = true; break; } } if (ThisPieceData.ID == JpPuzzleControllerInstance.HoldingPieceID() || IsChildOfHoldingPiece) { //Get colliding piece position in grid int CPElementRow = 0; int CPElementCol = 0; PPPuzzleController.ArrayPosToRC(CollidingPieceId, JpPuzzleControllerInstance.PiecesInCol, JpPuzzleControllerInstance.PiecesInRow, out CPElementRow, out CPElementCol); //Get this piece position in grid int PElementRow = 0; int PElementCol = 0; PPPuzzleController.ArrayPosToRC(ThisPieceData.ID, JpPuzzleControllerInstance.PiecesInCol, JpPuzzleControllerInstance.PiecesInRow, out PElementRow, out PElementCol); if (ThisPieceData.ID > CollidingPieceId && PElementCol == CPElementCol && PElementRow == CPElementRow + 1) { //If is child of holding piece make it parent //Make this piece parent of all Transform Temp = transform.root; transform.parent = null; Temp.parent = transform; JpPuzzleControllerInstance.UnholdPiece(); Vector3 CalculatedPos = new Vector3(); float LeftJointWorldScale = 0; float RightJointWorldScale = 0; float TopJointWorldScale = 0; float BotJointWorldScale = 0; float ColPLeftJointWorldScale = 0; float ColPRightJointWorldScale = 0; float ColPTopJointWorldScale = 0; float ColPBotJointWorldScale = 0; //Calculate required data CalculateDataForCollisionPlacement(ColPPieceData, out ColPLeftJointWorldScale, out ColPRightJointWorldScale, out ColPTopJointWorldScale, out ColPBotJointWorldScale); CalculateDataForCollisionPlacement(ThisPieceData, out LeftJointWorldScale, out RightJointWorldScale, out TopJointWorldScale, out BotJointWorldScale); //Calculate X CalculatedPos.x = ColP.transform.position.x - (ColPRightJointWorldScale / 2) + (ColPLeftJointWorldScale / 2) + (RightJointWorldScale / 2) - (LeftJointWorldScale / 2); //Calculate Y float CalcYWJ = ColP.transform.position.y + JpPuzzleControllerInstance.PieceHeightInWorld; CalculatedPos.y = CalcYWJ + (TopJointWorldScale / 2) - (BotJointWorldScale / 2) - (ColPTopJointWorldScale / 2) + (ColPBotJointWorldScale / 2); CalculatedPos.z = transform.position.z; transform.position = CalculatedPos; ColP.transform.root.parent = transform; CheckForPuzzleComplete(transform); } } }
/// <summary> /// UnityMethod: Initialize actual image mesh and handle camera resizing and placement /// </summary> /// <returns>Coroutine</returns> public override IEnumerator Start() { if (BackgroundMusic != null) { _audioManager.PlayMusic(BackgroundMusic); } yield return(StartCoroutine(base.Start())); #region "Pieces Initialization And Placement" Random.seed = System.DateTime.Now.Millisecond; //Place pieces randomly on screen and scale them accordingly for (int RowTrav = 0; RowTrav < PiecesInCol; RowTrav++) { for (int ColTrav = 0; ColTrav < PiecesInRow; ColTrav++) { GameObject Temp = _puzzlePieces[(RowTrav * PiecesInRow) + ColTrav]; JPPieceController TempPieceControllerInst = Temp.GetComponent <JPPieceController>(); TempPieceControllerInst.JpPuzzleControllerInstance = this; //Get this piece information SPieceInfo ThisPieceData = _puzzlePieceMaker._CreatedPiecesData[RowTrav, ColTrav].MakeCopy(); TempPieceControllerInst.ThisPieceData = ThisPieceData; //Position pieces randomly on screen Vector3 CalcPosition = Camera.main.ScreenToWorldPoint( new Vector3(Random.Range(_puzzlePieceMaker.PieceWidthWithoutJoint, Screen.width - _puzzlePieceMaker.PieceWidthWithoutJoint), Random.Range(_puzzlePieceMaker.PieceHeightWithoutJoint, Screen.height - _puzzlePieceMaker.PieceHeightWithoutJoint), 0)); CalcPosition.z = transform.position.z - 0.4f; Temp.transform.position = CalcPosition; //Enable collider for this piece Temp.GetComponent <BoxCollider>().enabled = true; TempPieceControllerInst.enabled = true; //Enable piece Temp.SetActive(true); } } #endregion //If have to display single mesh on puzzle completion set that mesh if (ActualImageOnPuzzleComplete) { GameObject ActualImagePrefab = Resources.Load("TestBackgroundImage", typeof(GameObject)) as GameObject; _actualImageGameObject = Instantiate(ActualImagePrefab); //_actualImageGameObject = GameObject.CreatePrimitive(PrimitiveType.Quad); _actualImageGameObject.transform.position = new Vector3(transform.position.x, transform.position.y, transform.position.z - 1); _actualImageGameObject.transform.localScale = transform.localScale; _actualImageGameObject.AddComponent <ActualImageObjController>(); _actualImageGameObject.name = "ActualPuzzleImage"; _actualImageGameObject.GetComponent <Renderer>().material.mainTexture = _puzzlePieceMaker.PuzzleOrigionalImage; _actualImageGameObject.AddComponent <BoxCollider>(); _actualImageGameObject.SetActive(false); } #region "Camera Resizing And Placement" //Resize camera to display whole puzzle in camera view float widthToBeSeen = PiecesInRow * PieceWidthInWorld; float heightToBeSeen = PiecesInCol * PieceHeightInWorld; parentCam.orthographicSize = widthToBeSeen > heightToBeSeen ? widthToBeSeen * 0.4f : heightToBeSeen * 0.4f; //Position camera in centre of puzzle //float CalcCameraX = ; //float CalcCameraY = ; //parentCamTransform.position = new Vector3(CalcCameraX, CalcCameraY, _pieceInstances[1][0].transform.position.z - 3); parentCamTransform.position = new Vector3(0, 0, transform.position.z - 10); #endregion }