public void initiate(PuzzlePieceInfo piece, Texture2D outLine, Texture2D theImage) { if(!initiated) { //set object's texture to puzzle-piece shaped highlight Color mainImageColor; //Set Up myPuzzlePiece = new PuzzlePieceInfo(); puzzleOutline = outLine; mainImageTexture = theImage; myPuzzlePiece = piece; // Debug.Log(pictureTexture.width); // Debug.Log(pictureTexture.height); // // Debug.Log("w "+outLine.width); // Debug.Log("h "+outLine.height); //Where does the texture start.. int initX = myPuzzlePiece.uvX; int initY = myPuzzlePiece.uvY; //How much of the texture will be shown (uv rect) float textureWidth = myPuzzlePiece.uvWidth; float textureHeight = myPuzzlePiece.uvHeight; myColor = myPuzzlePiece.myColor; //New "Canvas" to paint on myTexture = new Texture2D((int)textureWidth, (int)textureHeight); //Clears any other color that it is not its own for(int y = initY; y < initY + textureHeight; y++){ for(int x = initX; x < initX + textureWidth; x++){ //if pixel is not the piece's color, clear it if(puzzleOutline.GetPixel(x,y) != myColor) { myTexture.SetPixel(x-initX,y-initY,Color.clear); } else{ mainImageColor = mainImageTexture.GetPixel(x,y); myTexture.SetPixel(x-initX, y-initY, mainImageColor); } } } //Commit changes to texture and apply it myTexture.wrapMode = TextureWrapMode.Clamp; myTexture.Apply(); myUITexture.mainTexture = myTexture; myUITexture.enabled = false; initiated =true; } myUITexture.mainTexture = myTexture; myUITexture.enabled = false; }
//Main Calculation to get each individual piece's UVs void CalculateMinMax(PuzzlePieceInfo piece, int startX, int startY, bool findMinX, Color[] colors) { //Set up int minX = int.MaxValue; int maxX = int.MinValue; int minY = 0; int maxY = 0; int counterX = 0; int index = 0; bool notFound = false; bool findMinY = true; //if the piece is the last on column, then maxX will be texture's width if(piece.myColumn == numCol-1) maxX = puzzleOutline.width; //if the piece is the last on row, then maxY will be texture's height if(piece.myRow == numRows-1) maxY = puzzleOutline.height; //Don't need to find the minY for pieces on row 0 since it is 0 if(piece.myRow == 0) findMinY = false; //Main For loop for(int y = startY; y < puzzleOutline.height; y++){ //New row, then try to find a new MinX findMinX = true; //if it didn't find the piece's color after one traversal, assume end of piece if(notFound) { if(piece.myRow != numRows - 1){ maxY = y+2; //Just some padding } break; } for(int x = startX; x < puzzleOutline.width; x++) { index = y * puzzleOutline.width + x; //Find the uvX of currentPiece using the piece on the left as reference if(findMinX) { //if the pixel has the same color as the piece... if( piece.myColor == colors[index]){ //check if pixel positiion is lower than the current min and swap accordingly if(x < minX) minX = x; //find the very first occurence of the piece's color to find minY if(findMinY){ minY = y; findMinY = false; } //found first piece's color occurrence find the row's maxX (if not the last column piece) if(piece.myColumn != numCol - 1){ findMinX = false; } else break; } //if the current pixel is not the piece's color, is greater than current max //Or reached end of texture assume end of piece else if((maxX != int.MinValue && x > maxX) || (maxX != int.MinValue && !findMinY && x == puzzleOutline.width -1)) { notFound = true; break; } } //find the MaxX that the piece covers if(!findMinX) { //at the first occurrence that the color is no longer the same as the piece's if(piece.myColor != colors[index]){ //Check if currentX is greater than current Max and break regardless if(x > maxX) { maxX = x; } break; } } }//end X for loop }//end y for loop piece.uvX = minX; piece.uvY = minY; piece.uvHeight = maxY - minY; piece.uvWidth = maxX - minX; }
//Create Prefab, position in world and make it pixel perfect void InstantiatePrefab(PuzzlePieceInfo thePiece) { //Create Prefab and change name GameObject piece = GameObject.Instantiate(puzzlePiecePrefab) as GameObject; piece.name = "IndividualPiece "+ thePiece.myRow.ToString() + thePiece.myColumn.ToString(); //Calls the function to further clean up the individual piece piece.GetComponent<PuzzlePiece>().CreateTexture(thePiece, puzzleOutline, mainPuzzleImage); //Sets up the position of the piece piece.transform.parent = GameObject.FindGameObjectWithTag("PuzzlePanel").transform; Vector3 loc = piece.transform.localPosition; loc.x = locations[locationCounter].transform.position.x; loc.y = locations[locationCounter].transform.position.y; locationCounter++; //loc.x += 160 * thePiece.myColumn; //loc.y += 160 * thePiece.myRow; piece.transform.position = loc; Vector3 scale = piece.transform.localScale; scale.x = thePiece.uvWidth; scale.y = thePiece.uvHeight; piece.transform.localScale = scale; #if !USE_SHADER //Scale it to make it pixel perfect piece.GetComponent<UITexture>().MakePixelPerfect(); #endif //Some further scaling since the pieces are too big scale = piece.transform.localScale; scale.Scale(new Vector3(scalar, scalar, scalar)); piece.transform.localScale = scale; //add on extra scripts so it behaves like a puzzle piece piece.AddComponent<DraggablePuzzlePiece>(); piece.GetComponent<DraggablePuzzlePiece>().isSolution = true; piece.GetComponent<DraggablePuzzlePiece>().mySlot = GameObject.Find ("Slot"+thePiece.myColumn.ToString()+thePiece.myRow.ToString()+diff); piece.GetComponent<DraggablePuzzlePiece>().mySlot.GetComponent<DropContainerPuzzle>().initiate(thePiece, puzzleOutline, hintImage); piece.AddComponent<BoxCollider>(); piece.GetComponent<BoxCollider>().size = new Vector3(.8f,.8f,1f); piece.AddComponent<UIDragObject>(); piece.GetComponent<UIDragObject>().target= piece.transform; piece.GetComponent<UIDragObject>().restrictWithinPanel = true; piece.GetComponent<UIDragObject>().dragEffect = UIDragObject.DragEffect.None; }
//Creates individual piece (without UV's set up) void CreateIndividualPiece(int row, int col, Color pieceColor) { PuzzlePieceInfo puzzlePiece = new PuzzlePieceInfo(); puzzlePiece.myColor = pieceColor; puzzlePiece.myRow = row; puzzlePiece.myColumn = col; indivPiecesArray[row,col] = puzzlePiece; }
//Calculate the UV's depending on piece's grid location void CalculateUVRect(PuzzlePieceInfo piece, Color[] colors) { int prevUVX; int prevUVY; //if it is the very first piece, set UV's location to (0,0) if(piece.myRow == 0 && piece.myColumn == 0){ piece.uvX = 0; piece.uvY = 0; CalculateMinMax(piece, 0, 0, false, colors); } //if it is a piece on the first row, set UV's location to (UVX,0) else if(piece.myRow == 0){ piece.uvY = 0; prevUVX = indivPiecesArray[piece.myRow, piece.myColumn-1].uvX; prevUVY = 0; CalculateMinMax(piece, prevUVX, prevUVY, true, colors); } //if it is a piece on the first column, set UV's location to (0, UVY) else if(piece.myColumn == 0){ piece.uvX = 0; prevUVY = indivPiecesArray[piece.myRow-1, piece.myColumn].uvY; prevUVX = 0; CalculateMinMax(piece, prevUVX, prevUVY, true, colors); } //For the middle pieces else{ prevUVX = indivPiecesArray[piece.myRow, piece.myColumn-1].uvX; prevUVY = indivPiecesArray[piece.myRow-1, piece.myColumn].uvY; CalculateMinMax(piece, prevUVX, prevUVY, true, colors); } }
//Texture2D pictureTexture; /*/////////////////////////// IMPORTANT //////////////////////////// Individual piece only has main outline of the piece, still need to apply the color of the main picture (Texture2D pictureTexture) //////////////////////////*/ //Cleans up the individual piece's texture and applies it public void CreateTexture(PuzzlePieceInfo piece, Texture2D outLine, Texture2D theImage) { Color mainImageColor; //Set Up myPuzzlePiece = new PuzzlePieceInfo(); puzzleOutline = outLine; mainImageTexture = theImage; myPuzzlePiece = piece; //Where does the texture start.. int initX = myPuzzlePiece.uvX; int initY = myPuzzlePiece.uvY; //How much of the texture will be shown (uv rect) int textureWidth = myPuzzlePiece.uvWidth; int textureHeight = myPuzzlePiece.uvHeight; myColor = myPuzzlePiece.myColor; Material mat = new Material(myShader); myUITexture.material = mat; float offsetX = (float) initX/(float)puzzleOutline.width; float offsetY = (float) initY/(float)puzzleOutline.height; //New "Canvas" to paint on //myTexture = new Texture2D(textureWidth, textureHeight, TextureFormat.RGBA32, false); #if USE_SHADER myUITexture.material.SetColor("_MainColor", myColor); myUITexture.material.SetTexture("_OutlineTex", puzzleOutline); myUITexture.material.SetTexture("_MainTex", mainImageTexture); Rect newUVRect = myUITexture.uvRect; newUVRect.x = offsetX; newUVRect.y = offsetY; newUVRect.width = (float) textureWidth / (float) puzzleOutline.width; newUVRect.height = (float) textureHeight / (float) puzzleOutline.height; myUITexture.uvRect = newUVRect; this.gameObject.SetActive(true); #else myTexture = new Texture2D(textureWidth, textureHeight, TextureFormat.ARGB32, false); int numColors = (int) (textureWidth * textureHeight); int index = 0; int counter = 0; var colors = new Color32[numColors]; var outlineColors = puzzleOutline.GetPixels(initX, initY, textureWidth, textureHeight); var mainImageColors = mainImageTexture.GetPixels(initX, initY, textureWidth, textureHeight); //Using SetPixels32 and GetPixels() for(int i = 0; i < numColors; ++i){ if(outlineColors[i] != myColor) { colors[i] = Color.clear; } else{ colors[i] = mainImageColors[i]; } } //Using SetPixels32 with no GetPixels() //Clears any other color that it is not its own // for(int y = initY; y < initY + textureHeight; y++){ // for(int x = initX; x < initX + textureWidth; x++){ // // //if pixel is not the piece's color, clear it // if(puzzleOutline.GetPixel(x,y) != myColor) { // colors[counter] = Color.clear; // } // else{ // colors[counter] = mainImageTexture.GetPixel(x,y); // } // counter++; // } // } //Using individual set pixels (make sure to comment out setpixels32()) //Clears any other color that it is not its own // for(int y = initY; y < initY + textureHeight; y++){ // for(int x = initX; x < initX + textureWidth; x++){ // // //if pixel is not the piece's color, clear it // if(puzzleOutline.GetPixel(x,y) != myColor) { // myTexture.SetPixel(x-initX,y-initY,Color.clear); // } // else{ // mainImageColor = mainImageTexture.GetPixel(x,y); // myTexture.SetPixel(x-initX, y-initY, mainImageColor); // } // } // } myTexture.SetPixels32(colors); //Commit changes to texture and apply it myTexture.wrapMode = TextureWrapMode.Clamp; myTexture.Apply(false, true); myUITexture.mainTexture = myTexture; gameObject.SetActive(true); #endif }