- Home /
Script to Tell if Circuit / Path is Complete
Thanks for clicking!
What I'm trying to do is create a game reminiscient of Pipe Dream, and those little plastic picture slider puzzles. The point is to complete a path from the start block to the end block. Each block has an invisible "waypoint" block that collides with nothing, and is used simply for raycasts - it's how the player moves, snapping from block to block. The player can't move unless the block he's on and the block he wants to move to are connected by open sides.
Here's a screenshot for context:
http://i.imgur.com/RhBXb.png (link because the built-in image uploader on the questions form keeps popping up the picture in front of the "accept" button, rendering it unacceptable :P)
Basically, using the way points and raycasting method of moving my character, I'm trying to write a script that checks for whether an unbroken path between the start and finish has been made. Unfortunately, the script I've written has led to infinite loops, array out of bounds, and some other strange freezing issues with debug enabled and viewing the object with said script (?!?). Point is, it doesn't work - I feel like I'm close, but after 5 hours of tinkering, I haven't been able to get it functional.
That's where you come in, if you'd be so kind; here's the script, if anybody could give me tips on:
What I'm doing wrong
A better way of doing it
General issues you find
I'd very much appreciate it.
Here's the script, as is:
using UnityEngine; using System.Collections; using System.Collections.Generic;
public class CheckVictoryConditions : MonoBehaviour {
private bool foundOpens;
private bool victory;
private int timeCount;
private int tilesIndex;
private Tile curTile;
private List<Tile> tiles = new List<Tile>();
// helper
[System.Serializable]
public class Tile {
public Transform transform;
public bool checkedDirs = false;
public Tile[] opens = new Tile[4];
public Tile(Transform t) {
this.transform = t;
this.checkedDirs = false;
for (int i = 0; i < 4; i++) {
opens[i] = null;
}
}
}
// Use this for initialization
void Start() {
victory = false;
foundOpens = false;
timeCount = 0;
tilesIndex = 0;
curTile = new Tile(GameObject.Find("Tile_Start").GetComponent<Transform>());
tiles.Add(curTile);
Debug.Log(curTile.transform);
}
// Update is called once per frame
void Update() {
//while (CheckAnyOpens() == true) {
if (CheckAnyOpens() == true) {
curTile.opens = CheckTile(curTile); // check current tile
if (foundOpens == true) {
PickTile(curTile);
foundOpens = false;
}
SetTile(curTile, tilesIndex); // set tile up or down
if (curTile.transform.name == "Tile_Finish") {
victory = true;
//break;
}
}
//}
if (curTile.transform.name == "Tile_Finish") {
victory = true;
}
//Debug.Log(victory);
}
void ShiftTileIndex(Tile tile) {
// shift the working tile index
if (tile.opens[0] != null || tile.opens[1] != null || tile.opens[2] != null || tile.opens[3] != null) {
tilesIndex += 1;
foundOpens = true;
}
else {
tilesIndex -= 1;
foundOpens = false;
if (tilesIndex < 0) {
tilesIndex = 0;
}
}
}
void PickTile(Tile tile) {
for (int i = 0; i < 4; i++) {
if (tile.opens[i] != null && tile.opens[i].checkedDirs == false) {
tile = tile.opens[i];
tiles.Add(tile);
}
}
}
void SetTile(Tile tile, int index) {
if (index >= 0) {
tile = tiles[index];
}
}
// Goes through levels and checks if there are any remaining open paths to check
bool CheckAnyOpens() {
bool anyOpens = false;
for (int i = 0; i < tiles.Count; i++) {
for (int k = 0; k < 4; k++) {
if (tiles[i].opens[k] != null && tiles[i].opens[k].checkedDirs == false) {
anyOpens = true;
break;
}
}
}
Debug.Log("anyOpens = " + anyOpens);
return anyOpens;
}
// For current tile, checks each of the 4 directions for an open path, returns positions of waypoints for the open
// paths so that they can be checked for paths as well
Tile[] CheckTile(Tile tile) {
Debug.Log("CheckTile");
// should check to see if the tile is already listed in tiles or not, and if so, returns current opens
//foreach (Tile t in tiles) {
// if (t.transform.position == curTile.transform.position) {
// Debug.Log("Already have this tile");
// return curTile.opens;
// }
//}
Tile[] opens = new Tile[4];
for (int i = 0; i < 4; i++) {
opens[i] = null;
}
RaycastHit hit;
int targetLayer = 9;
// In order W, A, S, D
Physics.Raycast(tile.transform.position + Vector3.forward, Vector3.forward, out hit, Mathf.Infinity);
if (hit.transform.gameObject.layer == targetLayer) {
opens[0] = new Tile(hit.transform);
Debug.Log("Open path W");
}
Physics.Raycast(tile.transform.position + -Vector3.right, -Vector3.right, out hit, Mathf.Infinity);
if (hit.transform.gameObject.layer == targetLayer) {
opens[1] = new Tile(hit.transform);
Debug.Log("Open path A");
}
Physics.Raycast(tile.transform.position + -Vector3.forward, -Vector3.forward, out hit, Mathf.Infinity);
if (hit.transform.gameObject.layer == targetLayer) {
opens[2] = new Tile(hit.transform);
Debug.Log("Open path S");
}
Physics.Raycast(tile.transform.position + Vector3.right, Vector3.right, out hit, Mathf.Infinity);
if (hit.transform.gameObject.layer == targetLayer) {
opens[3] = new Tile(hit.transform);
Debug.Log("Open path D");
}
ShiftTileIndex(tile);
tile.checkedDirs = true;
return opens;
}
}
The idea was to deal with it like this: the computer would start at the Start block, check for open paths in the four directions (WASD, or up down left right), and if there were any, store them in an array. It would also move the tilesIndex up one, so that when I ran into a block with no open paths, I could just move back one using the tiles list.
From there, I'd pick one of the open paths on this block, then move to the block in that direction, and repeat the process. Each time I check a block I'd mark it as "checked" so that I wouldn't end up bouncing back and forth between two blocks. On paper it seems like this should run through every block connected to the Start block when it's called, but if it's not giving me an infinite loop or crashing Unity, it's not advancing blocks properly or something. I'm really not sure.
I hope that's enough information. Thanks :)
Note: I know the code is probably pretty poorly done, if there's anything confusing or lacking in description, I'll be sure to add to the description.
Note2: Apparently it doesn't want to keep the code's formatting. Sorry. :|
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Need an advise to upgrade my code!!! 1 Answer
How to select adjacent cubes along edges? 2 Answers
How to make AI wonder about? C#? 2 Answers