So i have a cool game going on. I have a script that controls the game itself. I don't know where i went wrong but where ever i click on the screen my game objects move. If i click the menu button, they move. I attached a background image in the area that i wanted to be swipe-able and it didn't seem to work. The object is to swipe bubbles that are the same color into another of the same color to collect points. But the swipe seems to be set to the whole screen. IE world position. Any help is welcome. Thanks. This is my game script. Code (CSharp): using UnityEngine; using System.Collections; using System.Collections.Generic; // this script is the main script and contains // - game logic // - input methods // - artificial intelligence public class Game : MonoBehaviour { // native resolution of this game is 1024x768 private float nativeWidth = 1024; private float nativeHeight = 768; // references to GUI objects public Texture2D buttonTexture; public Texture2D backgroundTexture; public GameObject backGround; // reference to the game tile public GameObject slider; // reference to the cell the game tile is in public GameObject cell; string scoreText; public GameObject restartButton; string scoreMessage; // organize the cells in an array GameObject[] cells; // size of game grid // game grid is 4x4 public int SIZE = 4; int[,] grid; // to save the score, best score and the actual move int score = 0 ; int best = 0; int move ; public Rect labelPosition; string labelText; public GUIStyle labelStyle; public Rect labelPosition1; public Rect labelPosition3; string labelText1; public GUIStyle labelStyle1; public GUIStyle labelStyle3; // if a new tile is generated, which value(s) can it be? int lowestNewTileValue = 2; int highestNewTileValue = 4; float horizontalSpacing = -2.2f; float verticalSpacing = 2.2f; float tileSize = 1.28f; float spacing = 0.2f; GameObject slider1; // Game state management is done via a finite state machine (fsm) // this is the data structure to determine which state the game is currently in enum GameStates { loaded, waitingForInput, checkAnimation, check, over, }; GameStates gameState; // which direction are we moving to enum Movement { none, left, right, up, down, }; Movement movement; // input viy xBox controller is possible struct DPad { public float leftRight; public float upDown; }; DPad oldDPad; bool success; bool animationFinished; // Variables for swipe gestures Vector2 firstPressPos; Vector2 secondPressPos; Vector2 currentSwipe; bool solver; bool solver1; float elapsed; float solverInterval = 0.2f; float sliderDepth; // we do not calculate every possible move - // since the board is symmetric, it can be rotated by 90 degree // so only direction must be calculated Vector2[,,] rotMatrix; // // void Start() // // this method initializes the game // void Start () { // count the moves move = 0; // in which direction are we moving // we are not moving at all movement = Movement.none; // initialize the game grid grid = new int[SIZE, SIZE]; // initialize the background backGround = (GameObject)Instantiate(backGround, new Vector3(0,0,0), Quaternion.identity); // set the score score = 0; // hiscore will be stored via Playerprefs // this is a very comfortable way to store information // (this even works in the web player) best = PlayerPrefs.GetInt("hiscore",0); // generate the cells' array cells = new GameObject[16]; int i = 0; for (int y = 0; y < SIZE; y++) { for (int x = 0; x < SIZE; x++) { // initialize the game grid grid [x,y] = 0; cells[i] = (GameObject)Instantiate (cell, new Vector3(horizontalSpacing+(tileSize+spacing)*x,verticalSpacing-(tileSize+spacing)*y,-0.1f), Quaternion.identity); cells[i].name += x + "_" + y ; i++; } } // set the AI to false solver = false; solver1 = false; sliderDepth = 1; // now initialize the matrix // for rotating the game board rotMatrix = new Vector2[4,4,4]; for (int y = 0; y < SIZE; y++) { for (int x = 0; x < SIZE; x++) { rotMatrix[0,x,y] = new Vector2(x,y); rotMatrix[1,x,y] = new Vector2(x,y); rotMatrix[2,x,y] = new Vector2(x,y); rotMatrix[3,x,y] = new Vector2(x,y); } } rotateMatrix(rotMatrix,1); rotateMatrix(rotMatrix,2); rotateMatrix(rotMatrix,2); rotateMatrix(rotMatrix,3); rotateMatrix(rotMatrix,3); rotateMatrix(rotMatrix,3); // set the actual gameState gameState = GameStates.loaded; } // // void rotateMatrix(Vector2[,,] grid, int index) // // do the rotation // // remember: a move to the right is equally to // rotating the grid 90° counterclockwise and // perform a move upwards // public void rotateMatrix(Vector2[,,] grid, int index) { for (int y = 0; y < SIZE/2; y++) { for (int x = y; x < SIZE - y - 1; x++) { Vector2 tmp = grid[index,y,x]; grid[index,y,x] = grid[index,x,SIZE-y-1]; grid[index,x,SIZE-y-1] = grid[index,SIZE-y-1,SIZE-x-1]; grid[index,SIZE-y-1,SIZE-x-1]=grid[index,SIZE-x-1,y]; grid[index,SIZE-x-1,y]=tmp; } } } // // void Update() // // this is the main game loop // void Update () { labelText = "" + score.ToString(); labelText1 = "" + best.ToString(); // check which state we are in switch (gameState) { // the game is started // reset the game grid // generate two random staring tiles // change state and for the player to make some input case GameStates.loaded: resetGrid(); generateRandomTile(); generateRandomTile(); gameState = GameStates.waitingForInput; break; // if the player can make a move, we have two possibilites // 1) AI plays // 2) player makes a move case GameStates.waitingForInput: // AI makes move if (solver) { elapsed += Time.deltaTime; if (elapsed > solverInterval) { elapsed -= solverInterval; KI(grid); } } // player makes move else { checkInput (); } // so we made a move // check which move we made switch (movement) { // we did move all tiles to the left case Movement.left: success = moveLeft(); animateTiles(); gameState = GameStates.checkAnimation; break; // we did move all tiles to the right case Movement.right: success = moveRight(); animateTiles (); gameState = GameStates.checkAnimation; break; // we did move all tiles up case Movement.up: success = moveUp(0); animateTiles(); gameState = GameStates.checkAnimation; break; // we did move all tiles down case Movement.down: success = moveDown(); animateTiles(); gameState = GameStates.checkAnimation; break; } break; // movement is joined to animation // animation must not be disturbed, so wait until animation is done case GameStates.checkAnimation: if (checkForAnimation()) gameState = GameStates.check; break; // ok, the move is over // show the game grid and // generate a new random tile case GameStates.check: if (success) { showTheGrid(); generateRandomTile(); success = false; } movement = Movement.none; // check if board is completely filled // and no further move is possible if (gameEnded()) { // if so, the gane is over gameState = GameStates.over; } else { // else the player can make a new move gameState = GameStates.waitingForInput; } break; // the game is over case GameStates.over: // is the new score better than the previously saved one if (score > best) { // then save the better score to PlayerPrefs PlayerPrefs.SetInt("hiscore",score); best = score; } break; } } public void saveScore() { // is the new score better than the previously saved one if (score > best) { // then save the better score to PlayerPrefs PlayerPrefs.SetInt("hiscore",score); best = score; resetGrid(); gameState = GameStates.loaded; } } // // void animateTiles() // // this method gets all tiles on the grid // (this is simple, since they're tagged "tile") // animate all the tiles // public void animateTiles() { animationFinished = false; GameObject[] tiles = GameObject.FindGameObjectsWithTag("Tile"); foreach (GameObject tile in tiles) { tile.GetComponent<TileAnimator>().animatePositionChange(); } } // // void chekForAnimation() // // this method checks if there is currently // an animation and returns true or false // // remember: only one animation at the time public bool checkForAnimation() { bool animationFinished = true; GameObject[] tiles = GameObject.FindGameObjectsWithTag("Tile"); foreach (GameObject tile in tiles) { animationFinished = animationFinished && tile.GetComponent<TileAnimator>().isFinished(); } return animationFinished; } // // void checkInput() // // this game allows a lot of different input methods // Keyboard : arrow keys // xBox-Controller : Buttons and dPad // Touch : swipe gestures (also works with mouse) // public void checkInput() { checkKeyboardInput(); checkXBoxButtons(); checkXBoxDPad(); checkXBoxStartButton(); checkSwipeTouch(); checkSwipeClick(); } // // void checkKeyboardInput() // // check the arrow keys and set the movement enum // void checkKeyboardInput() { if (Input.GetKeyUp(KeyCode.UpArrow)) movement = Movement.up; if (Input.GetKeyUp(KeyCode.DownArrow)) movement = Movement.down; if (Input.GetKeyUp(KeyCode.LeftArrow)) movement = Movement.left; if (Input.GetKeyUp(KeyCode.RightArrow)) movement = Movement.right; } // // void checkXBoxButtons() // // check the A, B, X, Y Button on xBox-Controller // and set the movement enum // void checkXBoxButtons() { if (Input.GetButtonUp("XBox_Y_Button")) movement = Movement.up; if (Input.GetButtonUp("XBox_A_Button")) movement = Movement.down; if (Input.GetButtonUp("XBox_B_Button")) movement= Movement.right; if (Input.GetButtonUp("XBox_X_Button")) movement = Movement.left; } // // void checkXBoxDPad() // // check the dPad on the xBox-Controller // and set the movement enum // void checkXBoxDPad() { DPad newDPad; newDPad.leftRight = Input.GetAxis("XBox_DPad_Horizontal"); newDPad.upDown = Input.GetAxis("XBox_DPad_Vertical"); if (!newDPad.Equals(oldDPad)) { if (newDPad.leftRight < -0.1f) movement = Movement.left; if (newDPad.leftRight > 0.1f) movement = Movement.right; if (newDPad.upDown > 0.1f) movement = Movement.up; if (newDPad.upDown < -0.1f) movement = Movement.down; } oldDPad = newDPad; } // // void checkXBoxStartButton() // // reset the game when player presses the start button // public void checkXBoxStartButton() { if (Input.GetButtonUp("XBox_Start_Button")) { resetGrid(); gameState = GameStates.loaded; } } // // void checkSwipeTouch() // // now for the last input method // (and the most important nowadays) // Check for Touch input and swipe gestures // void checkSwipeTouch() { if (Input.touches.Length > 0) { Touch t = Input.GetTouch(0); if(t.phase == TouchPhase.Began) { //save began touch 2d point firstPressPos = new Vector2(t.position.x,t.position.y); } if (t.phase == TouchPhase.Ended) { //save ended touch 2d point secondPressPos = new Vector2(t.position.x,t.position.y); //create vector from the two points currentSwipe = new Vector2(secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y); //normalize the 2d vector currentSwipe.Normalize(); //swipe upwards if(currentSwipe.y > 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f) { movement = Movement.up; } //swipe down if(currentSwipe.y < 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f) { movement = Movement.down; } //swipe left if(currentSwipe.x < 0 && currentSwipe.y > -0.5f && currentSwipe.y < 0.5f) { movement = Movement.left; } //swipe right if(currentSwipe.x > 0 && currentSwipe.y > -0.5f && currentSwipe.y < 0.5f){ movement = Movement.right; } } } } void checkSwipeClick() { if(Input.GetMouseButtonDown(0)) { //save began touch 2d point firstPressPos = new Vector2(Input.mousePosition.x,Input.mousePosition.y); } if(Input.GetMouseButtonUp(0)) { //save ended touch 2d point secondPressPos = new Vector2(Input.mousePosition.x,Input.mousePosition.y); //create vector from the two points currentSwipe = new Vector2(secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y); //normalize the 2d vector currentSwipe.Normalize(); //swipe upwards if(currentSwipe.y > 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f) { movement = Movement.up; } //swipe down if(currentSwipe.y < 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f) { movement = Movement.down; } //swipe left if(currentSwipe.x < 0 && currentSwipe.y > -0.5f && currentSwipe.y < 0.5f) { movement = Movement.left; } //swipe right if(currentSwipe.x > 0 && currentSwipe.y > -0.5f && currentSwipe.y < 0.5f) { movement = Movement.right; } } } // // Vector2 worldToGridPosition // // this method converts input-positions on the screen to game-grid positions // public Vector2 worldToGridPosition(Vector3 position) { Vector2 gridPosition = new Vector2(); gridPosition.x = (position.x - horizontalSpacing)/(tileSize+spacing); gridPosition.y = -(position.y - verticalSpacing)/(tileSize+spacing); return gridPosition; } // // Vector3 gridToWorldPosition // // convert grid Position to position on the screen // --> world position // public Vector3 gridToWorldPosition(int x, int y){ return new Vector3(horizontalSpacing+(tileSize+spacing)*x,verticalSpacing-(tileSize+spacing)*y,-0.2f); } // // GameObject getObjectAtGridPosition // // use a Raycast to check the actual grid position // for a gameObject // public GameObject getObjectAtGridPosition(int x, int y) { RaycastHit hit; // get the current world position Vector3 gridPosition = gridToWorldPosition(x,y); // step back from the object, so we can shoot a ray // (otherwise, it will hit the cell container or the background) gridPosition.z -= 0.2f; // cast a ray and see if we hit something if (Physics.Raycast(gridPosition, new Vector3(0,0,1),out hit)) { // is the GameObject found a tile? Tile tile = hit.collider.GetComponent<Tile>(); // then return the gameObject found at position (x,y) if (tile != null) return hit.collider.gameObject; } // sorry, we did not find an gameObject return null; } // // int getCurrentTiles // // get the number of tiles on the grid // this method is used to check the win/lose condition // if the grid is ull and no move can be done, the game is over // public int getCurrentTiles(){ // reset counter to zero int tileAmount = 0; // iterate the grid for (int y = 0; y < SIZE; y++) { for (int x = 0; x < SIZE; x++) { // if grid is not zero, // increment the counter if (grid[x,y] != 0) { tileAmount++; } } } // return the calculated number of cells return tileAmount; } // // void showTheGrid // // this method refreshes the grid // it destroy relics of the last game iteration and produces fresh tiles // public void showTheGrid() { // eliminate the game Objects on the grid (view) GameObject[] tiles = GameObject.FindGameObjectsWithTag("Tile"); foreach (GameObject tile in tiles) { Destroy(tile); } for (int y = 0; y < SIZE; y++) { for (int x = 0; x < SIZE; x++) { if (grid[x,y] != 0){ slider1 = (GameObject)Instantiate (slider, gridToWorldPosition(x,y), Quaternion.Euler (new Vector3(0,0,180))); slider1.name = x + "_" + y; slider1.GetComponent<Tile>().setValue(grid[x,y]); } } } } // // void generateRandomTile // // create a random tile on the grid // this is done every move // public void generateRandomTile(){ // can we create tiles anymore? if (getCurrentTiles() < SIZE*SIZE) { int value; // yes, we can... so generate a random number... float twoOrFour = Random.Range(0,0.99f); // ... and choose a 2 or 4, respectively if (twoOrFour >= 0.9f) { value = highestNewTileValue; } else { value = lowestNewTileValue; } // generate a list of cells List<Vector2> availableCells = new List<Vector2>(); // now find all empty places on te grid for (int y = 0; y < SIZE; y++) { for (int x = 0; x < SIZE; x++) { if (grid[x,y] == 0) { Vector2 available = new Vector2(x,y); // push the empty cell in the list availableCells.Add(available); } } } // get a random cell from the available cells Vector2 chosenCell = availableCells[Random.Range(0,availableCells.Count)]; GameObject newTile = (GameObject)Instantiate (slider, gridToWorldPosition((int)chosenCell.x,(int)chosenCell.y), Quaternion.Euler (new Vector3(0,0,180))); newTile.name = chosenCell.x + "_" + chosenCell.y; newTile.GetComponent<Tile>().setValue(value); newTile.transform.localScale= new Vector3(0,0,0); // play the animation newTile.GetComponent<TileAnimator>().entryAnimation(); grid[(int)chosenCell.x,(int)chosenCell.y] = value; } } // // void resetGrid // // Mr. Proper... // reset the grid // clean the cells // destroy tiles (GameObjects) // public void resetGrid(){ // clear the grid (model) for (int y = 0; y < SIZE; y++) { for (int x = 0; x < SIZE; x++) { grid[x,y] = 0; } } // eliminate the game Objects on the grid (view) GameObject[] tiles = GameObject.FindGameObjectsWithTag("Tile"); foreach (GameObject tile in tiles) { Destroy(tile); } } // // int findTarget // // check where the tiles can be moved after player input // public int findTarget(int col, int rows, int stop) { int target; if (rows == 0){ return rows; } for (target = rows-1; target >= 0; target--) { if (grid[col,target] != 0) { if (grid[col,target] != grid[col,rows]) { // merge is not possible, // take the next position return target+1; } return target; } else { // we should not slide further, // return this one if (target == stop) { return target; } } } // we did not find a position return rows; } // // bool slideArray // // can the player move be executed // and the tiles be moved in the intended direction // public bool slideArray(int col, int rot) { bool success = false; int target; int stopAtPosition=0; bool merged = false; // for each column, now iterate the complete row for (int y = 0; y < SIZE; y++) { // evaluate only, if grid cell is not empty if (grid[col,y] != 0) { target = findTarget(col, y, stopAtPosition); // target is not the current grid cell // then move or merge if (target != y){ // set stop variable to avoid double merge // 2,2,4,4 --> 4,8,0,0 and not // 2,2,4,4, --> 8,4,0,0 if (grid[col,target]!=0) { score += grid[col,target] + grid[col,y]; stopAtPosition = target + 1; merged = true; } // move the source cell to target position grid[col,target] += grid[col,y]; Vector2 targetPos = rotMatrix[rot, col, target]; Vector2 sourcePos = rotMatrix[rot, col, y]; GameObject tile = GameObject.Find(sourcePos.x+"_"+sourcePos.y); if (tile!=null) tile.GetComponent<TileAnimator>().setPosition(gridToWorldPosition((int)sourcePos.x,(int)sourcePos.y), gridToWorldPosition((int)targetPos.x,(int)targetPos.y)); // clear the source cell grid[col,y] = 0; success = true; } } } return success; } // // bool findPairs // // did we find equal tile in direct neighborhood // after the player's move? // (these will be merged) // public bool findPairs() { for (int y = 0;y < SIZE-1; y++) { for (int x = 0;x < SIZE; x++) { if (grid[x,y]==grid[x,y+1]) return true; } } return false; } // // bool gameEnded // // check if another move is possible // if not, the game is over // bool gameEnded() { bool ended = true; if (getCurrentTiles() < SIZE*SIZE) return false; if (findPairs()) return false; rotateBoard(); if (findPairs()) ended = false; rotateBoard(); rotateBoard(); rotateBoard(); if (ended == true) Debug.Log("Game Over"); return ended; } // // void rotateBoard // // as already discussed, a move to the right can be considered as // a counterclockwise rotation about 90° and a move upwards // // this method rotates the board by 90° // public void rotateBoard() { for (int y = 0; y < SIZE/2; y++) { for (int x = y; x < SIZE - y - 1; x++) { int tmp = grid[y,x]; grid[y,x] = grid[x,SIZE-y-1]; grid[x,SIZE-y-1] = grid[SIZE-y-1,SIZE-x-1]; grid[SIZE-y-1,SIZE-x-1]=grid[SIZE-x-1,y]; grid[SIZE-x-1,y]=tmp; } } } // // bool moveXY // // now see what I mean by considering th efollowing methods... // public bool moveLeft() { bool success; rotateBoard(); success = moveUp(1); rotateBoard(); rotateBoard(); rotateBoard(); return success; } public bool moveRight() { bool success; rotateBoard(); rotateBoard(); rotateBoard(); success = moveUp(3); rotateBoard(); return success; } public bool moveUp(int rot) { move++; bool success = false; // iterate each column for (int x = 0; x < SIZE; x ++) { success = success | slideArray(x, rot); } return success; } public bool moveDown() { bool success; rotateBoard(); rotateBoard(); success = moveUp(2); rotateBoard(); rotateBoard(); return success; } // // void OnGUI // // this method is an unity event function and draws the GUI // public void OnGUI(){ // try to calculate resolution independence float rx = Screen.width / nativeWidth; float ry = Screen.height / nativeHeight; GUI.matrix = Matrix4x4.TRS (new Vector3(0,0,0), Quaternion.identity, new Vector3 (rx, ry, 1)); // Create own style for a GUI-Label GUIStyle myLabelStyle = new GUIStyle(GUI.skin.label); myLabelStyle.fontSize = 20; myLabelStyle.fontStyle = FontStyle.Bold; labelStyle.normal.textColor = Color.white; labelStyle1.normal.textColor = Color.white; GUI.Label(labelPosition, labelText, labelStyle); GUI.Label(labelPosition1, labelText1, labelStyle1); // Create own style for a GUI-Label GUIStyle myLabel2Style = new GUIStyle(GUI.skin.label); myLabel2Style.fontSize = 80; myLabel2Style.fontStyle = FontStyle.Bold; myLabel2Style.normal.textColor = Color.blue; //GUI.Label(new Rect (450,10,200,200),"Dots",myLabel2Style); //new game button if (GUI.Button (labelPosition3,buttonTexture,labelStyle3)){ score = 0; resetGrid(); gameState = GameStates.loaded; } // if game ids over, display a message if (gameState == GameStates.over) { GUI.color = new Color(1,1,1,0.5f); GUI.DrawTexture(new Rect(277,226,472,472), backgroundTexture); GUI.color = new Color(1,1,1,1); myLabel2Style.fontSize = 128; myLabel2Style.normal.textColor = Color.gray; GUI.Label(new Rect (320,310,400,300),"GAME OVER",myLabel2Style); solver = false; solver1 = false; } } // --------------------------------------------------------------- // --------------------------------------------------------------- // --------------------------------------------------------------- // Attention, attention! now introducing: the 2048 AI // --------------------------------------------------------------- // --------------------------------------------------------------- // --------------------------------------------------------------- // even the AI is confronted with new random tiles generated each move... int[] MOVES = new int[2]{2,4}; double[] PROBABILITIES = new double[2]{0.9, 0.1}; // // void KI // // this is the main AI method // called from the Update method // // it gets a reference to the game grid to work on // public void KI(int[,] _grid) { // get copy of game grid for KI mover // as you can see, it's a "deep copy" - so it is no reference any more // but an independent copy int[,] myGrid = (int[,])_grid.Clone(); // evaluate the best move with a depth of 1 // I'm using alpha-beta-pruning int direction = bestDirection(myGrid, (int)sliderDepth); // whatever move seems to be the best, it is executed switch (direction){ case 0: movement = Movement.up; break; case 1: movement = Movement.right; break; case 2: movement = Movement.down; break; case 3: movement = Movement.left; break; } } // // int bestDirection // // this method evaluates the best move // depedent on the calculation depth // public int bestDirection(int[,] _grid, int depth) { // initialize bestScore and direction double bestScore = 0; int bestDir = -1; // iterate all directions for (int direction = 0; direction < 4; direction ++) { // make a copy of the grid - do not mess up the original game grid int[,] computerGrid = (int[,])_grid.Clone(); moveKI(computerGrid, direction); // we did not find a move if (compareGrids(computerGrid, _grid)) { // so continue with next possible direction continue; } // evaluate the computer move double computerScore = computerMove(computerGrid, 2*depth-1); // we did find a move (better than a preceding one) // so set the new move as the best one if (computerScore >= bestScore) { bestScore = computerScore; bestDir = direction; } } // return the best direction found so far return bestDir; } // // double computerMove // // computer move sets randomly a tile on the grid // public double computerMove(int[,] _grid, int _depth) { double totalScore = 0; double totalWeight = 0; // save the scores in a hashtable // for pruning the search tree Dictionary <string,double> hTable = new Dictionary<string, double>(); // iterate the game grid for (int y = 0; y < SIZE; y++) { for (int x = 0; x < SIZE; x++) { // if there is an empty spot on the grid, // the computer may set a "2" or a "4" if (_grid[x,y] == 0) { // so iterate the possibilities for (int i=0; i < 2; i++) { // deep copy the grid to prepare the player move int[,] playerGrid = (int[,])_grid.Clone(); // set value on the grid (2 or 4, respectively) playerGrid[x,y] = MOVES[i]; // do the player move double score = playerMove(playerGrid, _depth-1, hTable); totalScore += PROBABILITIES[i]*score; totalWeight += PROBABILITIES[i]; } } } } return totalWeight == 0 ? 0 : totalScore/totalWeight; } // // double playerMove // // it may sound kind of schizo (gollum.... gollum...) // the computer is switching personality. it now does a computation // "which move could the player have done to do the most impact on me..." // public double playerMove(int[,] _grid, int _depth, Dictionary<string,double> _htable) { // is the end of recusrion reached? if (_depth == 0) { return hasMove(_grid) ? evaluateHeuristic(_grid) : 0; } double bestScore = 0; for (int direction = 0; direction < 4; direction++) { int[,] computerGrid = (int[,])_grid.Clone(); moveKI (computerGrid,direction); if (compareGrids(computerGrid, _grid)) { continue; } double computerScore = 0; // ok. did we already measure the grid? // then there must be an entry in the hastable if (_htable.ContainsKey(calcHash(computerGrid))) { computerScore = _htable[calcHash(computerGrid)]; } // no score stored // so let's do some backtracking else { computerScore = computerMove(computerGrid, _depth-1); _htable.Add(calcHash(computerGrid),computerScore); } if (computerScore > bestScore) { bestScore = computerScore; } } return bestScore; } // // bool hasMove // // can the computer still make a move? // public bool hasMove(int[,] _grid) { // iterate the grid for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { // are there empty spots on the grid? if (_grid[x,y]== 0) return true; // are there neighboring cells with same value? if (x < 3 && _grid[x,y] == _grid[x+1,y]) return true; if (y < 3 && _grid[x,y] == _grid[x,y+1]) return true; } } // nothing found so far return false; } // // to see which move is the best one, we need a // weighting function // int[,,] weight_matrices = new int[2,4,4]{ { { 3, 2, 1, 0}, { 2, 1, 0, -1}, { 1, 0, -1, -2}, { 0, -1, -2, -3} }, { { 0, 1, 2, 3}, { -1, 0, 1, 2}, { -2, -1, 0, 1}, { -3, -2, -1, 0} } }; // // int evaluateHeuristic // // each move done is evaluated, given a hash value and stored in // a hastable // public int evaluateHeuristic(int[,] _grid) { // store the best heuristic move int best = 0; // we have two matrices to check for (int i = 0; i < 2; i++){ int s = 0; // iterate the grid for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { s += weight_matrices[i,y,x] * _grid[x,y]; } } s = Mathf.Abs(s); // Hack for symmetry // did we find a new best if (s > best) { best = s; } } return best; } // // void moveKI // // AI is making a move // void moveKI(int[,] _grid, int direction) { switch (direction){ case 0: shift_up(_grid); break; case 1: shift_right(_grid); break; case 2: shift_down(_grid); break; case 3: shift_left(_grid); break; } } void shift_up(int[,] _grid) { for (int column = 0; column < 4; column++) { int[] cells = new int[4]; for (int y = 0; y < 4; y++) { cells[y] = _grid[column,y]; } moveCells(cells); for (int y = 0; y < 4; y++) { _grid[column,y] = cells[y]; } } } void shift_down(int[,] _grid) { for (int column = 0; column < 4; column++) { int[] cells = new int[4]; for (int y = 0; y < 4; y++) { cells[y] = _grid[column, 3-y]; } moveCells(cells); for (int y = 0; y < 4; y++) { _grid[column, 3-y] = cells[y]; } } } void shift_left(int[,] _grid) { for (int row = 0; row < 4; row++) { int[] cells = new int[4]; for (int x = 0; x < 4; x++) { cells[x] = _grid[x,row]; } moveCells(cells); for (int x = 0; x < 4; x++) { _grid[x,row] = cells[x]; } } } void shift_right(int[,] _grid) { for (int row = 0; row < 4; row++) { int[] cells = new int[4]; for (int x = 0; x < 4; x++) { cells[x] = _grid[3-x,row]; } moveCells(cells); for (int x = 0; x < 4; x++) { _grid[3-x, row] = cells[x]; } } } void moveCells(int[] cells) { int target = 0; for (int i = 1; i < 4; i++) { int targetValue = cells[target]; int currentValue = cells[i]; if (currentValue != 0){ if (targetValue == 0){ cells[target] = currentValue; cells[i] = 0; } else{ if (targetValue == currentValue){ cells[i] = 0; cells[target] <<= 1; } else{ cells[i] = 0; cells[target + 1] = currentValue; } target++; } } } } // // bool compareGrids // // during evaluation, the computer may find a lot of possible grids // as a result of a valid move // we check whether the found grid is already known to possibly cut of // the search tree // public bool compareGrids(int[,] grid1, int[,] grid2) { for (int y = 0; y < SIZE; y ++) { for (int x = 0; x < SIZE; x ++) { if (grid1[x,y] != grid2[x,y]) return false; } } return true; } // // string calchash // // each grid is given an individual hash // consisting of position and value of the tiles // // this hash helps to find possible multiple moves // public string calcHash(int[,] _grid) { long h = 2166136261; for (int y = 0; y < SIZE; y ++) { for (int x = 0;x< SIZE;x++) { h = h ^ (_grid[x,y] * 16777619); } } return h.ToString(); } public int highestTile(int[,] _grid) { int h = 0; for (int y = 0; y < SIZE; y ++) { for (int x = 0;x< SIZE;x++) { if (_grid[x,y] > h) h = _grid[x,y]; } } return h; } public void onClick() { score = 0; resetGrid(); gameState = GameStates.loaded; } }
To clarify, because I'm not understanding the problem exactly- which combination of the following is your issue? Every GameObject is responding to / being controlled by a press regardless of where the press occurs The coordinates where you press do not match up to the raycast position being sent into the game world Raycasts are still firing into the game world even when UI elements are being pressed You wanted to restrict the "raycast on press" area to some small arbitrarily-set region of the screen and that restriction isn't being followed Also, this script is massive. Is there any chance at all you can dumb it down and/or cut out portions that you don't believe have anything to do with this? Leave the whole script where it is, just post the "shortened" version as new, if possible.
I attached a picture of what i mean. I want the green cross area to be swipable or clickable. The red are to not be toucbable. Although i want to add a drop down combo menu at the top somewhere. The game is a swipe type game. Swipe a color and it collides with another of the same color and the player gets points. Something along those lines. Here is the code that holds the ontouch and onlclick actions. Code (CSharp): void checkSwipeTouch() { if (Input.touches.Length > 0) { Touch t = Input.GetTouch(0); if(t.phase == TouchPhase.Began) { //save began touch 2d point firstPressPos = new Vector2(t.position.x,t.position.y); } if (t.phase == TouchPhase.Ended) { //save ended touch 2d point secondPressPos = new Vector2(t.position.x,t.position.y); //create vector from the two points currentSwipe = new Vector2(secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y); //normalize the 2d vector currentSwipe.Normalize(); //swipe upwards if(currentSwipe.y > 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f) { movement = Movement.up; } //swipe down if(currentSwipe.y < 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f) { movement = Movement.down; } //swipe left if(currentSwipe.x < 0 && currentSwipe.y > -0.5f && currentSwipe.y < 0.5f) { movement = Movement.left; } //swipe right if(currentSwipe.x > 0 && currentSwipe.y > -0.5f && currentSwipe.y < 0.5f){ movement = Movement.right; } } } } void checkSwipeClick() { if(Input.GetMouseButtonDown(0)) { //save began touch 2d point firstPressPos = new Vector2(Input.mousePosition.x,Input.mousePosition.y); } if(Input.GetMouseButtonUp(0)) { //save ended touch 2d point secondPressPos = new Vector2(Input.mousePosition.x,Input.mousePosition.y); //create vector from the two points currentSwipe = new Vector2(secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y); //normalize the 2d vector currentSwipe.Normalize(); //swipe upwards if(currentSwipe.y > 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f) { movement = Movement.up; } //swipe down if(currentSwipe.y < 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f) { movement = Movement.down; } //swipe left if(currentSwipe.x < 0 && currentSwipe.y > -0.5f && currentSwipe.y < 0.5f) { movement = Movement.left; } //swipe right if(currentSwipe.x > 0 && currentSwipe.y > -0.5f && currentSwipe.y < 0.5f) { movement = Movement.right; } } } // // Vector2 worldToGridPosition // // this method converts input-positions on the screen to game-grid positions // and this is the code that holds the grid where the game objects are cloned into the grid itself. It uses raycast. Code (CSharp): // // Vector2 worldToGridPosition // // this method converts input-positions on the screen to game-grid positions // public Vector2 worldToGridPosition(Vector3 position) { Vector2 gridPosition = new Vector2(); gridPosition.x = (position.x - horizontalSpacing)/(tileSize+spacing); gridPosition.y = -(position.y - verticalSpacing)/(tileSize+spacing); return gridPosition; } // // Vector3 gridToWorldPosition // // convert grid Position to position on the screen // --> world position // public Vector3 gridToWorldPosition(int x, int y){ return new Vector3(horizontalSpacing+(tileSize+spacing)*x,verticalSpacing-(tileSize+spacing)*y,-0.2f); } // // GameObject getObjectAtGridPosition // // use a Raycast to check the actual grid position // for a gameObject // public GameObject getObjectAtGridPosition(int x, int y) { RaycastHit hit; // get the current world position Vector3 gridPosition = gridToWorldPosition(x,y); // step back from the object, so we can shoot a ray // (otherwise, it will hit the cell container or the background) gridPosition.z -= 0.2f; // cast a ray and see if we hit something if (Physics.Raycast(gridPosition, new Vector3(0,0,1),out hit)) { // is the GameObject found a tile? Tile tile = hit.collider.GetComponent<Tile>(); // then return the gameObject found at position (x,y) if (tile != null) return hit.collider.gameObject; } // sorry, we did not find an gameObject return null; }
The problem is that where ever i touch, being inside the green area or the red area the colors move. I only want it swipable inside the green area.
I don't see any conditionals that have to do with touch regions (unless I'm blind)- you should define an area in either Screen coordinates or Viewport coordinates (my strong preference) that allow for swipes. You can do this in one of two easy ways that my sleep-deprived brain can currently conjure. The first is to make the input controller take care of whether or not the input is acceptable, and the second is to accept the input regardless and let some other method in your script handle whether the resulting positional data is usable. I went with the former in my own code, as it cuts down on processing the earlier you can stop an "illegal input", and leaves less room for errors. You seem to have gone for the third option of not having acceptable inputs but rather acceptable targets. I'd have a tough time debugging that kind of thing... In the former method, you'd essentially just check if the firstPressPosition is within the bounds you've set in screen space- and if it isn't, then don't even bother recording it, or better yet record it as Vector2.zero. Have the followup for the "ended" conditional check if the first position is Vector2.zero and skip that part too if it is. That way the input never even makes it into your game. You might also want to put in a mid-drag update check and force the drag to end when it runs outside of the border of your "play area".
well il do something like this. Code (CSharp): private float oldx; private float oldy; void Update() { oldx = transform.position.x; oldy = transform.position,y; if (clickinthemenu) { transform.position = new Vector2 ( oldx, oldy); } im not sure if this will work but I'm a bit of a noob