mvaganov

Line Drawing in Unity3D!

May 30th, 2013
94
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. public class LineDraw : MonoBehaviour
  6. {
  7.     static LineDraw instance = null;
  8.     float widthStart = 0.1f;
  9.     float widthFinish = 0.1f;
  10.     ShaderOptionEnum shader = ShaderOptionEnum.SelfIlluminDiffuse;
  11.     Color color = Color.red;
  12.    
  13.     string[] shaders = {"Self-Illumin/Diffuse", "Particles/Additive"};//, "VertexLit", "Diffuse"}; 
  14.     public enum ShaderOptionEnum {SelfIlluminDiffuse = 0, ParticlesAdditive};
  15.     //public class LineData{Vector3 a, b; float s, f; ShaderOptionEnum shader; Color c1, c2;}
  16.    
  17.     public void SetWidth_(float widthStart, float widthFinish)
  18.     {
  19.         this.widthStart = widthStart;
  20.         this.widthFinish = widthFinish;
  21.     }
  22.     public float GetWidthStart_(){return widthStart;}
  23.     public float GetWidthFinish_(){return widthFinish;}
  24.    
  25.     public void SetShaderOption_(ShaderOptionEnum shader)
  26.     {
  27.         this.shader = shader;
  28.     }
  29.    
  30.     public void SetColor_(Color color){this.color = color;}
  31.     public Color GetColor_(){return this.color;}
  32.    
  33.     public static void SetShaderOption(ShaderOptionEnum shader){instance.SetShaderOption_(shader);}
  34.     public static Color GetColor(){return instance.GetColor_();}
  35.     public static void SetColor(Color color){instance.SetColor_(color);}
  36.     public static void SetWidth(float widthStart, float widthFinish){instance.SetWidth_(widthStart, widthFinish);}
  37.     public static void SetWidth(float width){instance.SetWidth_(width, width);}
  38.     public static float GetWidthStart(){return instance.GetWidthStart_();}
  39.     public static float GetWidthFinish(){return instance.GetWidthFinish_();}
  40.    
  41.     public static GameObject AddPersistent(Vector3 a, Vector3 b){return instance.AddLine_(a, b, true);}
  42.     public static GameObject AddPersistentCircle(Vector3 center, float radius, Vector3 normal){return instance.AddCircle_(center, radius, normal, 360, 0, 24, true);}
  43.     public static GameObject AddPersistentSpiralPlane(Vector3 center, int size, Vector3 normal){return instance.AddSpiralPlane_(center, size, normal, 24, true);}
  44.     public static GameObject AddPersistentQuaternion(Vector3 p, float radius, Quaternion q){return instance.AddQuaternion_(p, radius, q, 24, true);}
  45.     public static void AddTemporary(Vector3 a, Vector3 b){instance.AddLine_(a, b, false);}
  46.     public static void AddTemporaryCircle(Vector3 center, float radius, Vector3 normal){instance.AddCircle_(center, radius, normal, 360, 0, 24, false);}
  47.  
  48.     List<GameObject> temp = new List<GameObject>();
  49.     List<GameObject> unusedTemp = new List<GameObject>();
  50.    
  51. // MonoBehavior upkeep stuff, including test code -----------------------------
  52.  
  53.     // TEST CODE
  54. //  float t = 0;
  55.     void LateUpdate()
  56.     {
  57.         for(int i = 0; i < temp.Count; ++i)
  58.         {
  59.             temp[i].active = false;
  60.             unusedTemp.Add(temp[i]);
  61.         }
  62.         temp.Clear();
  63.         // TEST CODE
  64. //      t += Time.deltaTime;
  65. //      if(t >= 360) t-=360;
  66. //      Quaternion q = Quaternion.AngleAxis(t * 360, Vector3.forward);
  67. //      Vector3 v = q * new Vector3(1,0,0);
  68. //      LineDraw.AddTemporary(Vector3.zero, v);
  69.     }
  70.     void Start()
  71.     {
  72.         if(instance == null)
  73.             instance = this;
  74.         // TEST CODE
  75. //      GameObject g = LineDraw.AddPersistent(new Vector3(-1,-1,-2), new Vector3(5,1,-2));
  76. //      Destroy(g, 3);
  77. //      Vector3 v = new Vector3(1,1,1);
  78. //      v.Normalize();
  79. //      LineDraw.AddPersistentSpiralPlane(new Vector3(-2,2,-1), 2, v);
  80. //      Vector3 p = new Vector3(2,-2,-1), n = new Vector3(-1,1,1).normalized;
  81. //      for(int i = 0; i < 5; ++i)
  82. //      {
  83. //          AddCircle_(p, 1.0f+(0.4f*i), n, 360-(i*15), 0+(i*30), 24, true);
  84. //      }
  85. //      LineDraw.SetColor(Color.white);
  86. //      Quaternion q = transform.rotation;
  87. //      AddPersistentQuaternion(new Vector3(0, -5, 0), .5f, q);
  88. //      LineDraw.SetColor(Color.blue);
  89.     }
  90.  
  91. // THE MEATY CODE -------------------------------------------------------------
  92.     GameObject GetLineGameObject()
  93.     {
  94.         GameObject go;
  95.         LineRenderer lineRenderer;
  96.         if(unusedTemp.Count > 0)
  97.         {
  98.             int lastIndex = unusedTemp.Count-1;
  99.             go = unusedTemp[lastIndex];
  100.             unusedTemp.RemoveAt(lastIndex);
  101.             go.active = true;
  102.             lineRenderer = go.GetComponent<LineRenderer>();
  103.         }else{
  104.             go = new GameObject("line");
  105.             lineRenderer = go.AddComponent<LineRenderer>();
  106.         }
  107.         string shaderName = shaders[(int)shader];
  108.         if(lineRenderer.material.shader.name != shaderName)
  109.         {
  110.             UnityEngine.Shader shaderObject = Shader.Find(shaderName);
  111.             lineRenderer.material = new Material(shaderObject);
  112.         }
  113.         lineRenderer.material.color = color;
  114.         lineRenderer.castShadows = false;
  115.         lineRenderer.receiveShadows = false;
  116.         lineRenderer.SetColors(color, color);
  117.         lineRenderer.SetWidth(widthStart, widthFinish);
  118.         go.transform.parent = transform;
  119.         return go;
  120.     }
  121.     public GameObject AddLine_(Vector3 a, Vector3 b, bool persistent)
  122.     {
  123.         int numPoints = 2;
  124.         GameObject lineg = GetLineGameObject();
  125.         LineRenderer lineRenderer = lineg.GetComponent<LineRenderer>();
  126.         lineRenderer.SetVertexCount(numPoints);
  127.         lineRenderer.SetPosition(0, a);
  128.         lineRenderer.SetPosition(1, b);
  129.         if(!persistent)
  130.             temp.Add(lineg);
  131.         return lineg;
  132.     }
  133.     public GameObject AddCircle_(Vector3 p, float r, Vector3 normal, float angle, float startAngle, int pointsPerCircle, bool persistent)
  134.     {
  135.         float numPointsF = (angle * pointsPerCircle / 360);
  136.         int numPoints = (int)(numPointsF);
  137.         float remainder = numPointsF - numPoints;
  138.         GameObject lineg = GetLineGameObject();
  139.         LineRenderer lineRenderer = lineg.GetComponent<LineRenderer>();
  140.         Quaternion q = Quaternion.LookRotation(normal);
  141.         Vector3 right = GetRightVector(q);
  142.         lineRenderer.SetVertexCount(numPoints+1 + ((remainder>0?1:0)));
  143.         lineRenderer.SetPosition(0, p + right * r);
  144.         for(int i = 0; i < numPoints+1; ++i)
  145.         {
  146.             q = Quaternion.AngleAxis(i*360.0f/pointsPerCircle + startAngle, normal);
  147.             lineRenderer.SetPosition(i, p + q * right * r);
  148.         }
  149.         if(remainder > 0)
  150.         {
  151.             q = Quaternion.AngleAxis(angle + startAngle, normal);
  152.             lineRenderer.SetPosition(numPoints+1, p + q * right * r);
  153.         }
  154.         if(!persistent)
  155.             temp.Add(lineg);
  156.         // TEST CODE
  157. //      Color c = GetColor_();
  158. //          SetColor_(Color.red);   AddLine_(p, GetRightVector(q) + p,persistent);
  159. //          SetColor_(Color.green); AddLine_(p, GetUpVector(q) + p,persistent);
  160. //          SetColor_(Color.blue);  AddLine_(p, GetForwardVector(q) + p,persistent);
  161. //      SetColor_(c);
  162.         return lineg;
  163.     }
  164.     public GameObject AddQuaternion_(Vector3 p, float r, Quaternion quaternion, int pointsPerCircle, bool persistent)
  165.     {
  166.         Vector3 axis;
  167.         float angle;
  168.         quaternion.ToAngleAxis(out angle, out axis);
  169.         float s = widthStart, f = widthFinish;
  170.         SetWidth_(s+f, 0);
  171.         Vector3 r2 = axis*r*2;
  172.         GameObject lineg = AddLine_(p-r2, p+r2, persistent);//GetLineGameObject();
  173.         GameObject curve = AddCircle_(p, r, axis, angle, 0, pointsPerCircle, persistent);
  174.         curve.transform.parent = lineg.transform;
  175.         SetWidth_(s, f);
  176.         if(!persistent)
  177.         {
  178.             temp.Add(lineg);
  179.             temp.Add(curve);
  180.         }
  181.         return lineg;
  182.     }
  183.     public GameObject AddSpiralPlane_(Vector3 p, int size, Vector3 normal, int pointsPerCircle, bool persistent)
  184.     {
  185.         int numPoints = size*pointsPerCircle;
  186.         GameObject lineg = GetLineGameObject();
  187.         LineRenderer lineRenderer = lineg.GetComponent<LineRenderer>();
  188.         Vector3 right = GetRightVector(Quaternion.LookRotation(normal));
  189.         lineRenderer.SetVertexCount(numPoints);
  190.         float rad = 0;
  191.         for(int i = 0; i < numPoints; ++i)
  192.         {
  193.             Quaternion q = Quaternion.AngleAxis(i*360.0f/pointsPerCircle, normal);
  194.             Vector3 delta = q * right * rad;
  195.             lineRenderer.SetPosition(i, p + (delta * 1));
  196.             rad += 2f/pointsPerCircle;
  197.         }          
  198.         if(!persistent)
  199.             temp.Add(lineg);
  200.         return lineg;
  201.     }
  202.     Vector3 GetForwardVector(Quaternion q)
  203.     {
  204.         return new Vector3( 2 * (q.x * q.z + q.w * q.y),
  205.                         2 * (q.y * q.z - q.w * q.x),
  206.                         1 - 2 * (q.x * q.x + q.y * q.y));
  207.     }
  208.     public static Vector3 GetUpVector(Quaternion q)
  209.     {
  210.         return new Vector3( 2 * (q.x * q.y - q.w * q.z),
  211.                         1 - 2 * (q.x * q.x + q.z * q.z),
  212.                         2 * (q.y * q.z + q.w * q.x));
  213.     }
  214.     public static Vector3  GetRightVector(Quaternion q)
  215.     {
  216.         return new Vector3( 1 - 2 * (q.y * q.y + q.z * q.z),
  217.                         2 * (q.x * q.y + q.w * q.z),
  218.                         2 * (q.x * q.z - q.w * q.y));
  219.     }
  220. }
RAW Paste Data