TubeRenderer C# Conversion, Few errors.

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

Thanks!!

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.

5: in C#, you find components like so:

Mesh mesh = gameObject.GetComponent<Mesh>();

Hope this helps!

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);
	}
}