Created
January 8, 2024 15:51
-
-
Save sasame/7af41c1ae0d543a7cb5465df2bda7c5c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System.Collections; | |
| using System.Collections.Generic; | |
| using UnityEngine; | |
| using Unity.Mathematics; | |
| using UnityEngine.Splines; | |
| public class SplineRoad : MonoBehaviour | |
| { | |
| [SerializeField] SplineContainer _spline; | |
| [SerializeField] Material _mtl; | |
| [SerializeField] Material _mtlDuraBarrier; | |
| [SerializeField] float _width = 5f; | |
| [SerializeField] float _height = 5f; | |
| [SerializeField] float _divideLength = 1f; | |
| [SerializeField] float _barrierHeight = 1f; | |
| [SerializeField] float _barrierWidth = 0.2f; | |
| Mesh createMesh() | |
| { | |
| List<Vector3> points = new List<Vector3>(); | |
| List<Vector2> uvs = new List<Vector2>(); | |
| List<Vector3> normals = new List<Vector3>(); | |
| List<int> triangles = new List<int>(); | |
| int pointOfs = 0; | |
| foreach(var s in _spline.Splines) | |
| { | |
| var length = s.CalculateLength(float4x4.identity); | |
| int pointCount = 0; | |
| for (float len = 0f; len < length; len += 1f) | |
| { | |
| var t = len / length; | |
| var pos = (Vector3)s.EvaluatePosition(t); | |
| var tangent = s.EvaluateTangent(t); | |
| var up = s.EvaluateUpVector(t); | |
| var right = Vector3.Cross(tangent, up).normalized; | |
| points.Add(pos - right * _width * 0.5f); // left | |
| points.Add(pos + right * _width * 0.5f); // right | |
| uvs.Add(new Vector2(0f,len / _height)); // left | |
| uvs.Add(new Vector2(1f, len / _height)); // right | |
| normals.Add(up); // left | |
| normals.Add(up); // right | |
| ++pointCount; | |
| } | |
| for(int i=0;i< pointCount-1;++i) | |
| { | |
| triangles.Add((i+ pointOfs) * 2 + 0); // 0 | |
| triangles.Add((i+ pointOfs) * 2 + 1); // 1 | |
| triangles.Add((i+ pointOfs) * 2 + 2); // 2 | |
| triangles.Add((i+ pointOfs) * 2 + 1); // 1 | |
| triangles.Add((i+ pointOfs) * 2 + 3); // 3 | |
| triangles.Add((i+ pointOfs) * 2 + 2); // 2 | |
| } | |
| pointOfs += pointCount * 2; | |
| } | |
| var mesh = new Mesh(); | |
| mesh.SetVertices(points); | |
| mesh.SetUVs(0, uvs); | |
| mesh.SetNormals(normals); | |
| mesh.SetTriangles(triangles,0); | |
| mesh.RecalculateTangents(); | |
| return mesh; | |
| } | |
| Mesh createBarrierMesh() | |
| { | |
| List<Vector3> points = new List<Vector3>(); | |
| List<Vector2> uvs = new List<Vector2>(); | |
| List<Vector3> normals = new List<Vector3>(); | |
| List<int> triangles = new List<int>(); | |
| int pointOfs = 0; | |
| foreach (var s in _spline.Splines) | |
| { | |
| var length = s.CalculateLength(float4x4.identity); | |
| int pointCount = 0; | |
| for (float len = 0f; len < length; len += 1f) | |
| { | |
| var t = len / length; | |
| var pos = (Vector3)s.EvaluatePosition(t); | |
| var tangent = s.EvaluateTangent(t); | |
| var up = (Vector3)s.EvaluateUpVector(t); | |
| var right = Vector3.Cross(tangent, up).normalized; | |
| points.Add(pos - right * (_width * 0.5f + _barrierWidth)); // left 0 | |
| points.Add(pos - right * (_width * 0.5f + _barrierWidth) + up * _barrierHeight); // left 1 | |
| points.Add(pos - right * _width * 0.5f + up * _barrierHeight); // left 2 | |
| points.Add(pos - right * _width * 0.5f); // left 3 | |
| points.Add(pos + right * _width * 0.5f); // right0 | |
| points.Add(pos + right * _width * 0.5f + up * _barrierHeight); // right1 | |
| points.Add(pos + right * (_width * 0.5f + _barrierWidth) + up * _barrierHeight); // right2 | |
| points.Add(pos + right * (_width * 0.5f + _barrierWidth)); // right3 | |
| uvs.Add(new Vector2(0f, len / _height)); // left0 | |
| uvs.Add(new Vector2(1f, len / _height)); // left1 | |
| uvs.Add(new Vector2(1f, len / _height)); // left2 | |
| uvs.Add(new Vector2(0f, len / _height)); // left3 | |
| uvs.Add(new Vector2(0f, len / _height)); // right0 | |
| uvs.Add(new Vector2(1f, len / _height)); // right1 | |
| uvs.Add(new Vector2(1f, len / _height)); // right2 | |
| uvs.Add(new Vector2(0f, len / _height)); // right3 | |
| normals.Add(-right); // left0 | |
| normals.Add(-right); // left1 | |
| normals.Add(right); // left2 | |
| normals.Add(right); // left3 | |
| normals.Add(-right); // right0 | |
| normals.Add(-right); // right1 | |
| normals.Add(right); // right2 | |
| normals.Add(right); // right3 | |
| ++pointCount; | |
| } | |
| const int linePoint = 8; | |
| const int lineHalf = 4; | |
| for (int i = 0; i < pointCount - 1; ++i) | |
| { | |
| for (int j = 0; j < 3; ++j) | |
| { | |
| triangles.Add((i + pointOfs) * linePoint + 0 + j); // 0 | |
| triangles.Add((i + pointOfs) * linePoint + 1 + j); // 1 | |
| triangles.Add((i + pointOfs + 1) * linePoint + 0 + j); // 2 | |
| triangles.Add((i + pointOfs) * linePoint + 1 + j); // 1 | |
| triangles.Add((i + pointOfs + 1) * linePoint + 1 + j); // 3 | |
| triangles.Add((i + pointOfs + 1) * linePoint + 0 + j); // 2 | |
| } | |
| for (int j = 0; j < 3; ++j) | |
| { | |
| triangles.Add((i + pointOfs) * linePoint + 0+ lineHalf + j); // 0 | |
| triangles.Add((i + pointOfs) * linePoint + 1 + lineHalf + j); // 1 | |
| triangles.Add((i + pointOfs + 1) * linePoint + 0 + lineHalf + j); // 2 | |
| triangles.Add((i + pointOfs) * linePoint + 1 + lineHalf + j); // 1 | |
| triangles.Add((i + pointOfs + 1) * linePoint + 1 + lineHalf + j); // 3 | |
| triangles.Add((i + pointOfs + 1) * linePoint + 0 + lineHalf + j); // 2 | |
| } | |
| } | |
| pointOfs += pointCount * 2; | |
| } | |
| var mesh = new Mesh(); | |
| mesh.SetVertices(points); | |
| mesh.SetUVs(0, uvs); | |
| mesh.SetNormals(normals); | |
| mesh.SetTriangles(triangles, 0); | |
| mesh.RecalculateTangents(); | |
| return mesh; | |
| } | |
| private void OnDestroy() | |
| { | |
| var mf = gameObject.GetComponent<MeshFilter>(); | |
| if (mf) | |
| { | |
| DestroyImmediate(mf.sharedMesh); | |
| } | |
| } | |
| // Start is called before the first frame update | |
| void Start() | |
| { | |
| { | |
| var o = new GameObject(); | |
| o.name = "Road"; | |
| o.transform.SetParent(transform, false); | |
| var mesh = createMesh(); | |
| var mf = o.AddComponent<MeshFilter>(); | |
| mf.sharedMesh = mesh; | |
| var mr = o.AddComponent<MeshRenderer>(); | |
| mr.sharedMaterial = _mtl; | |
| var mc = o.AddComponent<MeshCollider>(); | |
| mc.sharedMesh = mesh; | |
| } | |
| { | |
| var o = new GameObject(); | |
| o.name = "Barrier"; | |
| o.transform.SetParent(transform, false); | |
| var mesh = createBarrierMesh(); | |
| var mf = o.AddComponent<MeshFilter>(); | |
| mf.sharedMesh = mesh; | |
| var mr = o.AddComponent<MeshRenderer>(); | |
| mr.sharedMaterial = _mtlDuraBarrier; | |
| var mc = o.AddComponent<MeshCollider>(); | |
| mc.sharedMesh = mesh; | |
| } | |
| } | |
| // Update is called once per frame | |
| void Update() | |
| { | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment