So I got a list of roads, in game user can add more roads to this list. It starts as null.
So I create one road and OnDrawGismos going through all edges of my road and displays debug rays. All great.
As soon as I add second road to the list gizmos form the first road disappears and only second road gizmos are displayed !?
I think I am not fully understand how foreach loop and OnDrawGizmos work.
Appreciate some help.
What is often happening in these cases is one of the following:
the code you think is executing is not actually executing at all
the code is executing far EARLIER or LATER than you think
the code is executing far LESS OFTEN than you think
the code is executing far MORE OFTEN than you think
the code is executing on another GameObject than you think it is
To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.
Doing this should help you answer these types of questions:
is this code even running? which parts are running? how often does it run? what order does it run in?
what are the values of the variables involved? Are they initialized? Are the values reasonable?
are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)
Knowing this information will help you reason about the behavior you are seeing.
You can also put in Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene
You could also just display various important quantities in UI Text elements to watch them change as you play the game.
If you are running a mobile device you can also view the console output. Google for how on your particular mobile target.
Here’s an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:
Is it because I assign the same nodes and edges list to a different road object, but because the same one was assigned to previous road object. So basically both road objects will have the same lists?
public class RoadDraw : MonoBehaviour
{
private List<Road> roads = new List<Road>();
private List<RoadNode> nodes = new List<RoadNode>();
private List<RoadEdge> edges = new List<RoadEdge>();
public GameObject nodeIconPrefab;
public float roadWidth = 5f;
private int roadIndexCount = 0;
// Start is called before the first frame update
void Start()
{
InputController.onRoadDraw += CreateRoadData;
}
// Unsubscribe from event
private void OnDestroy()
{
InputController.onRoadDraw -= CreateRoadData;
}
// Debug road gizmos
private void OnDrawGizmos()
{
foreach (var road in roads)
{
foreach (var edge in road.Edges)
{
// Road edge debug
Gizmos.color = Color.red;
Gizmos.DrawRay(edge.StartPosition, edge.GetDirection());
// Road offset debug vector
Gizmos.color = Color.blue;
Gizmos.DrawRay(edge.StartPosition, edge.GetOffsetVector() * roadWidth);
Gizmos.DrawRay(edge.StartPosition, edge.GetOffsetVector() * -roadWidth);
Gizmos.DrawRay(edge.EndPosition, edge.GetOffsetVector() * roadWidth);
Gizmos.DrawRay(edge.EndPosition, edge.GetOffsetVector() * -roadWidth);
}
}
}
// Add new road to the list
public void AddRoad()
{
roads.Add(new Road());
nodes.Clear();
edges.Clear();
roadIndexCount++;
}
// Draw road by placing nodes
private void CreateRoadData()
{
PlaceNode();
CreateEdges();
SetRoadData();
}
// Place nodes
private void PlaceNode()
{
Vector3 nodePosition = GeneralHelper.GetMouseWorldPosition();
GameObject nodeIcon = Instantiate(nodeIconPrefab);
nodeIcon.transform.SetParent(this.transform);
nodes.Add(new RoadNode(nodePosition, nodeIcon));
}
// Create road edges
public void CreateEdges()
{
edges.Clear();
for (int i = 0; i < nodes.Count - 1; i++)
{
edges.Add(new RoadEdge(nodes[i].Position, nodes[i + 1].Position));
}
}
// Set Road data to current road
public void SetRoadData()
{
int currentRoadIndex = roadIndexCount - 1;
roads[currentRoadIndex].Nodes = nodes;
roads[currentRoadIndex].Edges = edges;
roads[currentRoadIndex].Width = roadWidth;
}
Sorry @Kurt-Dekker posted my reply before seeing yours.
So the question is. If I have two object and I assign a lest to them. If I would change the list these changes will apply to both objects?
You have a list of roads and a list of edges. Those are separate lists.
If you want edges to “belong” to a road, then perhaps put the list of edges inside the Road or RoadNode class.
Otherwise they’re just a list of edges.
Again, to find out what’s happening, strip it down to two tiny 1-segment roads, print out the values involved. It can’t be that complicated to see where the data storage logic is not matching your data model.
I think I got it, when I assign a list to my roads objects. I just passing the reference. So each time I create a new road object I changing a list for all road objects I had previously.
How would I assign a new list to each road, so each road has its own independent list of information?
// Set Road data to current road
public void SetRoadData()
{
int currentRoadIndex = roadIndexCount - 1;
roads[currentRoadIndex].Nodes = nodes;
roads[currentRoadIndex].Edges = edges;
roads[currentRoadIndex].Width = roadWidth;
}
Yes I am creating multiple road objects within roads list. I have nodes and edges lists within road class.
I am creating separate lists of edges and nodes in RoadDraw script and passing them to roads.
But I think because my nodes and edges are basically the same list to each road object. I have to make a clone of before passing them to the road, otherwise they still pointing to the same list