// Update is called once per frame void Update() { // If the savingUI is being used, don't make the puzzle interactable. if (usingSaveUI) { return; } // If the clueEditor is being used, don't do anything // This is mostly because saving during clue edit mode will be a different // save function than the build saving mode. if (clueEditScript.editingClues) { return; } // Cast a ray every frame, in case we click on a cube or are hovering over a cube // that needs a face lit up. RaycastHit hit; Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // If the player does a single left click on a cube, make a new cube "attached" to its face if (Input.GetMouseButtonUp(0)) { if (Physics.Raycast(ray, out hit, Mathf.Infinity)) { if (hit.transform.gameObject.tag == "BuildCube") { // if we are deleting cubes if (deletingCubes) { //TODO // Add possible undo queue adding of cubes that were deleted here. // If there is only one cube left (if cubeCount is 0), don't delete the cube. // AKA this if statement won't be reached. if (cubeCount >= 1) { // Delete the cube Destroy(hit.transform.gameObject); // Reduce the count of cubes by 1 since a cube was deleted. cubeCount--; } // TODO // update puzzle bounds here return; } // if we are set to add cubes (deleteCubes == false) else if (!deletingCubes) { // This is one unit away from the clicked cube, in the direction of // the normal of the face that was clicked on. newSpot = hit.transform.position + (hit.normal.normalized * 1.0f); newCube = Instantiate(originalCube, newSpot, hit.transform.rotation) as GameObject; newCube.transform.parent = gameObject.transform; // Icrement the number of cubes built by 1, and name the cube based on that number cubeCount++; newCube.name = "BuildCube" + cubeCount; // TODO // Set the Faces of the cube to be light or dark gray (alternating) // TODO // Store each cube that was made in a list. // This list will eventually be saved as a puzzle solution. // Get the face of the cube that was hit. string faceHit = GetFaceHit(hit.triangleIndex); // Get the indices of the cube that was clicked on. CubeScript hitCubeScript = hit.transform.gameObject.GetComponent <CubeScript>(); PuzzleUnit hitUnit = hitCubeScript.GetPuzzleUnit(); // Create an array of three integers that are the change in x,y,z. int[] indexChange = ReturnDimensionChange(faceHit); // Create indices for the new cube based on the face of the hitCube // that was clicked on. int newX = hitUnit.xIndex + indexChange[0]; int newY = hitUnit.yIndex + indexChange[1]; int newZ = hitUnit.zIndex + indexChange[2]; cubeID++; //TODO // Determine if I should just use this line instead. // Possibly add this unit to the list PuzzleUnit newUnit = new PuzzleUnit(newX, newY, newZ, cubeID); // Add this newly made puzzleUnit to the puzzleSolution's list. puzzleSolution.AddUnit(newUnit); // Save the newly created PuzzleUnit to the newly created cube's CubeScript. CubeScript newCubeScript = newCube.GetComponent <CubeScript>(); newCubeScript.SetPuzzleUnit(newX, newY, newZ, cubeID); /* * Debug.Log("OldX: " + hitUnit.xIndex + "\nOldY: " + hitUnit.yIndex + "\nOldZ: " + hitUnit.zIndex + "\n\nNewX: " + newX + + "\nNewY: " + newY + "\nNewZ: " + newZ); */ } } // end of if tag == "buildingCube" } // end of if raycast } // end of if GetMouseButtonUp(0) // If the player presses the Space key, change the status of the deletingCubes //variable to its opposite so it toggles between deleting cubes and adding cubes. if (Input.GetKeyUp(KeyCode.Space)) { deletingCubes = !deletingCubes; // If set to deleting cubes, make the text show deleting. if (deletingCubes) { tempBuildText = "Deleting"; } // If set to not deleting cubes, make the text show adding. else { tempBuildText = "Adding"; } // Update the text of the build status object. buildStatusObject.text = tempBuildText; } // If the s key is pressed, save a JSON file if (Input.GetKeyUp(KeyCode.S)) { // TODO // Call the method that shows a text input field to name the puzzle. uiManager.DisplayTextInputField(true); usingSaveUI = true; uiManager.SetInputStatus(true); } // if the RMB is being continuously held down, rotate the entire puzzle about the average center of itself if (Input.GetMouseButton(1)) { RotatePuzzle(); } // If the player is simply hovering over a cube, highlight its face, // specifically the face of the first cube hit by the raycast. if (Physics.Raycast(ray, out hit, Mathf.Infinity)) { if (hit.transform.gameObject.tag == "BuildCube") { // Reference to previous face in case a new face is hovered over string oldFace = lastFace; // Reference to previous cube object in case a new cube is hovered over GameObject oldCubeHoveringOver = cubeHoveringOver; // Reference to the cube being currently hovered over cubeHoveringOver = hit.transform.gameObject; //TODO // Set light or dark gray here. // If we are hovering over a new cube, set the old cube to be its default gray. if (cubeHoveringOver != oldCubeHoveringOver && oldCubeHoveringOver != null) { oldCubeHoveringOver.GetComponent <CubeFacesScript>().SetAllVertices(lightGrayFaceCoords); } /* Triangle indices for each cube face * front = 4,5 * right = 10,11 * top = 2,3 * back = 0,1 * left = 8,9 * bottom = 6,7 */ int hitTriangle = hit.triangleIndex; string faceHit = ""; // WEIRD CODE // I had to switch the faces/triangles for front/back and left/right. // Not sure why. Face selection was working fine until this set of if statements. if (hitTriangle == 0 || hitTriangle == 1) { faceHit = "front"; } if (hitTriangle == 2 || hitTriangle == 3) { faceHit = "top"; } if (hitTriangle == 4 || hitTriangle == 5) { faceHit = "back"; } if (hitTriangle == 6 || hitTriangle == 7) { faceHit = "bottom"; } if (hitTriangle == 8 || hitTriangle == 9) { faceHit = "right"; } if (hitTriangle == 10 || hitTriangle == 11) { faceHit = "left"; } lastFace = faceHit; // If the lastFace hovered over is the same as the new face (no change in face // being hovered over) don't do anything. // If it's a new cube but the same face (moving along a row of cubes) continue, // but if its the same face on the same cube, don't do anything. if (lastFace.Equals(oldFace) && cubeHoveringOver == oldCubeHoveringOver) { return; } // If a new face is being hovered over, set the last face to be its // respective gray again. // TODO set light/dark gray faces to gray here if (oldCubeHoveringOver != null) { oldCubeHoveringOver.GetComponent <CubeFacesScript>().SetFace(oldFace, "LightGray"); } // Now that we know which face was hit, set that face to be red while we are over it CubeFacesScript hitCubeScript = hit.transform.gameObject.GetComponent <CubeFacesScript>(); hitCubeScript.SetFace(faceHit, "Red"); // Set the color change tracker to true since a color on some cube was altered, // and thus needs to be undone if no cube is being hovered over in the future (else below). colorWasChanged = true; } } // end of raycast hit block // If the ray hasn't hit any cubes, set the faces of the last cube to be their original // shade of gray, then set the checker to update textures to false so it isn't constantly // trying to set a texture somewhere. else { // set faces of lastCube to be dark or light // If the color of a cube was changed but we are no longer over a cube, undo the // color change of the last hit cube. if (colorWasChanged) { // If the cube that was being hovered over no longer exists (was deleted) do no more. if (cubeHoveringOver == null) { return; } // TODO set this to be light or dark gray cubeHoveringOver.GetComponent <CubeFacesScript>().SetAllVertices(lightGrayFaceCoords); //Reset all tracking values so as if it was selecting a cube for the first time. lastFace = ""; cubeHoveringOver = null; // Then make it so there are no cubes to have to change color colorWasChanged = false; } } // Camera zoom block // update cameraDistance based on how the scroll wheel is being used cameraDistance += Input.GetAxis("Mouse ScrollWheel") * scrollSpeed; cameraDistance = Mathf.Clamp(cameraDistance, cameraDistanceMax, cameraDistanceMin); // set the camera's z value based on the updated cameraDistance Camera.main.transform.position = new Vector3(Camera.main.transform.position.x, Camera.main.transform.position.y, cameraDistance); }
//TODO //CONTINUE FROM HERE // Set up the object that will contain the list of cubes/dimensions of puzzle // and update those values as cubes are added/deleted. void Start() { uiManager = GameObject.Find("UIManager").GetComponent <UIManagerScript>(); clueEditScript = GameObject.Find("ClueEditManager").GetComponent <ClueEditScript>(); // the game starts at 1 cubes having been built (index 0) cubeCount = 0; lastFace = ""; colorWasChanged = false; //TODO might have to reset this every time build mode is started. cubeID = 0; // Initialize the cubeID that will increment every time a cube is made. deletingCubes = false; // The default for build mode is to add cubes. tempBuildText = "Adding"; // The default for build mode is to add cubes. usingSaveUI = false; // The UI in build mode starts hidden, so it is initially not // being used. // Create the first cube at 0,0,0 and with 0 rotation. fullBuildCube = Instantiate(originalCube, Vector3.zero, Quaternion.identity) as GameObject; // Parent the starting cube to the manager so it can be rotated with the puzzle. fullBuildCube.transform.parent = gameObject.transform; // The first cube gets the name "BuildCube0" fullBuildCube.name = "BuildCube" + cubeCount; // Set the first cube's attached PuzzleUnit to be at 0,0,0 with ID 0. CubeScript firstCubeScript = fullBuildCube.gameObject.GetComponent <CubeScript>(); firstCubeScript.SetPuzzleUnit(0, 0, 0, 0); // Initialize the puzzle solution that will be converted to a JSON file when saved. puzzleSolution = new PuzzleSolution(); // Add the first cube to the puzzleSolution's list of PuzzleUnits. puzzleSolution.AddUnit(firstCubeScript.GetPuzzleUnit()); CubeFacesScript faceScript = fullBuildCube.GetComponent <CubeFacesScript>(); float div = faceScript.div; // Set the faces for the fullBuildCube to be all one color lightGrayFaceCoords = new Vector2[] { new Vector2(0f * div, 1f * div), new Vector2(1f * div, 1f * div), new Vector2(0f * div, 0f * div), new Vector2(1f * div, 0f * div) }; darkGrayFaceCoords = new Vector2[] { new Vector2(1f * div, 1f * div), new Vector2(2f * div, 1f * div), new Vector2(1f * div, 0f * div), new Vector2(2f * div, 0f * div) }; redFaceCoords = new Vector2[] { new Vector2(7f * div, 1f * div), new Vector2(8f * div, 1f * div), new Vector2(7f * div, 0f * div), new Vector2(8f * div, 0f * div) }; faceScript.SetAllVertices(lightGrayFaceCoords); // set the reference to the buildStatusText object buildStatusObject = GameObject.Find("FlagStatusText").GetComponent <Text>(); buildStatusObject.text = tempBuildText; }
// This will make the cube GameObject in the parameter have its corresponding faces // toggled between blank and numbered. public void ToggleCubeFace(GameObject cubeObj, string facesToChange) { //CubeScript tempScript = cubeObj.GetComponent<CubeScript>(); //PuzzleUnit puzzUnit = tempScript.GetPuzzleUnit(); CubeFacesScript tempFacesScript = cubeObj.GetComponent <CubeFacesScript>(); //TODO // Get the color to set the cube to be light or dark gray to // maintain the checkerboard pattern. // This will be the status of the faces to hide before being clicked on. // Default to false. bool facesToHideStatus = false; // Determine which pair of faces need to be checked to see if they // have their clues shown or not. if (facesToChange.Equals("front") || facesToChange.Equals("back")) { facesToHideStatus = tempFacesScript.frontBackClueHidden; } if (facesToChange.Equals("top") || facesToChange.Equals("bottom")) { facesToHideStatus = tempFacesScript.topBottomClueHidden; } if (facesToChange.Equals("left") || facesToChange.Equals("right")) { facesToHideStatus = tempFacesScript.leftRightClueHidden; } // If the cube face is currently set to be hidden (within the context of the // clue editor mode being active), show the original puzzle faces. if (facesToHideStatus) { // If the faces are numbered, set the faces to gray // and set the corresponding facePairClueHidden value in the CubeFacesScript // to false. if (facesToChange.Equals("front") || facesToChange.Equals("back")) { tempFacesScript.SetFace("front", tempFacesScript.frontBack); tempFacesScript.SetFace("back", tempFacesScript.frontBack); tempFacesScript.frontBackClueHidden = false; tempFacesScript.SetFacesHidden("frontback", false); } if (facesToChange.Equals("top") || facesToChange.Equals("bottom")) { tempFacesScript.SetFace("top", tempFacesScript.topBottom); tempFacesScript.SetFace("bottom", tempFacesScript.topBottom); tempFacesScript.topBottomClueHidden = false; tempFacesScript.SetFacesHidden("topbottom", false); } if (facesToChange.Equals("left") || facesToChange.Equals("right")) { tempFacesScript.SetFace("left", tempFacesScript.leftRight); tempFacesScript.SetFace("right", tempFacesScript.leftRight); tempFacesScript.leftRightClueHidden = false; tempFacesScript.SetFacesHidden("leftright", false); } } // Otherwise if the clues on this face are set to be shown, set the faces // to be hidden (blank). else { // Set the gray for a face to be set as light or dark gray. string grayType = "LightGray"; if (tempFacesScript.dark) { grayType = "DarkGray"; } // If the faces are numbered, set the faces to gray // and set the corresponding facePairClueHidden value in the CubeFacesScript // to true. if (facesToChange.Equals("front") || facesToChange.Equals("back")) { tempFacesScript.SetFace("front", grayType); tempFacesScript.SetFace("back", grayType); tempFacesScript.frontBackClueHidden = true; tempFacesScript.SetFacesHidden("frontback", true); } if (facesToChange.Equals("top") || facesToChange.Equals("bottom")) { tempFacesScript.SetFace("top", grayType); tempFacesScript.SetFace("bottom", grayType); tempFacesScript.topBottomClueHidden = true; tempFacesScript.SetFacesHidden("topbottom", true); } if (facesToChange.Equals("left") || facesToChange.Equals("right")) { tempFacesScript.SetFace("left", grayType); tempFacesScript.SetFace("right", grayType); tempFacesScript.leftRightClueHidden = true; tempFacesScript.SetFacesHidden("leftright", true); } } // TODO // Figure out if I need to save the entire 3D array of cubes // that have clues hidden/shown, or to have an array of cubes in // the outermost layers that can be used to determine which cubes // have their faces hidden/shown. }