i am making an endless driving game and i want to generate an endless curved road as my car moves forward
i have been following this tutorial online: http://blog.nick.je/endless-procedural-curved-mesh-generation-in-unity-part-2/
however it is incomplete, and instead of showing how to generate new curves as the player moves forward it only show hot to generate a set amount of curves at the start of the game. i have tried to expand upon the code regardless but what i have so far doesn’t really work. 4uqb5i
as you can see by the past curves doesnt stay consistent as the player moves forward.
here is my code so far:
using UnityEngine;
using System.Collections.Generic;
public class TerrainGeneratorEndless : MonoBehaviour
{
Mesh mesh;
public static float Seed = 144765346f;
// This becomes a list of curves
List<Vector3[]> curves = new List<Vector3[]> ();
List<Vector3> vertices = new List<Vector3> ();
List<int> triangles = new List<int> ();
List<Vector3> ponts = new List<Vector3> ();
float xPos;
float pos;
private int lastZIndex = -10000;
float spos;
public float depth;
MeshFilter filter;
Vector3[] curve;
int zIndex;
public Transform player;
void Start ()
{
filter = GetComponent<MeshFilter> ();
mesh = filter.mesh;
mesh.Clear ();
xPos = 0f;
// For simplicity generate 10 curves
generate(5, true);
}
private void Update()
{
SpawnTiles();
}
private void SpawnTiles()
{
Vector3 playerPos = player.position;
playerPos.z -= depth;
zIndex = (int)(playerPos.z / depth);
float lastX = 0;
//Enable here for the optimization
if (lastZIndex == zIndex)
{
return;//On previour frame I have already changed all time positions for player's position
//I do not have to change the positions again because they are exactly same
}
lastZIndex = zIndex;
filter = GetComponent<MeshFilter>();
mesh = filter.mesh;
mesh.Clear();
//Array.Clear(positions, 0, positions.Length);
generate(5, true);
//BezierPath bezierPath = new BezierPath(positions, false, PathSpace.xyz);
//GetComponent<PathCreator>().bezierPath = bezierPath;
//Array.Clear(positions, 0, positions.Length);
}
//VertexPath GeneratePath(Vector3[] points, bool closedPath)
//{
// print("yo");
// // Create a closed, 2D bezier path from the supplied points array
// // These points are treated as anchors, which the path will pass through
// // The control points for the path will be generated automatically
// BezierPath bezierPath = new BezierPath(points, closedPath, PathSpace.xyz);
// // Then create a vertex path from the bezier path, to be used for movement etc
// return new VertexPath(bezierPath, test);
//}
//void check(int i)
//{
// if (forbiddenPoints.Contains(pos))
// {
// pos += depth;
// check(i);
// }
// else
// {
// curve[i] = new Vector3(n1(pos) * 20, /*n1(pos )*5*/ 0, (spos));
// GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube);
// go.transform.position = curve[i];
// }
//}
float n1(float z)
{
z += Seed;
z = Mathf.Abs(z);
return (Mathf.Sin(((z * 123124.2435345f) % 1f)) * 42353245.3245634f) % 1.0f;
}
float n2(float z)
{
z += Seed;
z = Mathf.Abs(z);
return (Mathf.Sin(((z / 123124.2435345f) % 1.2f)) * 65656.346346f) % 1.0f;
}
float n3(float z)
{
// random.init(z)
// random.range
z += Seed;
z = Mathf.Abs(z);
return (Mathf.Cos(((z * 36456.346346f) % 2.5f)) * 34634.35765f) % 1.0f;
}
void generate(int amount, bool begin)
{
mesh.Clear();
pos = zIndex * depth;
spos = 0;
for (int c = 0; c < amount; c++) {
curve = new Vector3[4];
//xPos = 0;
//xPos = (c * depth);
//xPos += (zIndex) * depth;
for (int i = 0; i < curve.Length; i++) {
Vector3[] prev = null;
if (curves.Count > 0) {
prev = curves [curves.Count - 1];
}
if (prev != null && i == 0) {
// Start of a new curve
// Set to the last point of the previous
curve [i] = prev [curve.Length - 1];
} else if (prev != null && i == 1) {
// First control point of a new curve
// Use the end of the previous curve to calculate
curve [i] = 2f * prev [curve.Length - 1] - prev [curve.Length - 2];
} else {
curve[i] = new Vector3(n1(pos) * 20, /*n1(pos )*5*/ 0, (pos));
}
print(pos);
pos += depth;
}
curves.Add (curve);
}
//https://www.graphicfilth.com/2014/10/3d-bezier-curves-in-unity/
//https://www.bitshiftprogrammer.com/2018/01/altos-adventure-style-procedural.html
// Same drawing code as before but now in a loop
if (begin)
{
foreach (var curve in curves)
{
int resolution = 20;
for (int i = 0; i < resolution; i++)
{
float t = (float)i / (float)(resolution - 1);
Vector3 p = CalculateBezierPoint(t, curve[0], curve[1], curve[2], curve[3]);
AddTerrainPoint(p);
ponts.Add(p);
//
}
}
}
else
{
int resolution = 20;
for (int i = 0; i < resolution; i++)
{
float t = (float)i / (float)(resolution - 1);
Vector3 p = CalculateBezierPoint(t, curve[0], curve[1], curve[2], curve[3]);
AddTerrainPoint(p);
ponts.Add(p);
////
}
}
mesh.vertices = vertices.ToArray();
mesh.triangles = triangles.ToArray();
RoadCreator.Instace.UpdateRoad(ponts);
ponts.Clear();
curves.Clear();
}
void AddTerrainPoint (Vector3 point)
{
// Create a corresponding point along the bottom
//vertices.Add (new Vector3 (point.x, 0f, 0f)); // Then add our top point
vertices.Add (point);
if (vertices.Count >= 4) {
// Completed a new quad, create 2 triangles
int start = vertices.Count - 4;
triangles.Add (start + 0);
triangles.Add (start + 1);
triangles.Add (start + 2);
triangles.Add (start + 1);
triangles.Add (start + 3);
triangles.Add (start + 2);
}
}
private Vector3 CalculateBezierPoint (float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
{
float u = 1 - t;
float tt = t * t;
float uu = u * u;
float uuu = uu * u;
float ttt = tt * t;
Vector3 p = uuu * p0;
p += 3 * uu * t * p1;
p += 3 * u * tt * p2;
p += ttt * p3;
return p;
}
}
//https://gist.github.com/Jakintosh/76b500ed47cc8c8b27e3