protected void Start() { // Generate a fixed array of skidmarks skidmarks = new MarkSection[MAX_MARKS]; for (int i = 0; i < MAX_MARKS; i++) { skidmarks[i] = new MarkSection(); } mf = GetComponent <MeshFilter>(); mr = GetComponent <MeshRenderer>(); if (mr == null) { mr = gameObject.AddComponent <MeshRenderer>(); } marksMesh = new Mesh(); marksMesh.MarkDynamic(); if (mf == null) { mf = gameObject.AddComponent <MeshFilter>(); } mf.sharedMesh = marksMesh; vertices = new Vector3[MAX_MARKS * 4]; normals = new Vector3[MAX_MARKS * 4]; tangents = new Vector4[MAX_MARKS * 4]; colors = new Color32[MAX_MARKS * 4]; uvs = new Vector2[MAX_MARKS * 4]; triangles = new int[MAX_MARKS * 6]; mr.shadowCastingMode = ShadowCastingMode.Off; mr.receiveShadows = false; mr.material = skidmarksMaterial; mr.lightProbeUsage = LightProbeUsage.Off; }
// Initiallizes the array holding the skidmark sections. void Awake() { skidmarks = new MarkSection[maxMarks]; for (int i = 0; i < maxMarks; i++) skidmarks[i] = new MarkSection(); if (((MeshFilter) GetComponent (typeof(MeshFilter))).mesh == null) ((MeshFilter) GetComponent (typeof(MeshFilter))).mesh = new Mesh(); }
// #### PUBLIC METHODS #### // Function called by the wheel that's skidding. Sets the intensity of the skidmark section // by setting the alpha of the vertex color public int AddSkidMark(Vector3 pos, Vector3 normal, float intensity, int lastIndex) { if (intensity > 1) { intensity = 1.0f; } else if (intensity < 0) { return(-1); } if (lastIndex > 0) { float sqrDistance = (pos - skidmarks[lastIndex].Pos).sqrMagnitude; if (sqrDistance < MIN_SQR_DISTANCE) { return(lastIndex); } } if (markIndex == -1 || markIndex == 0) { return(0); } curSection = skidmarks[markIndex]; curSection.Pos = pos + normal * GROUND_OFFSET; curSection.Normal = normal; curSection.Intensity = (byte)(intensity * 255f); curSection.LastIndex = lastIndex; if (lastIndex != -1) { lastSection = skidmarks[lastIndex]; Vector3 dir = (curSection.Pos - lastSection.Pos); Vector3 xDir = Vector3.Cross(dir, normal).normalized; curSection.Posl = curSection.Pos + xDir * MARK_WIDTH * 0.5f; curSection.Posr = curSection.Pos - xDir * MARK_WIDTH * 0.5f; curSection.Tangent = new Vector4(xDir.x, xDir.y, xDir.z, 1); if (lastSection.LastIndex == -1) { lastSection.Tangent = curSection.Tangent; lastSection.Posl = curSection.Pos + xDir * MARK_WIDTH * 0.5f; lastSection.Posr = curSection.Pos - xDir * MARK_WIDTH * 0.5f; } } UpdateSkidmarksMesh(); int curIndex = markIndex; // Update circular index markIndex = ++markIndex % MAX_MARKS; return(curIndex); }
// #### PROTECTED/PRIVATE METHODS #### // Update part of the mesh for the current markIndex void UpdateSkidmarksMesh() { MarkSection curr = skidmarks[markIndex]; // Nothing to connect to yet if (curr.LastIndex == -1) { return; } MarkSection last = skidmarks[curr.LastIndex]; vertices[markIndex * 4 + 0] = last.Posl; vertices[markIndex * 4 + 1] = last.Posr; vertices[markIndex * 4 + 2] = curr.Posl; vertices[markIndex * 4 + 3] = curr.Posr; normals[markIndex * 4 + 0] = last.Normal; normals[markIndex * 4 + 1] = last.Normal; normals[markIndex * 4 + 2] = curr.Normal; normals[markIndex * 4 + 3] = curr.Normal; tangents[markIndex * 4 + 0] = last.Tangent; tangents[markIndex * 4 + 1] = last.Tangent; tangents[markIndex * 4 + 2] = curr.Tangent; tangents[markIndex * 4 + 3] = curr.Tangent; colors[markIndex * 4 + 0] = new Color32(0, 0, 0, last.Intensity); colors[markIndex * 4 + 1] = new Color32(0, 0, 0, last.Intensity); colors[markIndex * 4 + 2] = new Color32(0, 0, 0, curr.Intensity); colors[markIndex * 4 + 3] = new Color32(0, 0, 0, curr.Intensity); //float s = Time.time; //colors[markIndex * 4 + 0] = Color32.LerpUnclamped(new Color32(0, 0, 0, last.Intensity), new Color32(0, 0, 0, 0), Time.time - s <=10 ? 0 : 1); //colors[markIndex * 4 + 1] = Color32.LerpUnclamped(new Color32(0, 0, 0, last.Intensity), new Color32(0, 0, 0, 0), Time.time - s <= 10 ? 0 : 1); //colors[markIndex * 4 + 2] = Color32.LerpUnclamped(new Color32(0, 0, 0, curr.Intensity), new Color32(0, 0, 0, 0), Time.time - s <= 10 ? 0 : 1); //colors[markIndex * 4 + 3] = Color32.LerpUnclamped(new Color32(0, 0, 0, curr.Intensity), new Color32(0, 0, 0, 0), Time.time - s <= 10 ? 0 : 1); uvs[markIndex * 4 + 0] = new Vector2(0, 0); uvs[markIndex * 4 + 1] = new Vector2(1, 0); uvs[markIndex * 4 + 2] = new Vector2(0, 1); uvs[markIndex * 4 + 3] = new Vector2(1, 1); triangles[markIndex * 6 + 0] = markIndex * 4 + 0; triangles[markIndex * 6 + 2] = markIndex * 4 + 1; triangles[markIndex * 6 + 1] = markIndex * 4 + 2; triangles[markIndex * 6 + 3] = markIndex * 4 + 2; triangles[markIndex * 6 + 5] = markIndex * 4 + 1; triangles[markIndex * 6 + 4] = markIndex * 4 + 3; meshUpdated = true; }
// Initiallizes the array holding the skidmark sections. void Awake() { skidmarks = new MarkSection[maxMarks]; for (int i = 0; i < maxMarks; i++) { skidmarks[i] = new MarkSection(); } if (((MeshFilter)GetComponent(typeof(MeshFilter))).mesh == null) { ((MeshFilter)GetComponent(typeof(MeshFilter))).mesh = new Mesh(); } }
// Function called by the wheel that's skidding. Sets the colour and intensity of the skidmark section. public int AddSkidMark(Vector3 pos, Vector3 normal, Color32 colour, int lastIndex) { if (colour.a == 0) { return(-1); // No point in continuing if it's invisible } if (lastIndex > 0) { float sqrDistance = (pos - skidmarks[lastIndex].Pos).sqrMagnitude; if (sqrDistance < MIN_SQR_DISTANCE) { return(lastIndex); } } colour.a = (byte)(colour.a * MAX_OPACITY); MarkSection curSection = skidmarks[markIndex]; curSection.Pos = pos + normal * GROUND_OFFSET; curSection.Normal = normal; curSection.Colour = colour; curSection.LastIndex = lastIndex; if (lastIndex != -1) { MarkSection lastSection = skidmarks[lastIndex]; Vector3 dir = (curSection.Pos - lastSection.Pos); Vector3 xDir = Vector3.Cross(dir, normal).normalized; curSection.Posl = curSection.Pos + xDir * MARK_WIDTH * 0.5f; curSection.Posr = curSection.Pos - xDir * MARK_WIDTH * 0.5f; curSection.Tangent = new Vector4(xDir.x, xDir.y, xDir.z, 1); if (lastSection.LastIndex == -1) { lastSection.Tangent = curSection.Tangent; lastSection.Posl = curSection.Pos + xDir * MARK_WIDTH * 0.5f; lastSection.Posr = curSection.Pos - xDir * MARK_WIDTH * 0.5f; } } UpdateSkidmarksMesh(); int curIndex = markIndex; // Update circular index markIndex = ++markIndex % MAX_MARKS; return(curIndex); }
// #### PROTECTED/PRIVATE METHODS #### // Update part of the mesh for the current markIndex void UpdateSkidmarksMesh() { MarkSection curr = skidmarks[markIndex]; //Debug.Log("UpdateSkidmarksMesh" + markIndex); //Debug.Log("curr.LastIndex" + curr.LastIndex); // Nothing to connect to yet if (curr.LastIndex == -1) { return; } MarkSection last = skidmarks[curr.LastIndex]; vertices[markIndex * 4 + 0] = last.Posl; vertices[markIndex * 4 + 1] = last.Posr; vertices[markIndex * 4 + 2] = curr.Posl; vertices[markIndex * 4 + 3] = curr.Posr; normals[markIndex * 4 + 0] = last.Normal; normals[markIndex * 4 + 1] = last.Normal; normals[markIndex * 4 + 2] = curr.Normal; normals[markIndex * 4 + 3] = curr.Normal; tangents[markIndex * 4 + 0] = last.Tangent; tangents[markIndex * 4 + 1] = last.Tangent; tangents[markIndex * 4 + 2] = curr.Tangent; tangents[markIndex * 4 + 3] = curr.Tangent; colors[markIndex * 4 + 0] = new Color32(0, 0, 0, last.Intensity); colors[markIndex * 4 + 1] = new Color32(0, 0, 0, last.Intensity); colors[markIndex * 4 + 2] = new Color32(0, 0, 0, curr.Intensity); colors[markIndex * 4 + 3] = new Color32(0, 0, 0, curr.Intensity); uvs[markIndex * 4 + 0] = new Vector2(0, 0); uvs[markIndex * 4 + 1] = new Vector2(1, 0); uvs[markIndex * 4 + 2] = new Vector2(0, 1); uvs[markIndex * 4 + 3] = new Vector2(1, 1); triangles[markIndex * 6 + 0] = markIndex * 4 + 0; triangles[markIndex * 6 + 2] = markIndex * 4 + 1; triangles[markIndex * 6 + 1] = markIndex * 4 + 2; triangles[markIndex * 6 + 3] = markIndex * 4 + 2; triangles[markIndex * 6 + 5] = markIndex * 4 + 1; triangles[markIndex * 6 + 4] = markIndex * 4 + 3; meshUpdated = true; }
// Initiallizes the array holding the skidmark sections. void Awake() { skidmarks = new MarkSection[maxMarks]; for (var i = 0; i < maxMarks; i++) { skidmarks[i] = new MarkSection(); } if (GetComponent <MeshFilter>().mesh == null) { GetComponent <MeshFilter>().mesh = new Mesh(); } }
void CheckIfMeshAlreadyCreated() { lastindex = 1; RacingLineParts = new MarkSection[MeshResolution]; for (int i = 0; i < MeshResolution; i++) { RacingLineParts[i] = new MarkSection(); } MeshFilter RacingLineMesh = (MeshFilter)GetComponent(typeof(MeshFilter)); if (RacingLineMesh.mesh == null) { RacingLineMesh.mesh = new Mesh(); } }
private void Awake() { // Pre-Initialize values skidmarks = new MarkSection[maxMarks]; for (int i = 0; i < maxMarks; i++) { skidmarks[i] = new MarkSection(); } meshFilter = GetComponent<MeshFilter>(); if (meshFilter.mesh == null) { meshFilter.mesh = new Mesh(); } }
protected void LateUpdate() { //Debug.Log("Hello world"); int curIndex = markFirst; for (int i = 0; i < MAX_MARKS; i++) { curIndex = (curIndex + i) % MAX_MARKS; //Debug.Log(colors[curIndex * 4 + 0].a); MarkSection curSection = skidmarks[curIndex]; if (Time.time - curSection.CreateTime < SHOW_MARK_TIME) { break; } if (colors[curIndex * 4 + 0].a != 0) { float apl = Mathf.Clamp(colors[curIndex * 4 + 0].a - 1, 0, colors[curIndex * 4 + 0].a - 1); colors[curIndex * 4 + 0].a = (byte)apl; colors[curIndex * 4 + 1].a = (byte)apl; colors[curIndex * 4 + 2].a = (byte)apl; colors[curIndex * 4 + 3].a = (byte)apl; } } //if (!meshUpdated) return; meshUpdated = false; //Debug.Log("Hello world"); // Reassign the mesh if it's changed this frame marksMesh.vertices = vertices; marksMesh.normals = normals; marksMesh.tangents = tangents; marksMesh.triangles = triangles; marksMesh.colors32 = colors; marksMesh.uv = uvs; if (!haveSetBounds) { // Could use RecalculateBounds here each frame instead, but it uses about 0.1-0.2ms each time // Save time by just making the mesh bounds huge, so the skidmarks will always draw // Not sure why I only need to do this once, yet can't do it in Start (it resets to zero) marksMesh.bounds = new Bounds(new Vector3(0, 0, 0), new Vector3(10000, 10000, 10000)); haveSetBounds = true; } mf.sharedMesh = marksMesh; }
// Function called by the wheels that is skidding. Gathers all the information needed to // create the mesh later. Sets the intensity of the skidmark section b setting the alpha // of the vertex color. public int AddSkidMark(Vector3 pos, Vector3 normal, float intensity, int lastIndex) { if (skidmarks == null) { InitSkidmarks(); } if (intensity > 1) { intensity = 1.0f; } if (intensity <= 0) { return(-1); } MarkSection curr = skidmarks[numMarks % maxMarks]; curr.pos = pos + normal * groundOffset; curr.normal = normal; curr.intensity = intensity; curr.lastIndex = lastIndex; if (lastIndex != -1) { MarkSection last = skidmarks[lastIndex % maxMarks]; Vector3 dir = (curr.pos - last.pos); Vector3 xDir = Vector3.Cross(dir, normal).normalized; curr.posl = curr.pos + xDir * markWidth * 0.5f; curr.posr = curr.pos - xDir * markWidth * 0.5f; curr.tangent = new Vector4(xDir.x, xDir.y, xDir.z, 1); if (last.lastIndex == -1) { last.tangent = curr.tangent; last.posl = curr.pos + xDir * markWidth * 0.5f; last.posr = curr.pos - xDir * markWidth * 0.5f; } } numMarks++; updated = true; return(numMarks - 1); }
public int AddSkidMark(Vector3 pos, Vector3 normal, float intensity, int lastIndex) { if (intensity > 1) { intensity = 1.0f; } if (intensity < 0) { return -1; } curr = skidmarks[numMarks % maxMarks]; curr.pos = pos + normal * groundOffset; curr.normal = normal; curr.intensity = intensity; curr.lastIndex = lastIndex; if (lastIndex != -1) { last = skidmarks[lastIndex % maxMarks]; dir = (curr.pos - last.pos); xDir = Vector3.Cross(dir, normal).normalized; curr.posl = curr.pos + xDir * markWidth * 0.5f; curr.posr = curr.pos - xDir * markWidth * 0.5f; curr.tangent = new Vector4(xDir.x, xDir.y, xDir.z, 1); if (last.lastIndex == -1) { last.tangent = curr.tangent; last.posl = curr.pos + xDir * markWidth * 0.5f; last.posr = curr.pos - xDir * markWidth * 0.5f; } } numMarks++; updated = true; return numMarks - 1; }
public int AddLineNode(Vector3 pos, Vector3 normal, float intensity, int lastIndex) { if (intensity > 1) { intensity = 1.0f; } if (intensity < 0) { return(-1); } MarkSection curr = RacingLineParts[numMarks % MeshResolution]; curr.pos = pos + normal * GroundOffset; curr.normal = normal; curr.intensity = intensity; curr.lastIndex = lastIndex; if (lastIndex != -1) { MarkSection last = RacingLineParts[lastIndex % MeshResolution]; Vector3 dir = (curr.pos - last.pos); Vector3 xDir = Vector3.Cross(dir, normal).normalized; curr.posl = curr.pos + xDir * RacingLineWidth * 0.5f; curr.posr = curr.pos - xDir * RacingLineWidth * 0.5f; curr.tangent = new Vector4(xDir.x, xDir.y, xDir.z, 1); if (last.lastIndex == -1) { last.tangent = curr.tangent; last.posl = curr.pos + xDir * RacingLineWidth * 0.5f; last.posr = curr.pos - xDir * RacingLineWidth * 0.5f; } } numMarks++; updateMesh = true; return(numMarks - 1); }
void UpdateMeshFilter() { if (!updateMesh) { return; } updateMesh = false; Mesh mesh = ((MeshFilter)GetComponent(typeof(MeshFilter))).mesh; mesh.Clear(); int segmentCount = 0; for (int j = 0; j < numMarks && j < MeshResolution; j++) { if (RacingLineParts[j].lastIndex != -1 && RacingLineParts[j].lastIndex > numMarks - MeshResolution) { segmentCount++; } } Vector3[] vertices = new Vector3[segmentCount * 4]; Vector3[] normals = new Vector3[segmentCount * 4]; Vector4[] tangents = new Vector4[segmentCount * 4]; Color[] colors = new Color[segmentCount * 4]; Vector2[] uvs = new Vector2[segmentCount * 4]; int[] triangles = new int[segmentCount * 6]; segmentCount = 0; for (int i = 0; i < numMarks && i < MeshResolution; i++) { if (RacingLineParts[i].lastIndex != -1 && RacingLineParts[i].lastIndex > numMarks - MeshResolution) { MarkSection curr = RacingLineParts[i]; MarkSection last = RacingLineParts[curr.lastIndex % MeshResolution]; float magnitude = (last.posr - curr.posr).magnitude; float tiling = (magnitude / TextureTile) + textureOffset; vertices[segmentCount * 4 + 0] = last.posl; vertices[segmentCount * 4 + 1] = last.posr; vertices[segmentCount * 4 + 2] = curr.posl; vertices[segmentCount * 4 + 3] = curr.posr; normals[segmentCount * 4 + 0] = last.normal; normals[segmentCount * 4 + 1] = last.normal; normals[segmentCount * 4 + 2] = curr.normal; normals[segmentCount * 4 + 3] = curr.normal; tangents[segmentCount * 4 + 0] = last.tangent; tangents[segmentCount * 4 + 1] = last.tangent; tangents[segmentCount * 4 + 2] = curr.tangent; tangents[segmentCount * 4 + 3] = curr.tangent; colors[segmentCount * 4 + 0] = new Color(0, 0, 0, last.intensity); colors[segmentCount * 4 + 1] = new Color(0, 0, 0, last.intensity); colors[segmentCount * 4 + 2] = new Color(0, 0, 0, curr.intensity); colors[segmentCount * 4 + 3] = new Color(0, 0, 0, curr.intensity); uvs[segmentCount * 4 + 0] = new Vector2(0, textureOffset); uvs[segmentCount * 4 + 1] = new Vector2(1, textureOffset); uvs[segmentCount * 4 + 2] = new Vector2(0, tiling); uvs[segmentCount * 4 + 3] = new Vector2(1, tiling); textureOffset = (magnitude / TextureTile) % 1 + textureOffset; triangles[segmentCount * 6 + 0] = segmentCount * 4 + 0; triangles[segmentCount * 6 + 2] = segmentCount * 4 + 1; triangles[segmentCount * 6 + 1] = segmentCount * 4 + 2; triangles[segmentCount * 6 + 3] = segmentCount * 4 + 2; triangles[segmentCount * 6 + 5] = segmentCount * 4 + 1; triangles[segmentCount * 6 + 4] = segmentCount * 4 + 3; segmentCount++; } } mesh.vertices = vertices; mesh.normals = normals; mesh.tangents = tangents; mesh.triangles = triangles; mesh.colors = colors; mesh.uv = uvs; textureOffset = 0; }
// If the mesh needs to be updated, i.e. a new section has been added, // the current mesh is removed, and a new mesh for the skidmarks is generated. void LateUpdate() { if (!updated) { return; } updated = false; Mesh mesh = ((MeshFilter)GetComponent(typeof(MeshFilter))).mesh; mesh.Clear(); int segmentCount = 0; for (int j = 0; j < numMarks && j < maxMarks; j++) { if (skidmarks[j].lastIndex != -1 && skidmarks[j].lastIndex > numMarks - maxMarks) { segmentCount++; } } Vector3[] vertices = new Vector3[segmentCount * 4]; Vector3[] normals = new Vector3[segmentCount * 4]; Vector4[] tangents = new Vector4[segmentCount * 4]; Color[] colors = new Color[segmentCount * 4]; Vector2[] uvs = new Vector2[segmentCount * 4]; int[] triangles = new int[segmentCount * 6]; segmentCount = 0; for (int i = 0; i < numMarks && i < maxMarks; i++) { if (skidmarks[i].lastIndex != -1 && skidmarks[i].lastIndex > numMarks - maxMarks) { MarkSection curr = skidmarks[i]; MarkSection last = skidmarks[curr.lastIndex % maxMarks]; vertices[segmentCount * 4 + 0] = last.posl; vertices[segmentCount * 4 + 1] = last.posr; vertices[segmentCount * 4 + 2] = curr.posl; vertices[segmentCount * 4 + 3] = curr.posr; normals[segmentCount * 4 + 0] = last.normal; normals[segmentCount * 4 + 1] = last.normal; normals[segmentCount * 4 + 2] = curr.normal; normals[segmentCount * 4 + 3] = curr.normal; tangents[segmentCount * 4 + 0] = last.tangent; tangents[segmentCount * 4 + 1] = last.tangent; tangents[segmentCount * 4 + 2] = curr.tangent; tangents[segmentCount * 4 + 3] = curr.tangent; colors[segmentCount * 4 + 0] = new Color(0, 0, 0, last.intensity); colors[segmentCount * 4 + 1] = new Color(0, 0, 0, last.intensity); colors[segmentCount * 4 + 2] = new Color(0, 0, 0, curr.intensity); colors[segmentCount * 4 + 3] = new Color(0, 0, 0, curr.intensity); uvs[segmentCount * 4 + 0] = new Vector2(0, 0); uvs[segmentCount * 4 + 1] = new Vector2(1, 0); uvs[segmentCount * 4 + 2] = new Vector2(0, 1); uvs[segmentCount * 4 + 3] = new Vector2(1, 1); triangles[segmentCount * 6 + 0] = segmentCount * 4 + 0; triangles[segmentCount * 6 + 2] = segmentCount * 4 + 1; triangles[segmentCount * 6 + 1] = segmentCount * 4 + 2; triangles[segmentCount * 6 + 3] = segmentCount * 4 + 2; triangles[segmentCount * 6 + 5] = segmentCount * 4 + 1; triangles[segmentCount * 6 + 4] = segmentCount * 4 + 3; segmentCount++; } } mesh.vertices = vertices; mesh.normals = normals; mesh.tangents = tangents; mesh.triangles = triangles; mesh.colors = colors; mesh.uv = uvs; }
private void LateUpdate() { if (!updated) { return; } updated = false; mesh.Clear(); segmentCount = 0; for (int j = 0; j < numMarks && j < maxMarks; j++) { if (skidmarks[j].lastIndex != -1 && skidmarks[j].lastIndex > numMarks - maxMarks) { segmentCount++; } } vertices = new Vector3[segmentCount * 4]; normals = new Vector3[segmentCount * 4]; tangents = new Vector4[segmentCount * 4]; colors = new Color[segmentCount * 4]; uvs = new Vector2[segmentCount * 4]; triangles = new int[segmentCount * 6]; segmentCount = 0; for (int i = 0; i < numMarks && i < maxMarks; i++) { if (skidmarks[i].lastIndex != -1 && skidmarks[i].lastIndex > numMarks - maxMarks) { curr = skidmarks[i]; last = skidmarks[curr.lastIndex % maxMarks]; vertices[segmentCount * 4 + 0] = last.posl; vertices[segmentCount * 4 + 1] = last.posr; vertices[segmentCount * 4 + 2] = curr.posl; vertices[segmentCount * 4 + 3] = curr.posr; normals[segmentCount * 4 + 0] = last.normal; normals[segmentCount * 4 + 1] = last.normal; normals[segmentCount * 4 + 2] = curr.normal; normals[segmentCount * 4 + 3] = curr.normal; tangents[segmentCount * 4 + 0] = last.tangent; tangents[segmentCount * 4 + 1] = last.tangent; tangents[segmentCount * 4 + 2] = curr.tangent; tangents[segmentCount * 4 + 3] = curr.tangent; colors[segmentCount * 4 + 0] = new Color(0, 0, 0, last.intensity); colors[segmentCount * 4 + 1] = new Color(0, 0, 0, last.intensity); colors[segmentCount * 4 + 2] = new Color(0, 0, 0, curr.intensity); colors[segmentCount * 4 + 3] = new Color(0, 0, 0, curr.intensity); uvs[segmentCount * 4 + 0] = new Vector2(0, 0); uvs[segmentCount * 4 + 1] = new Vector2(1, 0); uvs[segmentCount * 4 + 2] = new Vector2(0, 1); uvs[segmentCount * 4 + 3] = new Vector2(1, 1); triangles[segmentCount * 6 + 0] = segmentCount * 4 + 0; triangles[segmentCount * 6 + 2] = segmentCount * 4 + 1; triangles[segmentCount * 6 + 1] = segmentCount * 4 + 2; triangles[segmentCount * 6 + 3] = segmentCount * 4 + 2; triangles[segmentCount * 6 + 5] = segmentCount * 4 + 1; triangles[segmentCount * 6 + 4] = segmentCount * 4 + 3; segmentCount++; } } mesh.vertices = vertices; mesh.normals = normals; mesh.tangents = tangents; mesh.triangles = triangles; mesh.colors = colors; mesh.uv = uvs; }
// Function called by the wheel that's skidding. Sets the colour and intensity of the skidmark section. public int AddSkidMark(Vector3 pos, Vector3 normal, Color32 colour, int lastIndex) { if (colour.a == 0) { return(-1); // No point in continuing if it's invisible } MarkSection lastSection = null; Vector3 distAndDirection = Vector3.zero; Vector3 newPos = pos + normal * GROUND_OFFSET; if (lastIndex != -1) { lastSection = skidmarks[lastIndex]; distAndDirection = newPos - lastSection.Pos; if (distAndDirection.sqrMagnitude < MIN_SQR_DISTANCE) { return(lastIndex); } // Fixes an awkward bug: // - Car draws skidmark, e.g. index 50 with last index 40. // - Skidmark markIndex loops around, and other car overwrites index 50 // - Car draws skidmark, e.g. index 45. Last index was 40, but now 40 is different, changed by someone else. // This makes sure we ignore the last index if the distance looks wrong if (distAndDirection.sqrMagnitude > MIN_SQR_DISTANCE * 10) { lastIndex = -1; lastSection = null; } } colour.a = (byte)(colour.a * MAX_OPACITY); MarkSection curSection = skidmarks[markIndex]; curSection.Pos = newPos; curSection.Normal = normal; curSection.Colour = colour; curSection.LastIndex = lastIndex; if (lastSection != null) { Vector3 xDirection = Vector3.Cross(distAndDirection, normal).normalized; curSection.Posl = curSection.Pos + xDirection * MARK_WIDTH * 0.5f; curSection.Posr = curSection.Pos - xDirection * MARK_WIDTH * 0.5f; curSection.Tangent = new Vector4(xDirection.x, xDirection.y, xDirection.z, 1); if (lastSection.LastIndex == -1) { lastSection.Tangent = curSection.Tangent; lastSection.Posl = curSection.Pos + xDirection * MARK_WIDTH * 0.5f; lastSection.Posr = curSection.Pos - xDirection * MARK_WIDTH * 0.5f; } } UpdateSkidmarksMesh(); int curIndex = markIndex; // Update circular index markIndex = ++markIndex % MAX_MARKS; return(curIndex); }