I am stuck on this and can’t quite wrap my head around what is wrong. I am trying to create a single pathway with random turns, simply starting at 0,0,0 and randomly branching out from there until it hits it’s limit. The path also can’t intersect itself at any time.
Right now, the code works great unless it’s a large path, Unity gets hung up making it. I can’t quite figure out where it’s getting hung up, I can’t get anything print in the console because Unity just freezes. My guess is that it closes in on itself and has nowhere to go, but isn’t destroying the path and trying again, which is what I’m trying to get it to do if that happens.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PathCreator : MonoBehaviour
{
// to do:
// create path
// start coroutine
// create first block
// create loop for creating other blocks
// pick random directon
// after direction selected, find the coordinates of where new step would be
// check that there isn't already a block there
// if there isn't, check all coordinates around it.
// if there are 3 empty coordinates create block
public List<Vector2> steps = new List<Vector2> ();
public List<Vector2> randomDirections = new List<Vector2> ();
public int pathCountMin;
public int pathCountMax;
int pathCount;
GameObject pathContainer;
public Material matHidden;
public Material matShown;
public Material matCheckPoint;
public Material matEnd;
// Use this for initialization
void Start ()
{
//add 4 random directions to the list
randomDirections.Add (new Vector2 (0, 1));
randomDirections.Add (new Vector2 (0, -1));
randomDirections.Add (new Vector2 (1, 0));
randomDirections.Add (new Vector2 (-1, 0));
pathContainer = GameObject.FindWithTag ("PathContainer");
}
// Update is called once per frame
void Update ()
{
}
public void CreatePath ()
{
steps.Clear ();
//get a final count to know how long to make the path
pathCount = Random.Range (pathCountMin, pathCountMax);
//create first step to start the path
GameObject firstStep = GameObject.CreatePrimitive (PrimitiveType.Cube);
firstStep.transform.position = new Vector3 (0, -0.5f, 0);
firstStep.transform.localScale = new Vector3 (1, 0.5f, 1);
firstStep.name = "Cube " + steps.Count;
firstStep.transform.parent = pathContainer.transform;
steps.Add (new Vector2 (firstStep.transform.position.x, firstStep.transform.position.z));
StartCoroutine (CreateSteps ());
//HidePath ();
//ShowFirstStep ();
}
IEnumerator CreateSteps ()
{
//this will run the code for each step until pathCount is reached
for (int i = 0; i <= pathCount - 1; i++) {
bool testGood = false;
bool blockCreated = false;
List<Vector2> usedDirections = new List<Vector2> ();
do {
//find coordinates of the new step and mark openSpace as true if there is no step already there
Vector2 direction = randomDirections [Random.Range (0, randomDirections.Count)];
Vector2 lastStep = steps [steps.Count - 1];
Vector2 newStep = lastStep + direction;
if (!usedDirections.Contains (direction)) {
usedDirections.Add (direction);
}
while (steps.Contains(newStep)) {
//destroys path if all directions have been attempted
if (usedDirections.Count > 3) {
DestroyPath ();
} else {
//picks a new direction until it lands on one that hasn't been used yet.
while (usedDirections.Contains(direction)) {
direction = randomDirections [Random.Range (0, randomDirections.Count)];
}
if (!usedDirections.Contains (direction)) {
usedDirections.Add (direction);
}
newStep = lastStep + direction;
}
}
print (usedDirections.Count);
testGood = false;
int testCount = 0;
// //Check each direction around the new step. For each empty spot add 1 to testCount. If 3
// //successful testCounts exist, mark it as tested.
foreach (Vector2 dir in randomDirections) {
Vector2 testStep = dir + newStep;
if (!steps.Contains (testStep)) {
testCount += 1;
}
}
if (testCount <= 2) {
print ("tests failed");
if (!usedDirections.Contains (direction)) {
usedDirections.Add (direction);
}
testGood = false;
} else if (testCount == 0) {
DestroyPath ();
} else {
testGood = true;
}
//if tests pan out, create the next step and move on
if (testGood == true) {
GameObject step = GameObject.CreatePrimitive (PrimitiveType.Cube);
step.transform.position = new Vector3 (newStep.x, -0.5f, newStep.y);
step.transform.localScale = new Vector3 (1, 0.5f, 1);
step.name = "Cube " + steps.Count;
step.transform.parent = pathContainer.transform;
steps.Add (new Vector2 (step.transform.position.x, step.transform.position.z));
blockCreated = true;
usedDirections.Clear ();
}
} while (blockCreated == false);
}
yield return null;
}
void DestroyPath ()
{
StopAllCoroutines ();
foreach (Transform step in pathContainer.GetComponentsInChildren<Transform>()) {
if (step.tag == "PathContainer") {
} else {
Destroy (step.gameObject);
}
}
steps.Clear ();
print ("Had to Destroy Path");
CreatePath ();
}
void HidePath ()
{
foreach (Transform step in pathContainer.GetComponentsInChildren<Transform>()) {
if (step.tag == "PathContainer") {
} else {
step.gameObject.renderer.material = matHidden;
}
}
}
void ShowFirstStep ()
{
Collider[] colliders;
if ((colliders = Physics.OverlapSphere (new Vector3 (0, -0.5f, 0), 0.2f)).Length > 0) { //Presuming the object you are testing also has a collider 0 otherwise
foreach (Collider col in colliders) {
GameObject go = col.gameObject;
Debug.Log ("hello");
Debug.Log (go);
go.renderer.material = matShown;
}
}
}
}