Задачки с визуализацией веревок никак не отпускают )))
- Код: Выделить всё
using UnityEngine;
using System.Collections.Generic;
using System;
using System.Text;
using System.IO;
class TubeRenderer: MonoBehaviour
{
class TubeVertex
{
public Vector3 point = Vector3.zero;
public float radius = 1.0f;
public Color color = Color.white;
public TubeVertex(Vector3 pt, float r, Color c)
{
point = pt;
radius = r;
color = c;
}
}
TubeVertex[] vertices;
public Material material;
int crossSegments = 30;
private Vector3[] crossPoints;
/*
private Vector3 lastCameraPosition1;
private Vector3 lastCameraPosition2;
int movePixelsForRebuild = 6;
float maxRebuildTime = 0.1f;
private float lastRebuildTime = 0.00f;
*/
void Reset()
{
vertices = new TubeVertex[2];
vertices[0] = new TubeVertex(Vector3.zero, 1.0f, Color.white);
vertices[1] = new TubeVertex(new Vector3(1f, 0f, 0f), 1.0f, Color.white);
}
void Start()
{
this.gameObject.AddComponent("MeshFilter");
MeshRenderer mr = this.gameObject.AddComponent("MeshRenderer") as MeshRenderer;
mr.material = material;
crossPoints = new Vector3[crossSegments];
float theta = 2.0f * Mathf.PI / crossSegments;
for (int c = 0; c < crossSegments; c++)
crossPoints[c] = new Vector3(Mathf.Cos(theta * c), Mathf.Sin(theta * c), 0);
// начальные точки для ломаной "трубы"
Vector3[] points = new Vector3[4];
points[0] = new Vector3(1f, 1f, 1f);
points[1] = new Vector3(1f, 1f, 10f);
points[2] = new Vector3(10f, 10f, 10f);
points[3] = new Vector3(1f, 10f, 10f);
SetPoints(points, 1f, Color.cyan);
}
void Update()
{
if ((vertices == null) || (vertices.Length < 2))
{
renderer.enabled = false;
return;
}
renderer.enabled = true;
bool redraw = true; // !!! обновление рендера палюбасу (тест)
/*
float distFromMainCam;
if (vertices.Length > 1)
{
Vector3 cur1 = Camera.main.WorldToScreenPoint(vertices[0].point);
distFromMainCam = lastCameraPosition1.z;
lastCameraPosition1.z = 0;
Vector3 cur2 = Camera.main.WorldToScreenPoint(vertices[vertices.Length - 1].point);
lastCameraPosition2.z = 0;
float distance = (lastCameraPosition1 - cur1).magnitude;
distance += (lastCameraPosition2 - cur2).magnitude;
if (distance > movePixelsForRebuild || Time.time - lastRebuildTime > maxRebuildTime)
{
re = true;
lastCameraPosition1 = cur1;
lastCameraPosition2 = cur2;
}
}
*/
if (redraw)
{
Vector3[] meshVertices = new Vector3[vertices.Length * crossSegments];
Vector2[] uvs = new Vector2[vertices.Length * crossSegments];
Color[] colors = new Color[vertices.Length * crossSegments];
int[] tris = new int[vertices.Length * crossSegments * 6];
int[] lastVertices = new int[crossSegments];
int[] theseVertices = new int[crossSegments];
Quaternion rotation;
for (int p = 0; p < vertices.Length; p++)
{
if (p < vertices.Length - 1)
rotation = Quaternion.FromToRotation(Vector3.forward,
vertices[p + 1].point - vertices[p].point);
for (int c = 0; c < crossSegments; c++)
{
int vertexIndex = p * crossSegments + c;
meshVertices[vertexIndex] = vertices[p].point +
this.transform.rotation * crossPoints[c] * vertices[p].radius;
uvs[vertexIndex] = new Vector2((0.0f + c) / crossSegments, (0.0f + p) / vertices.Length);
colors[vertexIndex] = vertices[p].color;
lastVertices[c] = theseVertices[c];
theseVertices[c] = p * crossSegments + c;
}
if (p > 0)
for (int c = 0; c < crossSegments; c++)
{
int start = (p * crossSegments + c) * 6;
tris[start] = lastVertices[c];
tris[start + 1] = lastVertices[(c + 1) % crossSegments];
tris[start + 2] = theseVertices[c];
tris[start + 3] = tris[start + 2];
tris[start + 4] = tris[start + 1];
tris[start + 5] = theseVertices[(c + 1) % crossSegments];
}
}
Mesh mesh = new Mesh();
mesh.vertices = meshVertices;
mesh.triangles = tris;
mesh.RecalculateNormals();
mesh.uv = uvs;
MeshFilter mf = this.GetComponent(typeof(MeshFilter)) as MeshFilter;
mf.mesh = mesh;
}
}
// Задание точек ломаной и ее свойств
void SetPoints(Vector3[] points, float radius, Color col)
{
if (points.Length < 2)
return;
vertices = new TubeVertex[points.Length + 2];
Vector3 v0offset = (points[0] - points[1]) * 0.01f;
vertices[0] = new TubeVertex(v0offset + points[0], 0.0f, col);
Vector3 v1offset = (points[points.Length - 1] - points[points.Length - 2]) * 0.01f;
vertices[vertices.Length - 1] = new TubeVertex(v1offset + points[points.Length - 1], 0.0f, col);
for (int p = 0; p < points.Length; p++)
vertices[p + 1] = new TubeVertex(points[p], radius, col);
}
}