Hi Guys, I have been spending some time trying to convert the TubeRenderer Script on the Wiki, Which has gone reasonably well! I just have a few errors that I cannot figure out… If someone could help I would really appreciate it!
Code:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class TubeRenderer : MonoBehaviour {
public Material material;
public int crossSegments = 10;
public int movePixelsForRebuild;
public float flatAtDistance = 1.0f;
public float maxRebuildTime = 0.1f;
public Vector3[] verts;
private Vector3[] crossPoints;
private int lastCrossSegments;
private Vector3 lastCameraPosition1;
private Vector3 lastCameraPosition2;
private float lastRebuildTime = 0.00f;
void Start() {
MeshFilter mf = gameObject.AddComponent("MeshFilter") as MeshFilter;
MeshRenderer mr = gameObject.AddComponent("MeshRenderer") as MeshRenderer;
mr.material = material;
}
void LateUpdate () {
if (verts.Length <= 1) {
renderer.enabled=false;
return;
}
renderer.enabled=true;
//rebuild the mesh?
bool re = false;
float distFromMainCam;
if(verts.Length > 1)
{
var cur1 = Camera.main.WorldToScreenPoint(verts[0]);
distFromMainCam = lastCameraPosition1.z;
lastCameraPosition1.z = 0;
var cur2 = Camera.main.WorldToScreenPoint(verts[verts.Length - 1]);
lastCameraPosition2.z = 0;
var distance = (lastCameraPosition1 - cur1).magnitude;
distance += (lastCameraPosition2 - cur2).magnitude;
if(distance > movePixelsForRebuild || Time.time - lastRebuildTime > maxRebuildTime)
{
re = true;
lastCameraPosition1 = cur1;
lastCameraPosition2 = cur2;
}
}
if (re) {
if (crossSegments != lastCrossSegments) {
crossPoints = new Vector3[crossSegments];
//var theta : float = 2.0*Mathf.PI/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);
}
lastCrossSegments = crossSegments;
}
Vector3[] meshVertices = new Vector3[verts.Length * crossSegments];
Vector2[] uvs = new Vector2[verts.Length * crossSegments];
Color[] colors = new Color[verts.Length * crossSegments];
int[] tris = new int[verts.Length * crossSegments * 6];
int[] lastVertices = new int[crossSegments];
int[] theseVertices = new int[crossSegments];
Quaternion rotation = new Quaternion(0, 0, 0);
for (int p = 0; p < verts.Length; p++) {
if (p<verts.Length-1) rotation = Quaternion.FromToRotation(Vector3.forward, verts[p+1] - verts[p]);
for (int c = 0; c < crossSegments; c++) {
int vertexIndex = p * crossSegments + c;
meshVertices[vertexIndex] = verts[p] + rotation * crossPoints[c] * radius;
uvs[vertexIndex] = new Vector2(0.0 + c / crossSegments, (0.0 + p) / verts.Length);
lastVertices[c]=theseVertices[c];
theseVertices[c] = p*crossSegments+c;
}
//make triangles
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];
//print("Triangle: indexes("+tris[start]+", "+tris[start+1]+", "+tris[start+2]+"), ("+tris[start+3]+", "+tris[start+4]+", "+tris[start+5]+")");
}
}
}
Mesh mesh = gameObject.GetComponent("Mesh") as Mesh;
if (!mesh){
mesh = new Mesh();
}
mesh.vertices = meshVertices;
mesh.triangles = tris;
mesh.RecalculateNormals();
mesh.uv = uvs;
}
}
void Update () {
}
}
Errors:
Assets/Tube Shit/TubeRenderer.cs(80,80): error CS0165: Use of unassigned local variable `rotation’
Assets/Tube Shit/TubeRenderer.cs(80,108): error CS0103: The name `radius’ does not exist in the current context
Assets/Tube Shit/TubeRenderer.cs(82,122): error CS1502: The best overloaded method match for `UnityEngine.Vector2.Vector2(float, float)’ has some invalid arguments
Assets/Tube Shit/TubeRenderer.cs(82,122): error CS1503: Argument #1' cannot convert double’ expression to type `float’
Assets/Tube Shit/TubeRenderer.cs(102,69): error CS0039: Cannot convert type UnityEngine.Component' to UnityEngine.Mesh’ via a built-in conversion
This is off the top of my head, so bear with me if these points wont solve your problems.
1: Your Quaternion declaration only has 3 components. Quaternions take (x,y,z,w). To declare it with 3 components, you should use Quaternion.Euler(0,0,0);
Alternatively, I would suggest you declare a Quaternion named rotation at the start of the script and assign it a value, just to be sure it has a value in every case.
2: Again, declare radius at the start of the script.
3: when writing float values in c#, you need to write 0.0f. just typing 0.0 declares a different datatype, a double.
4: goes away when you fix #3. Youre trying to add floats and doubles. Like adding apples to oranges.
I went to the wiki and converted it, there might be some problems with the public/private vars, but that is simple to modify to ensure it works in the inspector as expected. It build out fine in MonoDevelop, anywho.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
internal class TubeVertex
{
private Vector3 m_Point = Vector3.zero;
private float m_Radius = 1.0f;
private Color m_Color = Color.white;
/// <summary>
/// Initializes a new instance of the <see cref="TubeVertex"/> class.
/// </summary>
/// <param name='point'>Point</param>
/// <param name='radius'>adius</param>
/// <param name='color'>Color</param>
public TubeVertex(Vector3 point, float radius, Color color)
{
m_Point = point;
m_Radius = radius;
m_Color = color;
}
/// <summary>
/// Gets or sets the point.
/// </summary>
public Vector3 Point
{
get { return m_Point; }
set { m_Point = value; }
}
/// <summary>
/// Gets or sets the radius.
/// </summary>
public float Radius
{
get { return m_Radius; }
set { m_Radius = value; }
}
/// <summary>
/// Gets or sets the color.
/// </summary>
public Color Color
{
get { return m_Color; }
set { m_Color = value; }
}
}
public class TubeRenderer : MonoBehaviour
{
private TubeVertex[] m_Vertices;
private Material m_Material;
private int m_CrossSegments = 3;
private Vector3[] m_CrossPoints;
private int m_LastCrossSegments;
private float m_FlatAtDistance = -1.0f;
private Vector3 m_LastCameraPosition1;
private Vector3 m_LastCameraPosition2;
private int m_MovePixelsForRebuild = 6;
private float m_MaxRebuildTime = 0.1f;
private float m_LastRebuildTime = 0.00f;
public void Start()
{
this.gameObject.AddComponent(typeof(MeshFilter));
MeshRenderer mr = (MeshRenderer)this.gameObject.AddComponent(typeof(MeshRenderer));
mr.material = this.m_Material;
}
public void Reset()
{
this.m_Vertices = new TubeVertex[] { new TubeVertex(Vector3.zero, 1.0f, Color.white), new TubeVertex(new Vector3(1, 0, 0), 1.0f, Color.white) };
}
public void LateUpdate()
{
if (m_Vertices != null || m_Vertices.Length <= 1)
{
this.renderer.enabled = false;
return;
}
this.renderer.enabled = true;
bool rebuildMesh = false;
float distanceFromMainCamera = 0.0f;
if (m_Vertices.Length > 1)
{
Vector3 cur1 = Camera.main.WorldToScreenPoint(m_Vertices[0].Point);
distanceFromMainCamera = m_LastCameraPosition1.z;
m_LastCameraPosition1.Set(m_LastCameraPosition1.x, m_LastCameraPosition1.y, 0);
// m_LastCameraPosition1 = New Vector3(m_LastCameraPosition1.x, m_LastCameraPosition1.y, 0);
Vector3 cur2 = Camera.main.WorldToScreenPoint(m_Vertices[m_Vertices.Length - 1].Point);
m_LastCameraPosition2.Set(m_LastCameraPosition2.x, m_LastCameraPosition2.y, 0);
// m_LastCameraPosition2 = New Vector3(m_LastCameraPosition2.x, m_LastCameraPosition2.y, 0);
float distance = (m_LastCameraPosition1 - cur1).magnitude;
distance += (m_LastCameraPosition2 - cur2).magnitude;
if (distance > m_MovePixelsForRebuild || Time.time - m_LastRebuildTime > m_MaxRebuildTime)
{
rebuildMesh = true;
m_LastCameraPosition1 = cur1;
m_LastCameraPosition2 = cur2;
}
if (rebuildMesh)
{
if(m_CrossSegments != m_LastCrossSegments)
{
m_CrossPoints = new Vector3[m_CrossSegments];
float theta = 2.0f * Mathf.PI / m_CrossSegments;
for(int c = 0; c < m_CrossSegments; c++)
{
m_CrossPoints[c] = new Vector3(Mathf.Cos(theta*c), Mathf.Sin(theta*c), 0);
}
m_LastCrossSegments = m_CrossSegments;
}
Vector3[] meshVertices = new Vector3[m_Vertices.Length * m_CrossSegments];
Vector2[] uvs = new Vector2[m_Vertices.Length * m_CrossSegments];
Color[] colors = new Color[m_Vertices.Length * m_CrossSegments];
int[] tris = new int[m_Vertices.Length * m_CrossSegments * 6];
int[] lastVertices = new int[m_CrossSegments];
int[] theseVertices = new int[m_CrossSegments];
Quaternion rotation = Quaternion.identity; // so the compiler will stop talking smack.
for(int p = 0; p < m_Vertices.Length; p++)
{
if(p < m_Vertices.Length - 1)
{
rotation = Quaternion.FromToRotation(Vector3.forward, m_Vertices[p+1].Point - m_Vertices[p].Point);
}
for(int c = 0; c < m_CrossSegments; c++)
{
int vertexIndex = p * m_CrossSegments + c;
meshVertices[vertexIndex] = m_Vertices[p].Point + rotation * m_CrossPoints[c] * m_Vertices[p].Radius;
uvs[vertexIndex] = new Vector2((0.0f+c) / m_CrossSegments, (0.0f+p) / m_Vertices.Length);
colors[vertexIndex] = m_Vertices[p].Color;
//print(c+" - vertex index " + (p*m_CrossSegments+c) + " is " + meshVertices[p * m_CrossSegments + c]);
lastVertices[c] = theseVertices[c];
theseVertices[c] = p * m_CrossSegments + c;
}
//make triangles
if (p>0)
{
for (int c = 0;c < m_CrossSegments;c++)
{
int start = (p*m_CrossSegments+c)*6;
tris[start] = lastVertices[c];
tris[start+1] = lastVertices[(c+1)%m_CrossSegments];
tris[start+2] = theseVertices[c];
tris[start+3] = tris[start+2];
tris[start+4] = tris[start+1];
tris[start+5] = theseVertices[(c+1)%m_CrossSegments];
//print("Triangle: indexes("+tris[start]+", "+tris[start+1]+", "+tris[start+2]+"), ("+tris[start+3]+", "+tris[start+4]+", "+tris[start+5]+")");
}
}
}
Mesh mesh = GetComponent<MeshFilter>().mesh;
if (!mesh)
{
mesh = new Mesh();
}
mesh.triangles = tris;
mesh.RecalculateNormals();
mesh.uv = uvs;
}
}
}
public void SetPoints(Vector3[] points, float radius, Color col)
{
if (points.Length < 2)
return;
m_Vertices = new TubeVertex[points.Length + 2];
Vector3 v0offset = (points[0] - points[1]) * 0.01f;
m_Vertices[0] = new TubeVertex(v0offset + points[0], 0.0f, col);
Vector3 v1offset = (points[points.Length - 1] - points[points.Length - 2]) * 0.01f;
m_Vertices[m_Vertices.Length - 1] = new TubeVertex(v1offset + points[points.Length - 1], 0.0f, col);
for (int p = 0; p < points.Length; p++)
m_Vertices[p + 1] = new TubeVertex(points[p], radius, col);
}
}