- Home /
Problem with creating a random generation script
Hi all. In my spare time I've been working on a random generator in Unityscript that uses individual modules that connect to each other. For ease of use I'm using it as a dungeon generator at the moment.
I have an array of connectors (which, in a dungeon setting would be doors) that belong to the starting module called pendingExits and have it iterate through them all to find other modules that have connectors with a matching tag so as to randomly pick one, instantiate it, then line it up. This works perfectly. The problem appears to happen when it's time for the second iteration. I collect all the connectors on these new modules that aren't already in use and replace all the connectors in pendingExits with these new ones. It's at this point that it breaks. Sometimes it can manage to create one module on the second iteration, but that's pretty rare.
It seems like the answer is staring me right in the face, but I just can't figure out where I've gone wrong.
I'll add the code here in case it's obvious to someone else just by looking, but otherwise I have a link to the project here: https://www.dropbox.com/s/u835gil43bnpqhu/RandomGenerator.rar?dl=0
ModularWorldGenerator2
#pragma strict
import System.Collections.Generic;
import System.Linq;
var modules2 : GameObject[]; //NOTE: Using prefabs loses the mesh, use modules in the hierarchy, then disable them.
var startModule2 : GameObject;
var iterations2 = 5;
var newExitsCount = 0;
function Start ()
{
var startModule2 = Instantiate(startModule2, transform.position +Vector3(0,0,0), transform.rotation);
var pendingExits = new Array(startModule2.GetComponent(Module2).GetExits()); //This gets all the module connectors attached to the starting module.
for (var iteration = 0; iteration < iterations2; iteration++) //This is for repeating the generation for each iteration specified.
{
var newExits = new Array(0); //Need to decide if I'm using lists or arrays.
for(var pendingExit:ModuleConnector2 in pendingExits) //Cycle through the module connectors.
{
print("New Exits Count " + newExitsCount);
var newTag = GetRandom(pendingExit.connectorTags);
print("New Tag = '" + newTag + "'");
var newModuleObject = GetRandomWithTag(modules2, newTag);
var newModulePrefab : GameObject = newModuleObject; //This is to convert the object to a GameObject to access it's components.
print("New Prefab = '" + newModulePrefab.name + "'");
var newModule = Instantiate(newModulePrefab);
var newModuleExits = newModule.GetComponent(Module2).GetExits();
var exitToMatch = GetRandom(newModuleExits);
MatchConnectors(pendingExit, exitToMatch);
UpdateNewConnectors(newModuleExits,exitToMatch,newExits,newExitsCount);
}
pendingExits = newExits;
newExitsCount = 0;
}
}
function GetRandom(randomArray:Array) //Picks a random value in an array and returns it.
{
return randomArray[Random.Range(0, randomArray.length)];
}
function GetRandomWithTag(modules:GameObject[],tagToMatch:String) //Fetches a random module that has matching tags.
{
var selectedModules = new Array(0); //This stores the modules that have a matching tag.
var positiveMatches = 0;
//var negativeMatches = 0;
for(var i=0; i < modules.Length; i++) //Cycles through the available modules.
{
//print("ForEach Loop Iteration = '" + i + "'");
if (modules[i].GetComponent(Module2).moduleTags.Contains(tagToMatch)) //Checks if the module has the specified tag.
{
print("Possible Room Option #" + i + ":" + modules[i].name);
positiveMatches++;
selectedModules.length = positiveMatches; //Increases the size of the array by 1 to make room for a matching module.
print("Selected Modules Count = " + selectedModules.length);
selectedModules[i] = modules[i]; //Adds the matching module into the space created by the previous line.
}
if (!modules[i].GetComponent(Module2).moduleTags.Contains(tagToMatch)) //This cycles through all the modules that don't have the specified tag.
{
//negativeMatches++;
print("Possible Room Option #" + i + ": No Match.");
}
}
print("Positive Matches: " + positiveMatches);
//print("Negative Matches: " + negativeMatches);
print("Final Selected Modules Count = " + selectedModules.length);
return GetRandom(selectedModules); //Returns the array of matching modules.
}
function MatchConnectors(oldExit:ModuleConnector2,newExit:ModuleConnector2) //Lines up the rooms based on their connectors.
{
var newModule = newExit.transform.parent; //The transform of the current new module.
var forwardVectorToAlignWith = -oldExit.transform.forward;
var alignmentRotation = Azimuth(forwardVectorToAlignWith) - Azimuth(newExit.transform.forward);
newModule.RotateAround(newExit.transform.position,Vector3.up,alignmentRotation);//This rotates the module around the connector to line it up.
var alignmentTranslation = oldExit.transform.position - newExit.transform.position;
newModule.transform.position += alignmentTranslation;
}
function UpdateNewConnectors(newConnectors:Array,pickedConnector:ModuleConnector2,updatedList:Array,newExitsAmount:int)
{
//Need to increase the newExits array by one and add to it for each connector that hasn't been picked.
//Maybe try creating an array in here and returning it, instead of modifying an array elsewhere.
for(var i=0; i < newConnectors.length; i++)
{
print("Is this an unused connector? - " + i);
if(newConnectors[i] != pickedConnector)
{
print("YES!");
print("Updated List + " + i);
updatedList.length += 1;
print("Updated List Length = " + updatedList.length);
updatedList[newExitsAmount] = newConnectors[i];
newExitsAmount += 5;
}
if(newConnectors[i] == pickedConnector)
{
print("NO.");
}
}
}
function Azimuth(vector:Vector3)
{
return Vector3.Angle(Vector3.forward, vector) * Mathf.Sign(vector.x);
}
Module2
#pragma strict
public var moduleTags : String[];
function GetExits()
{
return GetComponentsInChildren(ModuleConnector2);
}
ModuleConnector2
#pragma strict
public var connectorTags : String[];
public var isDefault2 : boolean;
var thisObject : GameObject;
function Start()
{
thisObject = this.gameObject;
}
function OnDrawGizmos()
{
var scale = 1.0f;
Gizmos.color = Color.blue;
Gizmos.DrawLine(transform.position, transform.position + transform.forward * scale);
Gizmos.color = Color.red;
Gizmos.DrawLine(transform.position, transform.position - transform.right * scale);
Gizmos.DrawLine(transform.position, transform.position + transform.right * scale);
Gizmos.color = Color.green;
Gizmos.DrawLine(transform.position, transform.position + Vector3.up * scale);
Gizmos.color = Color.yellow;
Gizmos.DrawSphere(transform.position, 0.125f);
}
I'm almost definite that the issue lies in the UpdateNewConnectors function, or something that it effects. Without it the script runs fine, though it never gets new connectors so it just keeps making and placing the same modules in the same spots for every iteration.
I would be extremely grateful for any assistance, thank you. =)