- Home /
Best method for procedural railroads?
Hello!
I am fairly new to Unity (decided to switch from UE4), and I want to implement a procedural railroad system. I tried using a bezier system to generate the tracks procedurally, but that ended up getting me nowhere. So I'm attempting a new method involving a set of premade track pieces. Here's my track pieces:
The idea here is that each piece would have an attachment point at each end, which would be used to align each piece. Howeve, I haven't the faintest idea how to set this up. Would I need each of these parts to have a script, generating the empty transforms as the attachment points? (with a primary Generator to create and attach the pieces) Or can I generate this setup procedurally?
UPDATE: I'm starting to get somewhere, but my math seems to be wrong. I've built a switch-case block to identify which track I'm going to place next, then use an attachPoint variable to lay the track. The issue now is that the generation begins to deteriorate when a curved section is placed. Here's the code:
Vector3 attachPoint = new Vector3(0, 0, 0);
Quaternion attachRot = Quaternion.Euler(0, 0, 0);
for(int x = 0; x < generatorSize; x++)
{
int rng = Random.Range(0, trackElements.Length - 1);
Instantiate(trackElements[rng], attachPoint, attachRot);
switch (trackElements[rng].name)
{
case "railsshort":
attachPoint += new Vector3(0, 0, -138.77f);
break;
case "railsmedium":
attachPoint += new Vector3(0, 0, -282.1f);
break;
case "railslarge":
attachPoint += new Vector3(0, 0, -569.8f);
break;
case "railsshortlightcurve":
attachPoint += new Vector3(-7.2f, 0, -138.5f);
attachRot *= Quaternion.Euler(0, 10f, 0);
break;
case "railsmediumlightcurve":
attachPoint += new Vector3(-36.9f, 0, -278.5f);
attachRot *= Quaternion.Euler(0, 15f, 0);
break;
case "railslargecurve":
attachPoint += new Vector3(-189f, 0, -519f);
attachRot *= Quaternion.Euler(0, 45f, 0);
break;
case "railslargehill":
attachPoint += new Vector3(0, -44.7f, -567.25f);
attachRot *= Quaternion.Euler(-10f, 0, 0);
break;
case "railslargehillup":
attachPoint += new Vector3(0, 44.7f, -567.25f);
attachRot *= Quaternion.Euler(10f, 0, 0);
break;
}
}
The issue appears to be that the attachPoint vector I'm using is not adjusted relative to the new track. How can I get my attachPoint to factor in the position it was originally in?
Answer by xxmariofer · Jan 13, 2019 at 12:41 PM
Hello @aldkouwenhoven, not sure if this is the solution you were expecting, but have you tried creating a child object at the end of each raill and use it as your attachPoint? doing something like this (not tested at all):
attachPoint = Instantiante(trackElements[rng], attachPoint, attachRot).transform.GetChild(0).position;
the world position of the child will always be the exact point you want to use for spawning.
I am attempting this through Blender, but I just need to get the angles right. The issue is getting that point to be just perfect, or else clipping issues might occur.
Edit: Wow... sometimes the simplest solutions are the best! Thank you! Here's the code I whipped up: for (int x = 0; x < generatorSize; x++) { int rng = Random.Range(0, trackElements.Length - 1); attachPoint = Instantiate(trackElements[rng], attachPoint, attachRot).GetChild(0).position; attachRot *= trackElements[rng].GetChild(0).rotation; } Thank you so much!
Your answer
Follow this Question
Related Questions
Which Implementation is Better? A Performance Question 1 Answer
Networked Scoreboard / Highscore Table 2 Answers
How to detect sprite in player's position (2D Platformer Game) And get it t do something 2 Answers
How to implement water buoyancy 1 Answer
Cannot add menu item 'Assets/External Dependency Manager/Version Handler/Update' for method ..... 1 Answer