Hi,
I’m working on a script which aligns sections of various shapes one after the other to create a level/path. The 5 sections are initially laid in the scene but ‘out of the way’ - we’ll call this the Parking Lot (thanks Fattie for the idea ) so they can be positioned into the level when required. These sections are held in a public Transform List called ‘ParkLotSectionList’ with indices (0 to 4)and dragged into their slots via the Inspector.
Each section has its pivot at one end (the start) and an empty object at the other (the end-point to which each section bolts onto).
The idea behind the script is to initially have 2 sections of the level sitting in the scene. A random number is passed to the script which selects an index of ParkLotSectionList (ie. a section) to add next. Now, in order to always have one of each section in the Parking Lot at all times, I have Instantiated one in its place at the same time. Therefore, I have created another List called ‘PrefabSectionList’ to hold each of the 5 section prefabs. So for example, if the random number is 1 (section2), then a section2 will be Instantiated on top of the one in the Parking Lot then section2 will be positioned at the end of the level. This all works fine and I can add sections one after the other correctly.
However, I am also trying to destroy the sections from the very start as each new one is added to the end. So, if we have section1 + section2 initially, then, if section3 is added to section2, I would like section1 to be destroyed, and so on. In order to achieve this, I created a List to keep track of which sections are currently in the level - called ‘CurrentlyLaidSectionList’. This is public and initially made of size 2 in the Inspector to hold the first 2 sections in the scene (section1 and section2) which were dragged into the slots. The new section is added to ‘CurrentlyLaidSectionList’, then the first element is removed (the first section in level), and finally the section is removed (Destroyed) from the scene. Now, this seems to go as planned up to a point and usually around 4 iterations (sections added and destroyed), so the first thing that springs to mind is that one of the Lists is over-flowing somewhere, not sure where or which, though. :s
When this does go wrong, if looking at the List’s contents in the Inspector, they show the following (sorry, not very specific) errors. The ‘ParkLotSectionList’ shows missing sections, usually starting with just one, then more as the iterations continue. The ‘CurrentlyLaidSectionList’ begins to have empty slots too. All of the missing slots vary each time.
Note, to control the rate at which the sections are added, I am using a key press - ‘A’, in Update().
The script is shown below;
Any help with this would be fantastic! Please ask any questions.
//---------------
public class SectionAssembler : MonoBehaviour
{
// Array of Strings used to keep track of whether a Section is used or not
// private List<string> SectionList = new List<string>();
// The array of sections in the Parking Lot
public List<Transform> ParkLotSectionList = new List<Transform>();
// List of the prefabs of the sections to use in case one does not exist in the scene
public List<Transform> PrefabSectionList = new List<Transform>();
// The currently laid sections in the scene - not the parking lot sections
public List<Transform> CurrentlyLaidSectionList = new List<Transform>();
// The positions of the sections in the parking lot - should not change
private List<Transform> ParkLotParkingSpotList = new List<Transform>();
// The End-point of the first section in the scene that we will add onto
// Added in Inspector
public Transform StartingSectionEndpoint;
// Used to select which section to add to position in the scene next
// This is a random number passed in from the LevelAlign script
// private int SectionSelected;
// Obj ref to the Track Assembler empty object containing LevelAlign script
private GameObject TrackAssemObj;
// Used to keep track of the End-point to add to
private Transform endPointMarker;
// Flag used to only call something once
private bool firstSection = true;
void Start()
{
// Find Track Assembler object
TrackAssemObj = GameObject.Find("Track Assembler");
ParkLotParkingSpotList = ParkLotSectionList;
}
void Update()
{
if (Input.GetKeyDown("a"))
{
// Get the random number between 0 and 4
int RandIndex = GetComponent<RandomNumberGen>().RandomNum;
Debug.Log("RandIndex = " + RandIndex);
// Debug.Log("Section 1 Endpoint = " + EndP.position);
Transform newSection = Instantiate(PrefabSectionList[RandIndex], ParkLotParkingSpotList[RandIndex].position, ParkLotParkingSpotList[RandIndex].rotation) as Transform;
AlignSections(RandIndex);
}
}
//-----------------------------------------------------
// Used to receive the random number as the SectionIndex - ie. to select
// which section to use next
void AlignSections(int ChosenIndex)
{
// Set nextTrans to reference the chosend section
Transform nextTrans = ParkLotSectionList[ChosenIndex];
// If nextTrans does not yet have a value - ie this is the first section we are adding,
// then assign it the StartingSectionEndpoint values.
if (firstSection)
{
// Set the position of nextTrans to the same as the section's End-point
nextTrans.position = StartingSectionEndpoint.position;
// Set the rotation of nextTrans to the same as the section's End-point
nextTrans.rotation = StartingSectionEndpoint.rotation;
// Add the new section to the end of the CurrentlyLaidSectionList List
CurrentlyLaidSectionList.Add(nextTrans);
// Pass the current section to the setLastEndpoint method to keep track of the endpoint
setLastEndpoint(ChosenIndex);
// Set the flag to false as the following sections will not be the first
firstSection = false;
}
// Otherwise, assign it the End-point values for the following sections
else
{
// Call the getLastEndpoint method which returns the End-point of the last Section/Transform
// Get its position and set to nextTrans
nextTrans.position = getLastEndpoint().position;
// Get its rotation and set to nextTrans
nextTrans.rotation = getLastEndpoint().rotation;
// Add the new Section to the end of the CurrentlyLaidSectionList List
CurrentlyLaidSectionList.Add(nextTrans);
// Pass the current section to the setLastEndpoint method to keep track of the endpoint
setLastEndpoint(ChosenIndex);
Debug.Log("CurrentlyLaidSectionList[0] = " + CurrentlyLaidSectionList[0]);
// Remove section at back from the scene
Destroy(CurrentlyLaidSectionList[0].gameObject);
// Remove the first element in the list (first section in level)
CurrentlyLaidSectionList.RemoveAt(0);
}
}
//-----------------------------------------------------
// Keeps track of the last section to be added.
// Finds its end-point and assigns it to endPointMarker
void setLastEndpoint(int sectionIndex)
{
endPointMarker = ParkLotSectionList[sectionIndex].GetComponent<EndpointFinder>().EndPoint;
}
//-----------------------------------------------------
// Returns the End-Point of the last section to be added
Transform getLastEndpoint()
{
return endPointMarker;
}
}