public override void Execute(RobotController target, InstructionExecutor executor) { instructionExecutor = executor; robot = target; executeNext = false; var currentX = robot.X; var currentZ = robot.Z; switch (moveDirection) { case Directions.Up: currentX++; break; case Directions.Down: currentX--; break; case Directions.Left: currentZ++; break; case Directions.Right: currentZ--; break; } // Find object at the given direction var obj = softwareLevelGenerator.GetObject(currentX, currentZ); if (obj == null) { throw new InstructionException("Could not find object " + moveDirection.ToString()); return; } var arrayElement = obj.GetComponent <IndexElement>(); if (arrayElement == null) { throw new InstructionException("Could not find object " + moveDirection.ToString()); return; } // Jump to the index of the object adjacent targetPos = softwareLevelGenerator.IndexLocation("a" + arrayElement.Value); var didMove = robot.MoveTo(Vector3.zero, "a" + arrayElement.Value); if (!didMove) { throw new InstructionException("Could not move to " + arrayElement.Value); } // Increment index element arrayElement.Value++; }
// Move to the specified coordinate or index of the an array in the scene // If it is coordinate, it will use the destination vector3 // If destination is Vector3.zero, it will use the array concatenate with index as identifier for accessing the array // e.g "a" + 0 will access index 0 of array a public bool MoveTo(Vector3 destination, string index) { try { // Check if is index or coordinate access var dest = destination; if (destination == Vector3.zero) { dest = generator.IndexLocation(index); if (dest == Vector3.zero) { return(false); } } // Calculate the required distance to translate for x and z var currentPos = isoTransform.Position; int x = (int)(dest.x - currentPos.x); int z = (int)(dest.z - currentPos.z); // This is for storing ths sequence of paths to traverse through Vector3[] path = new Vector3[Mathf.Abs(x) + Mathf.Abs(z) + 1]; path[0] = currentPos; int count = 1; // temp variables are used as a ghost for collision detection int tempX = X; int tempZ = Z; bool moveX = true; bool moveZ = true; // Check z then x by default Debug.Log("Trying z then x"); for (int i = 0; i < Mathf.Abs(z); i++) { tempZ = z < 0 ? --tempZ : ++tempZ; if (generator.GetMapLayout(tempX, tempZ) == SoftwareLevelGenerator.Layout.EMPTY) { path[count] = new Vector3(tempX - 1, Y, tempZ - 1); count++; } else { moveZ = false; } } // Traverse through x for (int i = 0; i < Mathf.Abs(x); i++) { tempX = x < 0 ? --tempX : ++tempX; // Check for collision and add to path if (generator.GetMapLayout(tempX, tempZ) == SoftwareLevelGenerator.Layout.EMPTY) { path[count] = new Vector3(tempX - 1, Y, tempZ - 1); count++; } else { moveX = false; } } // Check if collision exist in z then x path, if it does the reset the path and try path x then z if (!moveZ || !moveX) { moveZ = true; moveX = true; Debug.Log("No z then x path, trying x then z"); path = new Vector3[Mathf.Abs(x) + Mathf.Abs(z) + 1]; path[0] = currentPos; count = 1; // temp variables are used as a ghost for collision detection tempX = X; tempZ = Z; // Traverse through x for (int i = 0; i < Mathf.Abs(x); i++) { tempX = x < 0 ? --tempX : ++tempX; // Check for collision and add to path if (generator.GetMapLayout(tempX, tempZ) == SoftwareLevelGenerator.Layout.EMPTY) { path[count] = new Vector3(tempX - 1, Y, tempZ - 1); count++; } else { moveX = false; } } for (int i = 0; i < Mathf.Abs(z); i++) { tempZ = z < 0 ? --tempZ : ++tempZ; if (generator.GetMapLayout(tempX, tempZ) == SoftwareLevelGenerator.Layout.EMPTY) { path[count] = new Vector3(tempX - 1, Y, tempZ - 1); count++; } else { moveZ = false; } } } // If no collision then run it as a co-routine if (moveX && moveZ) { StartCoroutine(Shift(path)); return(true); } } catch (NullReferenceException e) { return(false); } catch (IndexOutOfRangeException e) { return(false); } Debug.Log("COLLIDE"); return(false); }