- Home /
Method to return lists...
Hi Guys, I have created two classes Road and StreetGenerator. Road makes road (list) from lanes with specific width. StreetGenerator supposed to make left side of road and right side of the road using MakeRoad() method from Road class.
Questions: 1. Where would you keep all the variable for road creation? (in Road or StreetGenerator) 2. I managed to reference Road class in StreetGenerator, but how I create two roads? If I use MakeRoad() twice I still got just one road.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Road : MonoBehaviour
{
//Road control variables
public bool isRoadOnBothSides;
public GameObject lanePrefab;
public float laneWidth;
public int numberOfLanes;
private List<GameObject> laneList = new List<GameObject>();
private float laneOffset;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
// MakeRoad();
}
//Create Road form lane objects.
public List<GameObject> MakeRoad()
{
if (laneList.Count < numberOfLanes)
{
AddLane();
}
else if (laneList.Count > numberOfLanes)
{
RemoveLane();
}
ScaleLane(); //scales lane gameobjects in run time
CheckLanePosition(); // checks and adjust lane position after scale change
return laneList;
}
//Add lane
public void AddLane()
{
laneOffset = laneWidth * laneList.Count;
GameObject lane = Instantiate(lanePrefab, new Vector3(laneOffset, 0, 0), Quaternion.identity);
laneList.Add(lane);
}
//Scale lane
public void ScaleLane()
{
for (int i = 0; i < laneList.Count; i++)
{
laneList[i].transform.localScale = new Vector3(laneWidth, 1, 1);
//laneList[i].GetComponent<SpriteRenderer>().size = new Vector2(laneWidth, 2.1f);
}
}
//Check lane position
public void CheckLanePosition()
{
for (int i = 0; i < laneList.Count; i++)
{
laneList[i].transform.position = new Vector3(laneWidth * i, 0, 0);
}
}
//Remove lane
public void RemoveLane()
{
GameObject destroyLane = laneList[laneList.Count - 1];
laneList.Remove(destroyLane);
Destroy(destroyLane);
}
}
Am I doing something wrong with instantiate ?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StreetGenerator : MonoBehaviour
{
Road road; // reference to Road class
private List<GameObject> leftRoad = new List<GameObject>(); // List of lanes on left side. This is a default list if isRoadOnBothSides is False
private List<GameObject> rightRoad = new List<GameObject>();
// Start is called before the first frame update
void Start()
{
road = FindObjectOfType<Road>(); // find Road class in the scene
}
// Update is called once per frame
void Update()
{
//leftRoad = road.MakeRoad();
//rightRoad = road.MakeRoad();
}
}
Answer by JavaMcGee · Jun 18, 2020 at 09:26 PM
Sorry to suggest to change a lot, but I'd turn this around and put the MakeRoad and all the functions it uses in the StreetGenerator - so StreetGenerator does all the work to make roads. And move the road control values to a third class called RoadSpec which is a plain class and not a MonoBehaviour, that you can pass to StreetGenerator like MakeRoad(roadSpec). To get different kinds of road you would make several types of RoadSpec, either fill in different values, make subclasses that set them in the constructor, or if you're going to have lots of road types, check out ScriptableObjects.
(Also I think you'd use MakeRoads from Start, not from Update)
Answer by Artpen · Jun 18, 2020 at 10:20 PM
Thank you @JavaMcGee It is exactly what I was looking for. Some advice. It is an early prototype so I can change it no problem. I want to be sure I will not have many problems when it gets bigger. This is a reason why asked the question.
May I check with you something:
My street will have (left & right roads, pavements, and and buildings) all simple 2d sprites. Initially I thought to keep them as separate classes Road, Pavement, Buildings ... And have StreetGenerator to handle position of these elements. Is not putting all functions fro roads, pavements and buildings into StreetGenerator will make too big?
RoadSpec is great idea! MakeRoad(roadSpec), so is it possible to get the whole bunch of variables in one call to a class roadSpec?
I was planning that the user will design the road so there is going to be only one road at time. But user is able to change its parameters at runtime. Don't think I will need ScriptableObjects?
Thank you for your help
1) I wouldn't worry too much about the number of functions in StreetGenerator. If it's hundreds or a thousand lines long then maybe think of splitting into parts like a separate BuildingGenerator. 2) Not quite sure about the question: but roadSpec can have lots of variables and they could be public so accessible to the StreetGenerator class (roadSpec.laneWidth). 3) If the user is designing the road variables then, no, ScriptableObject might not be useful.
Thank you @Java$$anonymous$$cGee . Will try to reorganise my code.
Ok so what does the Road class is going to do? StreetGenerator() makes road and have all methods RoadsSpec() holds variables
Was looking at it bit more. And wondering if I have to use object pooling? So my StreetGenerator is a pooler of roads. pavements and so on...?